[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