mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-30 22:05:27 +00:00
tests: Add regression tests for the aa_policy_cache API
The aa_features and aa_kernel_interface APIs get a little bit of testing, as well. Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Acked-by: Steve Beattie <steve@nxnw.org>
This commit is contained in:
@@ -135,6 +135,21 @@ Install libdbus-1-dev or equivalent package to build and run these tests${nl}\
|
|||||||
************************************************************************${nl})
|
************************************************************************${nl})
|
||||||
endif
|
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=%)
|
EXEC=$(SRC:%.c=%)
|
||||||
|
|
||||||
TESTS=access \
|
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
|
TESTS+=dbus_eavesdrop dbus_message dbus_service dbus_unrequested_reply
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
TESTS+=$(AA_POLICY_CACHE_TEST)
|
||||||
|
|
||||||
# Tests that can crash the kernel should be placed here
|
# Tests that can crash the kernel should be placed here
|
||||||
RISKY_TESTS=
|
RISKY_TESTS=
|
||||||
|
|
||||||
|
229
tests/regression/apparmor/aa_policy_cache.c
Normal file
229
tests/regression/apparmor/aa_policy_cache.c
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
* 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_kernel_interface_unref(kernel_interface);
|
||||||
|
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);
|
||||||
|
}
|
149
tests/regression/apparmor/aa_policy_cache.sh
Executable file
149
tests/regression/apparmor/aa_policy_cache.sh
Executable file
@@ -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"
|
Reference in New Issue
Block a user