From c2b8a723176b874f92fd09c86d5df1ac2e722a9c Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 8 Oct 2014 13:20:20 -0700 Subject: [PATCH] disable downgrade and not enforced rule messages by default Currently the apparmor parser warns about rules that are not enforced or downgraded. This is a problem for distros that are not carrying the out of tree kernel patches, as most profile loads result in warnings. Change the behavior to not output a message unless a warn flag is passed. This patch adds 2 different warn flags --warn rule-downgraded # warn if a rule is downgraded --warn rule-not-enforced # warn if a rule is not enforced at all If the warnings are desired by default the flags can be set in the parser.conf file. v2 of patch - update man page - add --warn to usage statement - make --quiet clear warn flags Signed-off-by: John Johansen Acked-by: Steve Beattie --- parser/af_unix.cc | 6 ++++-- parser/apparmor_parser.pod | 10 ++++++++++ parser/dbus.cc | 2 +- parser/mount.cc | 2 +- parser/parser.h | 7 +++++++ parser/parser_common.c | 1 + parser/parser_interface.c | 2 +- parser/parser_main.c | 28 ++++++++++++++++++++++++++++ parser/ptrace.cc | 2 +- parser/signal.cc | 2 +- 10 files changed, 55 insertions(+), 7 deletions(-) diff --git a/parser/af_unix.cc b/parser/af_unix.cc index 55549c7f3..11fc137f2 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -176,7 +176,8 @@ static void warn_once(const char *name, const char *msg) static void warn_once(const char *name) { - warn_once(name, "extended network unix socket rules not enforced"); + if (warnflags & WARN_RULE_NOT_ENFORCED) + warn_once(name, "extended network unix socket rules not enforced"); } static void writeu16(std::ostringstream &o, int v) @@ -321,7 +322,8 @@ int unix_rule::gen_policy_re(Profile &prof) if (kernel_supports_network) { /* only warn if we are building against a kernel * that requires downgrading */ - warn_once(prof.name, "downgrading extended network unix socket rule to generic network rule\n"); + if (warnflags & WARN_RULE_DOWNGRADED) + warn_once(prof.name, "downgrading extended network unix socket rule to generic network rule\n"); /* TODO: add ability to abort instead of downgrade */ return RULE_OK; } diff --git a/parser/apparmor_parser.pod b/parser/apparmor_parser.pod index fc5db256a..90db4ae35 100644 --- a/parser/apparmor_parser.pod +++ b/parser/apparmor_parser.pod @@ -239,6 +239,16 @@ Do not report on the profiles as they are loaded, and not show warnings. Report on the profiles as they are loaded, and show warnings. +=item --warn=n + +Enable various warnings during policy compilation. A single dump flag +can be specified per --warn option, but the --warn flag can be passed +multiple times. + + apparmor_parser --warn=rules-not-enforced ... + +Use --help=warn to see a full list of which warn flags are supported. + =item -d, --debug Given once, only checks the profiles to ensure syntactic correctness. diff --git a/parser/dbus.cc b/parser/dbus.cc index a01b2b196..9cdb19d93 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -194,7 +194,7 @@ static void warn_once(const char *name) { static const char *warned_name = NULL; - if (warned_name != name) { + if ((warnflags & WARN_RULE_NOT_ENFORCED) && warned_name != name) { cerr << "Warning from profile " << name << " ("; if (current_filename) cerr << current_filename; diff --git a/parser/mount.cc b/parser/mount.cc index 0f6408036..f3a9a91fc 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -558,7 +558,7 @@ static void warn_once(const char *name) { static const char *warned_name = NULL; - if (warned_name != name) { + if ((warnflags & WARN_RULE_NOT_ENFORCED) && warned_name != name) { cerr << "Warning from profile " << name << " ("; if (current_filename) cerr << current_filename; diff --git a/parser/parser.h b/parser/parser.h index d4d97a236..c20109dce 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -47,6 +47,13 @@ class rule_t; */ extern int parser_token; + +#define WARN_RULE_NOT_ENFORCED 1 +#define WARN_RULE_DOWNGRADED 2 + +extern dfaflags_t warnflags; + + typedef enum pattern_t pattern_t; struct prefixes { diff --git a/parser/parser_common.c b/parser/parser_common.c index 517435fc9..b41e3ce28 100644 --- a/parser/parser_common.c +++ b/parser/parser_common.c @@ -80,6 +80,7 @@ int current_lineno = 1; int option = OPTION_ADD; dfaflags_t dfaflags = (dfaflags_t)(DFA_CONTROL_TREE_NORMAL | DFA_CONTROL_TREE_SIMPLE | DFA_CONTROL_MINIMIZE | DFA_CONTROL_DIFF_ENCODE); +dfaflags_t warnflags = 0; char *subdomainbase = NULL; const char *progname = __FILE__; diff --git a/parser/parser_interface.c b/parser/parser_interface.c index d535803fd..855e09f2f 100644 --- a/parser/parser_interface.c +++ b/parser/parser_interface.c @@ -442,7 +442,7 @@ void sd_serialize_profile(std::ostringstream &buf, Profile *profile, sd_write_uint16(buf, profile->net.deny[i] & profile->net.quiet[i]); } sd_write_arrayend(buf); - } else if (profile->net.allow) + } else if (profile->net.allow && (warnflags & WARN_RULE_NOT_ENFORCED)) pwarn(_("profile %s network rules not enforced\n"), profile->name); if (profile->policy.dfa) { diff --git a/parser/parser_main.c b/parser/parser_main.c index a7d94e15f..51649ba08 100644 --- a/parser/parser_main.c +++ b/parser/parser_main.c @@ -127,6 +127,7 @@ struct option long_options[] = { {"preprocess", 0, 0, 'p'}, {"abort-on-error", 0, 0, 132}, /* no short option */ {"skip-bad-cache-rebuild", 0, 0, 133}, /* no short option */ + {"warn", 1, 0, 134}, /* no short option */ {NULL, 0, 0, 0}, }; @@ -178,9 +179,25 @@ static void display_usage(const char *command) "-h [cmd], --help[=cmd] Display this text or info about cmd\n" "--abort-on-error Abort processing of profiles on first error\n" "--skip-bad-cache-rebuild Do not try rebuilding the cache if it is rejected by the kernel\n" + "--warn n Enable warnings (see --help=warn)\n" ,command); } +optflag_table_t warnflag_table[] = { + { 0, "rule-not-enforced", "warn if a rule is not enforced", WARN_RULE_NOT_ENFORCED }, + { 0, "rule-downgraded", "warn if a rule is downgraded to a lesser but still enforcing rule", WARN_RULE_DOWNGRADED }, + { 0, NULL, NULL, 0 }, +}; + +void display_warn(const char *command) +{ + display_version(); + printf("\n%s: --warn [Option]\n\n" + "Options:\n" + "--------\n" + ,command); + print_flag_table(warnflag_table); +} /* Treat conf file like options passed on command line */ @@ -285,6 +302,8 @@ static int process_arg(int c, char *optarg) strcmp(optarg, "optimize") == 0 || strcmp(optarg, "O") == 0) { display_optimize(progname); + } else if (strcmp(optarg, "warn") == 0) { + display_warn(progname); } else { PERROR("%s: Invalid --help option %s\n", progname, optarg); @@ -384,6 +403,7 @@ static int process_arg(int c, char *optarg) case 'q': conf_verbose = 0; conf_quiet = 1; + warnflags = 0; break; case 'v': conf_verbose = 1; @@ -435,6 +455,14 @@ static int process_arg(int c, char *optarg) preprocess_only = 1; skip_mode_force = 1; break; + case 134: + if (!handle_flag_table(warnflag_table, optarg, + &warnflags)) { + PERROR("%s: Invalid --warn option %s\n", + progname, optarg); + exit(1); + } + break; default: display_usage(progname); exit(1); diff --git a/parser/ptrace.cc b/parser/ptrace.cc index 1bdea8fee..6f2891a26 100644 --- a/parser/ptrace.cc +++ b/parser/ptrace.cc @@ -105,7 +105,7 @@ static void warn_once(const char *name) { static const char *warned_name = NULL; - if (warned_name != name) { + if ((warnflags & WARN_RULE_NOT_ENFORCED) && warned_name != name) { cerr << "Warning from profile " << name << " ("; if (current_filename) cerr << current_filename; diff --git a/parser/signal.cc b/parser/signal.cc index e12a8f4dd..7f9aa26da 100644 --- a/parser/signal.cc +++ b/parser/signal.cc @@ -241,7 +241,7 @@ static void warn_once(const char *name) { static const char *warned_name = NULL; - if (warned_name != name) { + if ((warnflags & WARN_RULE_NOT_ENFORCED) && warned_name != name) { cerr << "Warning from profile " << name << " ("; if (current_filename) cerr << current_filename;