[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