[apparmor] [PATCH v2 46/42] tests: Add regression tests for the aa_policy_cache API

Tyler Hicks tyhicks at canonical.com
Wed Mar 25 07:03:40 UTC 2015


The aa_features and aa_kernel_interface APIs get a little bit of
testing, as well.

Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
---
 tests/regression/apparmor/Makefile           |  17 ++
 tests/regression/apparmor/aa_policy_cache.c  | 228 +++++++++++++++++++++++++++
 tests/regression/apparmor/aa_policy_cache.sh | 149 +++++++++++++++++
 3 files changed, 394 insertions(+)
 create mode 100644 tests/regression/apparmor/aa_policy_cache.c
 create mode 100755 tests/regression/apparmor/aa_policy_cache.sh

diff --git a/tests/regression/apparmor/Makefile b/tests/regression/apparmor/Makefile
index 497652b..c0aad62 100644
--- a/tests/regression/apparmor/Makefile
+++ b/tests/regression/apparmor/Makefile
@@ -135,6 +135,21 @@ Install libdbus-1-dev or equivalent package to build and run these tests${nl}\
 ************************************************************************${nl})
 endif
 
+ifdef USE_SYSTEM
+  ifneq (,$(shell pkg-config --atleast-version 2.10 libapparmor && echo TRUE))
+    SRC+=aa_policy_cache.c
+    AA_POLICY_CACHE_TEST=aa_policy_cache
+  else
+    $(warning ${nl}\
+    ************************************************************************${nl}\
+    Skipping aa_policy_cache tests: requires libapparmor 2.10 or newer ...${nl}\
+    ************************************************************************${nl})
+  endif
+else
+  SRC+=aa_policy_cache.c
+  AA_POLICY_CACHE_TEST=aa_policy_cache
+endif
+
 EXEC=$(SRC:%.c=%)
 
 TESTS=access \
@@ -195,6 +210,8 @@ ifneq (,$(shell pkg-config --exists dbus-1 && echo TRUE))
 TESTS+=dbus_eavesdrop dbus_message dbus_service dbus_unrequested_reply
 endif
 
+TESTS+=$(AA_POLICY_CACHE_TEST)
+
 # Tests that can crash the kernel should be placed here
 RISKY_TESTS=
 
