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

Tyler Hicks tyhicks at canonical.com
Wed Mar 25 21:26:57 UTC 2015


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>
> ---
>  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
-------------- 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/20150325/d536972c/attachment.pgp>


More information about the AppArmor mailing list