[apparmor] [PATCH v2 46/42] tests: Add regression tests for the aa_policy_cache API
Steve Beattie
steve at nxnw.org
Thu Mar 26 07:48:30 UTC 2015
On Wed, Mar 25, 2015 at 04:26:57PM -0500, Tyler Hicks wrote:
> On 2015-03-25 02:03:40, Tyler Hicks wrote:
> > 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>
I've already ack'ed your followup changes to this, but
Acked-by: Steve Beattie <steve at nxnw.org> for this as well.
> > ---
> > 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;
>
> I didn't call aa_kernel_interface_unref(kernel_interface) here, which
> causes a memory leak. I've made the change in my local branch.
>
> Tyler
>
> > +}
> > +
> > +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
> >
> >
> > --
> > AppArmor mailing list
> > AppArmor at lists.ubuntu.com
> > Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
> --
> AppArmor mailing list
> AppArmor at lists.ubuntu.com
> Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
--
Steve Beattie
<sbeattie at ubuntu.com>
http://NxNW.org/~steve/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <https://lists.ubuntu.com/archives/apparmor/attachments/20150326/2c10ed60/attachment-0001.pgp>
More information about the AppArmor
mailing list