diff --git a/tests/regression/apparmor/aa_policy_cache.c b/tests/regression/apparmor/aa_policy_cache.c
new file mode 100644
index 0000000..01ae6eb
--- /dev/null
+++ b/tests/regression/apparmor/aa_policy_cache.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2015 Canonical, Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact Canonical Ltd.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/apparmor.h>
+
+#define OPT_CREATE		"create"
+#define OPT_IS_VALID		"is-valid"
+#define OPT_NEW			"new"
+#define OPT_NEW_CREATE		"new-create"
+#define OPT_REMOVE		"remove"
+#define OPT_REMOVE_POLICY	"remove-policy"
+#define OPT_REPLACE_ALL		"replace-all"
+
+static void usage(const char *prog)
+{
+	fprintf(stderr,
+		"FAIL - usage: %s %s <PATH>\n"
+		"              %s %s <PATH>\n"
+		"              %s %s <PATH>\n"
+		"              %s %s <PATH>\n"
+		"              %s %s <PATH>\n"
+		"              %s %s <PROFILE_NAME>\n"
+		"              %s %s <PATH>\n",
+		prog, OPT_CREATE, prog, OPT_IS_VALID, prog, OPT_NEW,
+		prog, OPT_NEW_CREATE, prog, OPT_REMOVE, prog, OPT_REMOVE_POLICY,
+		prog, OPT_REPLACE_ALL);
+}
+
+static int test_create(const char *path)
+{
+	aa_features *features = NULL;
+	aa_policy_cache *policy_cache = NULL;
+	int rc = 1;
+
+	if (aa_features_new_from_kernel(&features)) {
+		perror("FAIL - aa_features_new_from_kernel");
+		goto out;
+	}
+
+	if (aa_policy_cache_new(&policy_cache, features, path, false)) {
+		perror("FAIL - aa_policy_cache_new");
+		goto out;
+	}
+
+	if (aa_policy_cache_create(policy_cache)) {
+		perror("FAIL - aa_policy_cache_create");
+		goto out;
+	}
+
+	rc = 0;
+out:
+	aa_features_unref(features);
+	aa_policy_cache_unref(policy_cache);
+	return rc;
+}
+
+static int test_is_valid(const char *path)
+{
+	aa_features *features = NULL;
+	aa_policy_cache *policy_cache = NULL;
+	int rc = 1;
+
+	if (aa_features_new_from_kernel(&features)) {
+		perror("FAIL - aa_features_new_from_kernel");
+		goto out;
+	}
+
+	if (aa_policy_cache_new(&policy_cache, features, path, false)) {
+		perror("FAIL - aa_policy_cache_new");
+		goto out;
+	}
+
+	if (!aa_policy_cache_is_valid(policy_cache)) {
+		errno = EINVAL;
+		perror("FAIL - aa_policy_cache_is_valid");
+		goto out;
+	}
+
+	rc = 0;
+out:
+	aa_features_unref(features);
+	aa_policy_cache_unref(policy_cache);
+	return rc;
+}
+
+static int test_new(const char *path, bool create)
+{
+	aa_features *features = NULL;
+	aa_policy_cache *policy_cache = NULL;
+	int rc = 1;
+
+	if (aa_features_new_from_kernel(&features)) {
+		perror("FAIL - aa_features_new_from_kernel");
+		goto out;
+	}
+
+	if (aa_policy_cache_new(&policy_cache, features, path, create)) {
+		perror("FAIL - aa_policy_cache_new");
+		goto out;
+	}
+
+	rc = 0;
+out:
+	aa_features_unref(features);
+	aa_policy_cache_unref(policy_cache);
+	return rc;
+}
+
+static int test_remove(const char *path)
+{
+	int rc = 1;
+
+	if (aa_policy_cache_remove(path)) {
+		perror("FAIL - aa_policy_cache_remove");
+		goto out;
+	}
+
+	rc = 0;
+out:
+	return rc;
+}
+
+static int test_remove_policy(const char *name)
+{
+	aa_features *features = NULL;
+	aa_kernel_interface *kernel_interface = NULL;
+	int rc = 1;
+
+	if (aa_features_new_from_kernel(&features)) {
+		perror("FAIL - aa_features_new_from_kernel");
+		goto out;
+	}
+
+	if (aa_kernel_interface_new(&kernel_interface, features, NULL)) {
+		perror("FAIL - aa_kernel_interface_new");
+		goto out;
+	}
+
+	if (aa_kernel_interface_remove_policy(kernel_interface, name)) {
+		perror("FAIL - aa_kernel_interface_remove_policy");
+		goto out;
+	}
+
+	rc = 0;
+out:
+	aa_features_unref(features);
+	return rc;
+}
+
+static int test_replace_all(const char *path)
+{
+	aa_features *features = NULL;
+	aa_policy_cache *policy_cache = NULL;
+	int rc = 1;
+
+	if (aa_features_new_from_kernel(&features)) {
+		perror("FAIL - aa_features_new_from_kernel");
+		goto out;
+	}
+
+	if (aa_policy_cache_new(&policy_cache, features, path, false)) {
+		perror("FAIL - aa_policy_cache_new");
+		goto out;
+	}
+
+	if (aa_policy_cache_replace_all(policy_cache, NULL)) {
+		perror("FAIL - aa_policy_cache_replace_all");
+		goto out;
+	}
+
+	rc = 0;
+out:
+	aa_features_unref(features);
+	aa_policy_cache_unref(policy_cache);
+	return rc;
+}
+
+int main(int argc, char **argv)
+{
+	int rc = 1;
+
+	if (argc != 3) {
+		usage(argv[0]);
+		exit(1);
+	}
+
+	if (strcmp(argv[1], OPT_CREATE) == 0) {
+		rc = test_create(argv[2]);
+	} else if (strcmp(argv[1], OPT_IS_VALID) == 0) {
+		rc = test_is_valid(argv[2]);
+	} else if (strcmp(argv[1], OPT_NEW) == 0) {
+		rc = test_new(argv[2], false);
+	} else if (strcmp(argv[1], OPT_NEW_CREATE) == 0) {
+		rc = test_new(argv[2], true);
+	} else if (strcmp(argv[1], OPT_REMOVE) == 0) {
+		rc = test_remove(argv[2]);
+	} else if (strcmp(argv[1], OPT_REMOVE_POLICY) == 0) {
+		rc = test_remove_policy(argv[2]);
+	} else if (strcmp(argv[1], OPT_REPLACE_ALL) == 0) {
+		rc = test_replace_all(argv[2]);
+	} else {
+		usage(argv[0]);
+	}
+
+	if (!rc)
+		printf("PASS\n");
+
+	exit(rc);
+}
diff --git a/tests/regression/apparmor/aa_policy_cache.sh b/tests/regression/apparmor/aa_policy_cache.sh
new file mode 100755
index 0000000..fb9a830
--- /dev/null
+++ b/tests/regression/apparmor/aa_policy_cache.sh
@@ -0,0 +1,149 @@
+#! /bin/bash
+#	Copyright (C) 2015 Canonical, Ltd.
+#
+#	This program is free software; you can redistribute it and/or
+#	modify it under the terms of the GNU General Public License as
+#	published by the Free Software Foundation, version 2 of the
+#	License.
+
+#=NAME aa_policy_cache
+#=DESCRIPTION
+# This test verifies that the aa_policy_cache API works as expected.
+#=END
+
+pwd=`dirname $0`
+pwd=`cd $pwd ; /bin/pwd`
+
+bin=$pwd
+
+. $bin/prologue.inc
+
+cachedir=$tmpdir/cache
+policies=$(echo aa_policy_cache_test_{0001..1024})
+
+create_cachedir()
+{
+	mkdir -p "$cachedir"
+}
+
+remove_cachedir()
+{
+	if [ -n "$cachedir" ]
+	then
+		rm -rf "$cachedir"
+	fi
+}
+
+create_empty_cache()
+{
+	$test new-create "$cachedir" > /dev/null
+}
+
+create_cache_files()
+{
+	local cachefile
+
+	create_cachedir
+	for policy in $policies
+	do
+		cachefile="${cachedir}/${policy}"
+
+		echo "profile $policy { /f r, }" | ${subdomain} -qS > "$cachefile"
+	done
+}
+
+install_bad_features_file()
+{
+	echo "file {\n}\n" > "${cachedir}/.features"
+}
+
+remove_features_file()
+{
+	if [ -n "$cachedir" ]
+	then
+		rm -f "${cachedir}/.features"
+	fi
+}
+
+verify_policies_are_not_loaded()
+{
+	for policy in $policies
+	do
+		if grep -q "^policy " /sys/kernel/security/apparmor/profiles
+		then
+			fatalerror "Policy \"${policy}\" must not be loaded"
+			return
+		fi
+	done
+}
+
+runchecktest_policies_are_loaded()
+{
+	for policy in $policies
+	do
+		if ! grep -q "^$policy (enforce)" /sys/kernel/security/apparmor/profiles
+		then
+			echo "Error: Policy \"${policy}\" was not loaded"
+			testfailed
+			return
+		fi
+	done
+}
+
+runchecktest_remove_policies()
+{
+	for policy in $policies
+	do
+		runchecktest "AA_POLICY_CACHE remove-policy ($policy)" pass remove-policy "$policy"
+	done
+}
+
+# IMPORTANT: These tests build on themselves so the first failing test can
+# cause many failures
+
+runchecktest "AA_POLICY_CACHE new (no cachedir)" fail new "$cachedir"
+create_cachedir
+runchecktest "AA_POLICY_CACHE new (no .features)" fail new "$cachedir"
+remove_cachedir
+runchecktest "AA_POLICY_CACHE new-create (no cachedir)" pass new-create "$cachedir"
+runchecktest "AA_POLICY_CACHE new-create (existing cache)" pass new-create "$cachedir"
+runchecktest "AA_POLICY_CACHE new (existing cache)" pass new "$cachedir"
+
+runchecktest "AA_POLICY_CACHE is-valid (good .features)" pass is-valid "$cachedir"
+install_bad_features_file
+runchecktest "AA_POLICY_CACHE is-valid (bad .features)" fail is-valid "$cachedir"
+remove_cachedir
+runchecktest "AA_POLICY_CACHE is-valid (no cachedir)" fail is-valid "$cachedir"
+
+create_cachedir
+install_bad_features_file
+runchecktest "AA_POLICY_CACHE create (bad .features)" pass create "$cachedir"
+runchecktest "AA_POLICY_CACHE create (good .features)" pass create "$cachedir"
+remove_features_file
+runchecktest "AA_POLICY_CACHE create (no .features)" fail create "$cachedir"
+remove_cachedir
+runchecktest "AA_POLICY_CACHE create (no cachedir)" fail create "$cachedir"
+
+# Make sure that no test policies are already loaded
+verify_policies_are_not_loaded
+
+runchecktest "AA_POLICY_CACHE replace-all (no cachedir)" fail replace-all "$cachedir"
+create_cachedir
+runchecktest "AA_POLICY_CACHE replace-all (no .features)" fail replace-all "$cachedir"
+create_empty_cache
+runchecktest "AA_POLICY_CACHE replace-all (empty cache)" pass replace-all "$cachedir"
+create_cache_files
+runchecktest "AA_POLICY_CACHE replace-all (full cache)" pass replace-all "$cachedir"
+
+# Test that the previous policy load was successful 
+runchecktest_policies_are_loaded
+
+runchecktest "AA_POLICY_CACHE remove-policy (DNE)" fail remove-policy "aa_policy_cache_test_DNE"
+runchecktest_remove_policies
+
+runchecktest "AA_POLICY_CACHE remove (full cache)" pass remove "$cachedir"
+runchecktest "AA_POLICY_CACHE remove (no .features)" pass remove "$cachedir"
+install_bad_features_file
+runchecktest "AA_POLICY_CACHE remove (empty cache)" pass remove "$cachedir"
+remove_cachedir
+runchecktest "AA_POLICY_CACHE remove (DNE)" fail remove "$cachedir"
-- 
2.1.4




More information about the AppArmor mailing list