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 <[email protected]>

Acked-by: John Johansen <[email protected]>

> ---
>  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);
> +}
> +
> 


-- 
AppArmor mailing list
[email protected]
Modify settings or unsubscribe at: 
https://lists.ubuntu.com/mailman/listinfo/apparmor

Reply via email to