[apparmor] [PATCH 01/11] tests: Rename stacking.c to transition.c
John Johansen
john.johansen at canonical.com
Fri May 27 10:59:30 UTC 2016
On 05/25/2016 01:59 PM, Tyler Hicks wrote:
> This test will soon be made to do more than just stack a new profile.
> It will be extended to allow for changing to a new profile and,
> therefore, be renamed.
>
> Signed-off-by: Tyler Hicks <tyhicks at canonical.com>
Acked-by: John Johansen <john.johansen at canonical.com>
> ---
> tests/regression/apparmor/Makefile | 4 +-
> tests/regression/apparmor/exec_stack.sh | 2 +-
> tests/regression/apparmor/stacking.c | 337 ------------------------------
> tests/regression/apparmor/stackonexec.sh | 2 +-
> tests/regression/apparmor/stackprofile.sh | 2 +-
> tests/regression/apparmor/transition.c | 337 ++++++++++++++++++++++++++++++
> 6 files changed, 342 insertions(+), 342 deletions(-)
> delete mode 100644 tests/regression/apparmor/stacking.c
> create mode 100644 tests/regression/apparmor/transition.c
>
> diff --git a/tests/regression/apparmor/Makefile b/tests/regression/apparmor/Makefile
> index ca9a294..87f756a 100644
> --- a/tests/regression/apparmor/Makefile
> +++ b/tests/regression/apparmor/Makefile
> @@ -168,7 +168,7 @@ ifdef USE_SYSTEM
> endif
>
> ifneq (,$(shell pkg-config --atleast-version 2.10.95 libapparmor && echo TRUE))
> - SRC+=stacking.c
> + SRC+=transition.c
> CONDITIONAL_TESTS+=exec_stack stackonexec stackprofile
> else
> $(warning ${nl}\
> @@ -177,7 +177,7 @@ ifdef USE_SYSTEM
> ************************************************************************${nl})
> endif
> else
> - SRC+=aa_policy_cache.c stacking.c
> + SRC+=aa_policy_cache.c transition.c
> CONDITIONAL_TESTS+=exec_stack aa_policy_cache stackonexec stackprofile
> endif
>
> diff --git a/tests/regression/apparmor/exec_stack.sh b/tests/regression/apparmor/exec_stack.sh
> index ef12015..2423dea 100755
> --- a/tests/regression/apparmor/exec_stack.sh
> +++ b/tests/regression/apparmor/exec_stack.sh
> @@ -20,7 +20,7 @@ bin=$pwd
> . $bin/prologue.inc
>
> requires_kernel_features domain/stack
> -settest stacking
> +settest transition
>
> file=$tmpdir/file
> otherfile=$tmpdir/file2
> diff --git a/tests/regression/apparmor/stacking.c b/tests/regression/apparmor/stacking.c
> deleted file mode 100644
> index ac1afce..0000000
> --- a/tests/regression/apparmor/stacking.c
> +++ /dev/null
> @@ -1,337 +0,0 @@
> -/*
> - * Copyright (C) 2014-2016 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.
> - */
> -
> -#define _GNU_SOURCE
> -
> -#include <errno.h>
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -#include <sys/apparmor.h>
> -#include <sys/socket.h>
> -#include <sys/types.h>
> -#include <unistd.h>
> -
> -#include "changehat.h" /* for do_open() */
> -
> -#define STACK_DELIM "//&"
> -#define STACK_DELIM_LEN strlen(STACK_DELIM)
> -
> -#define NO_MODE "(null)"
> -
> -static void file_io(const char *file)
> -{
> - int rc = do_open(file);
> -
> - if (rc != 0)
> - exit(rc);
> -}
> -
> -struct single_label {
> - const char *label;
> - size_t len;
> -};
> -
> -#define MAX_LABELS 32
> -
> -struct compound_label {
> - size_t num_labels;
> - struct single_label labels[MAX_LABELS];
> -};
> -
> -/**
> - * Initializes @sl by parsing @compound_label. Returns a pointer to the
> - * location of the next label in the compound label string, which should be
> - * passed in as @compound_label the next time that next_label() is called. NULL
> - * is returned when there are no more labels in @compound_label.
> - */
> -static const char *next_label(struct single_label *sl,
> - const char *compound_label)
> -{
> - const char *delim;
> -
> - if (!compound_label || compound_label[0] == '\0')
> - return NULL;
> -
> - delim = strstr(compound_label, STACK_DELIM);
> - if (!delim) {
> - sl->label = compound_label;
> - sl->len = strlen(sl->label);
> - return sl->label + sl->len;
> - }
> -
> - sl->label = compound_label;
> - sl->len = delim - sl->label;
> - return delim + STACK_DELIM_LEN;
> -}
> -
> -/* Returns true if the compound label was constructed successfully */
> -static bool compound_label_init(struct compound_label *cl,
> - const char *compound_label)
> -{
> - memset(cl, 0, sizeof(*cl));
> - while ((compound_label = next_label(&cl->labels[cl->num_labels],
> - compound_label))) {
> - cl->num_labels++;
> -
> - if (cl->num_labels == MAX_LABELS)
> - return false;
> - }
> -
> - return true;
> -}
> -
> -/* Returns true if the compound label contains the single label */
> -static bool compound_label_contains(struct compound_label *cl,
> - struct single_label *sl)
> -{
> - bool matched = false;
> - size_t i;
> -
> - for (i = 0; !matched && i < cl->num_labels; i++) {
> - if (cl->labels[i].len != sl->len)
> - continue;
> -
> - if (strncmp(cl->labels[i].label, sl->label, sl->len))
> - continue;
> -
> - matched = true;
> - }
> -
> - return matched;
> -}
> -
> -/* Returns true if the two compound labels contain the same label sets */
> -static bool compound_labels_equal(struct compound_label *cl1,
> - struct compound_label *cl2)
> -{
> - size_t i;
> -
> - if (cl1->num_labels != cl2->num_labels)
> - return false;
> -
> - for (i = 0; i < cl1->num_labels; i++) {
> - if (!compound_label_contains(cl2, &cl1->labels[i]))
> - return false;
> - }
> -
> - return true;
> -}
> -
> -/**
> - * Verifies that the current confinement context matches the expected context.
> - *
> - * Either @expected_label or @expected_mode can be NULL if their values should
> - * not be verified. If a NULL mode is expected, as what happens when an
> - * unconfined process calls aa_getcon(2), then @expected_mode should be equal
> - * to NO_MODE.
> - */
> -static void verify_confinement_context(const char *expected_label,
> - const char *expected_mode)
> -{
> - char *label, *mode;
> - int expected_rc, rc;
> - bool null_expected_mode = expected_mode ?
> - strcmp(NO_MODE, expected_mode) == 0 : false;
> -
> - rc = aa_getcon(&label, &mode);
> - if (rc < 0) {
> - int err = errno;
> - fprintf(stderr, "FAIL - aa_getcon: %m");
> - exit(err);
> - }
> -
> - if (expected_label) {
> - struct compound_label cl, expected_cl;
> -
> - if (!compound_label_init(&cl, label)) {
> - fprintf(stderr, "FAIL - could not parse current compound label: %s\n",
> - label);
> - rc = EINVAL;
> - goto err;
> - }
> -
> - if (!compound_label_init(&expected_cl, expected_label)) {
> - fprintf(stderr, "FAIL - could not parse expected compound label: %s\n",
> - expected_label);
> - rc = EINVAL;
> - goto err;
> - }
> -
> - if (!compound_labels_equal(&cl, &expected_cl)) {
> - fprintf(stderr, "FAIL - label \"%s\" != expected_label \"%s\"\n",
> - label, expected_label);
> - rc = EINVAL;
> - goto err;
> - }
> - }
> -
> - if (expected_mode &&
> - ((!mode && !null_expected_mode) ||
> - (mode && strcmp(mode, expected_mode)))) {
> - fprintf(stderr, "FAIL - mode \"%s\" != expected_mode \"%s\"\n",
> - mode, expected_mode);
> - rc = EINVAL;
> - goto err;
> - }
> -
> - expected_rc = expected_label ? strlen(expected_label) : strlen(label);
> -
> - /**
> - * Add the expected bytes following the returned label string:
> - *
> - * ' ' + '(' + mode + ')'
> - */
> - if (expected_mode && !null_expected_mode)
> - expected_rc += 1 + 1 + strlen(expected_mode) + 1;
> - else if (mode)
> - expected_rc += 1 + 1 + strlen(mode) + 1;
> -
> - expected_rc++; /* Trailing NUL terminator */
> -
> - if (rc != expected_rc) {
> - fprintf(stderr, "FAIL - rc (%d) != expected_rc (%d)\n",
> - rc, expected_rc);
> - rc = EINVAL;
> - goto err;
> - }
> -
> - return;
> -err:
> - free(label);
> - exit(EINVAL);
> -}
> -
> -static void stack_onexec(const char *label)
> -{
> - if (aa_stack_onexec(label) != 0) {
> - int err = errno;
> - perror("FAIL - aa_stack_onexec");
> - exit(err);
> - }
> -}
> -
> -static void stack_profile(const char *label)
> -{
> - if (aa_stack_profile(label) != 0) {
> - int err = errno;
> - perror("FAIL - aa_stack_profile");
> - exit(err);
> - }
> -}
> -
> -static void exec(const char *prog, char **argv)
> -{
> - int err;
> -
> - execv(prog, argv);
> - err = errno;
> - perror("FAIL - execv");
> - exit(err);
> -}
> -
> -static void usage(const char *prog)
> -{
> - fprintf(stderr,
> - "%s: [-o <LABEL> | -p <LABEL>] [-l <LABEL>] [-m <MODE>] [-f <FILE>] [-- ... [-- ...]]\n"
> - " -o <LABEL>\tCall aa_stack_onexec(LABEL)\n"
> - " -p <LABEL>\tCall aa_stack_profile(LABEL)\n"
> - " -l <LABEL>\tVerify that aa_getcon() returns LABEL\n"
> - " -m <MODE>\tVerify that aa_getcon() returns MODE. Set to \"%s\" if a NULL mode is expected.\n"
> - " -f <FILE>\tOpen FILE and attempt to write to and read from it\n\n"
> - "If \"--\" is encountered, execv() will be called using the following argument\n"
> - "as the program to execute and passing it all of the arguments following the\n"
> - "program name.\n", prog, NO_MODE);
> - exit(EINVAL);
> -}
> -
> -struct options {
> - const char *file;
> - const char *expected_label;
> - const char *expected_mode;
> - const char *stack_onexec;
> - const char *stack_profile;
> - const char *exec;
> - char **exec_argv;
> -};
> -
> -static void parse_opts(int argc, char **argv, struct options *opts)
> -{
> - int o;
> -
> - memset(opts, 0, sizeof(*opts));
> - while ((o = getopt(argc, argv, "f:l:m:o:p:")) != -1) {
> - switch (o) {
> - case 'f': /* file */
> - opts->file = optarg;
> - break;
> - case 'l': /* expected label */
> - opts->expected_label = optarg;
> - break;
> - case 'm': /* expected mode */
> - opts->expected_mode = optarg;
> - break;
> - case 'o': /* aa_stack_onexec */
> - opts->stack_onexec = optarg;
> - break;
> - case 'p': /* aa_stack_profile */
> - opts->stack_profile = optarg;
> - break;
> - default: /* '?' */
> - usage(argv[0]);
> - }
> - }
> -
> - /* Can only specify one or the other */
> - if (opts->stack_onexec && opts->stack_profile) {
> - usage(argv[0]);
> - }
> -
> - if (optind < argc) {
> - /* Ensure that the previous option was "--" */
> - if (optind == 0 || strcmp("--", argv[optind - 1]))
> - usage(argv[0]);
> -
> - opts->exec = argv[optind];
> - opts->exec_argv = &argv[optind];
> - }
> -}
> -
> -int main(int argc, char **argv)
> -{
> - struct options opts;
> -
> - parse_opts(argc, argv, &opts);
> -
> - if (opts.stack_onexec)
> - stack_onexec(opts.stack_onexec);
> - else if (opts.stack_profile)
> - stack_profile(opts.stack_profile);
> -
> - if (opts.file)
> - file_io(opts.file);
> -
> - if (opts.expected_label || opts.expected_mode)
> - verify_confinement_context(opts.expected_label,
> - opts.expected_mode);
> -
> - if (opts.exec)
> - exec(opts.exec, opts.exec_argv);
> -
> - printf("PASS\n");
> - exit(0);
> -}
> -
> diff --git a/tests/regression/apparmor/stackonexec.sh b/tests/regression/apparmor/stackonexec.sh
> index 7bad824..565fbfc 100755
> --- a/tests/regression/apparmor/stackonexec.sh
> +++ b/tests/regression/apparmor/stackonexec.sh
> @@ -20,7 +20,7 @@ bin=$pwd
> . $bin/prologue.inc
>
> requires_kernel_features domain/stack
> -settest stacking
> +settest transition
>
> file=$tmpdir/file
> otherfile=$tmpdir/file2
> diff --git a/tests/regression/apparmor/stackprofile.sh b/tests/regression/apparmor/stackprofile.sh
> index 7f248a1..efe8a7c 100755
> --- a/tests/regression/apparmor/stackprofile.sh
> +++ b/tests/regression/apparmor/stackprofile.sh
> @@ -20,7 +20,7 @@ bin=$pwd
> . $bin/prologue.inc
>
> requires_kernel_features domain/stack
> -settest stacking
> +settest transition
>
> file=$tmpdir/file
> otherfile=$tmpdir/file2
> diff --git a/tests/regression/apparmor/transition.c b/tests/regression/apparmor/transition.c
> new file mode 100644
> index 0000000..ac1afce
> --- /dev/null
> +++ b/tests/regression/apparmor/transition.c
> @@ -0,0 +1,337 @@
> +/*
> + * Copyright (C) 2014-2016 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.
> + */
> +
> +#define _GNU_SOURCE
> +
> +#include <errno.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/apparmor.h>
> +#include <sys/socket.h>
> +#include <sys/types.h>
> +#include <unistd.h>
> +
> +#include "changehat.h" /* for do_open() */
> +
> +#define STACK_DELIM "//&"
> +#define STACK_DELIM_LEN strlen(STACK_DELIM)
> +
> +#define NO_MODE "(null)"
> +
> +static void file_io(const char *file)
> +{
> + int rc = do_open(file);
> +
> + if (rc != 0)
> + exit(rc);
> +}
> +
> +struct single_label {
> + const char *label;
> + size_t len;
> +};
> +
> +#define MAX_LABELS 32
> +
> +struct compound_label {
> + size_t num_labels;
> + struct single_label labels[MAX_LABELS];
> +};
> +
> +/**
> + * Initializes @sl by parsing @compound_label. Returns a pointer to the
> + * location of the next label in the compound label string, which should be
> + * passed in as @compound_label the next time that next_label() is called. NULL
> + * is returned when there are no more labels in @compound_label.
> + */
> +static const char *next_label(struct single_label *sl,
> + const char *compound_label)
> +{
> + const char *delim;
> +
> + if (!compound_label || compound_label[0] == '\0')
> + return NULL;
> +
> + delim = strstr(compound_label, STACK_DELIM);
> + if (!delim) {
> + sl->label = compound_label;
> + sl->len = strlen(sl->label);
> + return sl->label + sl->len;
> + }
> +
> + sl->label = compound_label;
> + sl->len = delim - sl->label;
> + return delim + STACK_DELIM_LEN;
> +}
> +
> +/* Returns true if the compound label was constructed successfully */
> +static bool compound_label_init(struct compound_label *cl,
> + const char *compound_label)
> +{
> + memset(cl, 0, sizeof(*cl));
> + while ((compound_label = next_label(&cl->labels[cl->num_labels],
> + compound_label))) {
> + cl->num_labels++;
> +
> + if (cl->num_labels == MAX_LABELS)
> + return false;
> + }
> +
> + return true;
> +}
> +
> +/* Returns true if the compound label contains the single label */
> +static bool compound_label_contains(struct compound_label *cl,
> + struct single_label *sl)
> +{
> + bool matched = false;
> + size_t i;
> +
> + for (i = 0; !matched && i < cl->num_labels; i++) {
> + if (cl->labels[i].len != sl->len)
> + continue;
> +
> + if (strncmp(cl->labels[i].label, sl->label, sl->len))
> + continue;
> +
> + matched = true;
> + }
> +
> + return matched;
> +}
> +
> +/* Returns true if the two compound labels contain the same label sets */
> +static bool compound_labels_equal(struct compound_label *cl1,
> + struct compound_label *cl2)
> +{
> + size_t i;
> +
> + if (cl1->num_labels != cl2->num_labels)
> + return false;
> +
> + for (i = 0; i < cl1->num_labels; i++) {
> + if (!compound_label_contains(cl2, &cl1->labels[i]))
> + return false;
> + }
> +
> + return true;
> +}
> +
> +/**
> + * Verifies that the current confinement context matches the expected context.
> + *
> + * Either @expected_label or @expected_mode can be NULL if their values should
> + * not be verified. If a NULL mode is expected, as what happens when an
> + * unconfined process calls aa_getcon(2), then @expected_mode should be equal
> + * to NO_MODE.
> + */
> +static void verify_confinement_context(const char *expected_label,
> + const char *expected_mode)
> +{
> + char *label, *mode;
> + int expected_rc, rc;
> + bool null_expected_mode = expected_mode ?
> + strcmp(NO_MODE, expected_mode) == 0 : false;
> +
> + rc = aa_getcon(&label, &mode);
> + if (rc < 0) {
> + int err = errno;
> + fprintf(stderr, "FAIL - aa_getcon: %m");
> + exit(err);
> + }
> +
> + if (expected_label) {
> + struct compound_label cl, expected_cl;
> +
> + if (!compound_label_init(&cl, label)) {
> + fprintf(stderr, "FAIL - could not parse current compound label: %s\n",
> + label);
> + rc = EINVAL;
> + goto err;
> + }
> +
> + if (!compound_label_init(&expected_cl, expected_label)) {
> + fprintf(stderr, "FAIL - could not parse expected compound label: %s\n",
> + expected_label);
> + rc = EINVAL;
> + goto err;
> + }
> +
> + if (!compound_labels_equal(&cl, &expected_cl)) {
> + fprintf(stderr, "FAIL - label \"%s\" != expected_label \"%s\"\n",
> + label, expected_label);
> + rc = EINVAL;
> + goto err;
> + }
> + }
> +
> + if (expected_mode &&
> + ((!mode && !null_expected_mode) ||
> + (mode && strcmp(mode, expected_mode)))) {
> + fprintf(stderr, "FAIL - mode \"%s\" != expected_mode \"%s\"\n",
> + mode, expected_mode);
> + rc = EINVAL;
> + goto err;
> + }
> +
> + expected_rc = expected_label ? strlen(expected_label) : strlen(label);
> +
> + /**
> + * Add the expected bytes following the returned label string:
> + *
> + * ' ' + '(' + mode + ')'
> + */
> + if (expected_mode && !null_expected_mode)
> + expected_rc += 1 + 1 + strlen(expected_mode) + 1;
> + else if (mode)
> + expected_rc += 1 + 1 + strlen(mode) + 1;
> +
> + expected_rc++; /* Trailing NUL terminator */
> +
> + if (rc != expected_rc) {
> + fprintf(stderr, "FAIL - rc (%d) != expected_rc (%d)\n",
> + rc, expected_rc);
> + rc = EINVAL;
> + goto err;
> + }
> +
> + return;
> +err:
> + free(label);
> + exit(EINVAL);
> +}
> +
> +static void stack_onexec(const char *label)
> +{
> + if (aa_stack_onexec(label) != 0) {
> + int err = errno;
> + perror("FAIL - aa_stack_onexec");
> + exit(err);
> + }
> +}
> +
> +static void stack_profile(const char *label)
> +{
> + if (aa_stack_profile(label) != 0) {
> + int err = errno;
> + perror("FAIL - aa_stack_profile");
> + exit(err);
> + }
> +}
> +
> +static void exec(const char *prog, char **argv)
> +{
> + int err;
> +
> + execv(prog, argv);
> + err = errno;
> + perror("FAIL - execv");
> + exit(err);
> +}
> +
> +static void usage(const char *prog)
> +{
> + fprintf(stderr,
> + "%s: [-o <LABEL> | -p <LABEL>] [-l <LABEL>] [-m <MODE>] [-f <FILE>] [-- ... [-- ...]]\n"
> + " -o <LABEL>\tCall aa_stack_onexec(LABEL)\n"
> + " -p <LABEL>\tCall aa_stack_profile(LABEL)\n"
> + " -l <LABEL>\tVerify that aa_getcon() returns LABEL\n"
> + " -m <MODE>\tVerify that aa_getcon() returns MODE. Set to \"%s\" if a NULL mode is expected.\n"
> + " -f <FILE>\tOpen FILE and attempt to write to and read from it\n\n"
> + "If \"--\" is encountered, execv() will be called using the following argument\n"
> + "as the program to execute and passing it all of the arguments following the\n"
> + "program name.\n", prog, NO_MODE);
> + exit(EINVAL);
> +}
> +
> +struct options {
> + const char *file;
> + const char *expected_label;
> + const char *expected_mode;
> + const char *stack_onexec;
> + const char *stack_profile;
> + const char *exec;
> + char **exec_argv;
> +};
> +
> +static void parse_opts(int argc, char **argv, struct options *opts)
> +{
> + int o;
> +
> + memset(opts, 0, sizeof(*opts));
> + while ((o = getopt(argc, argv, "f:l:m:o:p:")) != -1) {
> + switch (o) {
> + case 'f': /* file */
> + opts->file = optarg;
> + break;
> + case 'l': /* expected label */
> + opts->expected_label = optarg;
> + break;
> + case 'm': /* expected mode */
> + opts->expected_mode = optarg;
> + break;
> + case 'o': /* aa_stack_onexec */
> + opts->stack_onexec = optarg;
> + break;
> + case 'p': /* aa_stack_profile */
> + opts->stack_profile = optarg;
> + break;
> + default: /* '?' */
> + usage(argv[0]);
> + }
> + }
> +
> + /* Can only specify one or the other */
> + if (opts->stack_onexec && opts->stack_profile) {
> + usage(argv[0]);
> + }
> +
> + if (optind < argc) {
> + /* Ensure that the previous option was "--" */
> + if (optind == 0 || strcmp("--", argv[optind - 1]))
> + usage(argv[0]);
> +
> + opts->exec = argv[optind];
> + opts->exec_argv = &argv[optind];
> + }
> +}
> +
> +int main(int argc, char **argv)
> +{
> + struct options opts;
> +
> + parse_opts(argc, argv, &opts);
> +
> + if (opts.stack_onexec)
> + stack_onexec(opts.stack_onexec);
> + else if (opts.stack_profile)
> + stack_profile(opts.stack_profile);
> +
> + if (opts.file)
> + file_io(opts.file);
> +
> + if (opts.expected_label || opts.expected_mode)
> + verify_confinement_context(opts.expected_label,
> + opts.expected_mode);
> +
> + if (opts.exec)
> + exec(opts.exec, opts.exec_argv);
> +
> + printf("PASS\n");
> + exit(0);
> +}
> +
>
More information about the AppArmor
mailing list