[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