[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