From b255ff88318253025a8a11832331b2300fbd9c1b Mon Sep 17 00:00:00 2001 From: John Johansen Date: Tue, 14 Sep 2021 17:18:36 -0700 Subject: [PATCH 01/25] parser: cleanup Makefile header dependencies Recent work on the parser has surfaced missing header dependencies and other issues. Cleanup up and simplify the dependencies so it is harder to break them. Signed-off-by: John Johansen --- parser/Makefile | 86 +++++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/parser/Makefile b/parser/Makefile index f95fd4af2..c91794dd2 100644 --- a/parser/Makefile +++ b/parser/Makefile @@ -103,9 +103,16 @@ SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \ mount.cc dbus.cc profile.cc rule.cc signal.cc ptrace.cc \ af_rule.cc af_unix.cc policy_cache.c default_features.c userns.cc \ mqueue.cc -HDRS = parser.h parser_include.h immunix.h mount.h dbus.h lib.h profile.h \ - rule.h common_optarg.h signal.h ptrace.h network.h af_rule.h af_unix.h \ - policy_cache.h file_cache.h userns.h mqueue.h +STATIC_HDRS = af_rule.h af_unix.h capability.h common_optarg.h dbus.h \ + file_cache.h immunix.h lib.h mount.h network.h parser.h \ + parser_include.h parser_version.h policy_cache.h policydb.h \ + profile.h ptrace.h rule.h signal.h userns.h mqueue.h + +SPECIAL_HDRS = parser_yacc.h unit_test.h base_cap_names.h +GENERATED_HDRS = af_names.h generated_af_names.h \ + cap_names.h generated_cap_names.h parser_version.h +LIBAA_HDRS = libapparmor_re/apparmor_re.h libapparmor_re/aare_rules.h + TOOLS = apparmor_parser OBJECTS = $(patsubst %.cc, %.o, $(SRCS:.c=.o)) @@ -167,8 +174,11 @@ else endif export Q VERBOSE BUILD_OUTPUT -po/${NAME}.pot: ${SRCS} ${HDRS} - $(MAKE) -C po ${NAME}.pot NAME=${NAME} SOURCES="${SRCS} ${HDRS}" +HDRS=$(STATIC_HDRS) $(GENERATED_HDRS) parser_yacc.h $(LIBAA_HDRS) $(APPARMOR_H) + + +po/${NAME}.pot: ${SRCS} ${STATIC_HDRS} + $(MAKE) -C po ${NAME}.pot NAME=${NAME} SOURCES="${SRCS} ${STATIC_HDRS}" techdoc.pdf: techdoc.tex timestamp=$(shell date --utc "+%Y%m%d%H%M%S%z" -r $< );\ @@ -218,94 +228,94 @@ apparmor_parser: $(OBJECTS) $(AAREOBJECTS) $(LIBAPPARMOR_A) $(CXX) $(LDFLAGS) $(EXTRA_CFLAGS) -o $@ $(OBJECTS) $(LIBS) \ ${LEXLIB} $(AAREOBJECTS) $(AARE_LDFLAGS) $(AALIB) -parser_yacc.c parser_yacc.h: parser_yacc.y parser.h profile.h file_cache.h +parser_yacc.c parser_yacc.h: parser_yacc.y $(STATIC_HDRS) $(DYNAMIC_HDRS) $(YACC) $(YFLAGS) -o parser_yacc.c parser_yacc.y -parser_lex.c: parser_lex.l parser_yacc.h parser.h profile.h mount.h dbus.h policy_cache.h file_cache.h +parser_lex.c: parser_lex.l $(HDRS) $(LEX) ${LEXFLAGS} -o$@ $< -parser_lex.o: parser_lex.c parser.h parser_yacc.h +parser_lex.o: parser_lex.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_misc.o: parser_misc.c parser.h parser_yacc.h profile.h cap_names.h $(APPARMOR_H) +parser_misc.o: parser_misc.c $(HDRS) unit_test.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_yacc.o: parser_yacc.c parser_yacc.h $(APPARMOR_H) +parser_yacc.o: parser_yacc.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_main.o: parser_main.c parser.h parser_version.h policy_cache.h file_cache.h libapparmor_re/apparmor_re.h $(APPARMOR_H) +parser_main.o: parser_main.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_interface.o: parser_interface.c parser.h profile.h libapparmor_re/apparmor_re.h +parser_interface.o: parser_interface.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_include.o: parser_include.c parser.h parser_include.h file_cache.h +parser_include.o: parser_include.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_merge.o: parser_merge.c parser.h profile.h +parser_merge.o: parser_merge.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_regex.o: parser_regex.c parser.h profile.h libapparmor_re/apparmor_re.h libapparmor_re/aare_rules.h $(APPARMOR_H) +parser_regex.o: parser_regex.c $(HDRS) unit_test.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_symtab.o: parser_symtab.c parser.h +parser_symtab.o: parser_symtab.c $(HDRS) unit_test.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_variable.o: parser_variable.c parser.h profile.h +parser_variable.o: parser_variable.c $(HDRS) unit_test.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_policy.o: parser_policy.c parser.h parser_yacc.h profile.h +parser_policy.o: parser_policy.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_alias.o: parser_alias.c parser.h profile.h +parser_alias.o: parser_alias.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -parser_common.o: parser_common.c parser.h file_cache.h +parser_common.o: parser_common.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -mount.o: mount.cc mount.h parser.h immunix.h rule.h +mount.o: mount.cc mount.h $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -common_optarg.o: common_optarg.c common_optarg.h parser.h libapparmor_re/apparmor_re.h +common_optarg.o: common_optarg.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -policy_cache.o: policy_cache.c policy_cache.h parser.h lib.h +policy_cache.o: policy_cache.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -lib.o: lib.c lib.h parser.h +lib.o: lib.c $(HDRS) unit_test.h $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -dbus.o: dbus.cc dbus.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H) +dbus.o: dbus.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -signal.o: signal.cc signal.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H) +signal.o: signal.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -ptrace.o: ptrace.cc ptrace.h parser.h immunix.h parser_yacc.h rule.h $(APPARMOR_H) +ptrace.o: ptrace.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -network.o: network.c network.h parser.h immunix.h parser_yacc.h rule.h af_names.h $(APPARMOR_H) +network.o: network.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -default_features.o: default_features.c parser.h +default_features.o: default_features.c $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -af_rule.o: af_rule.cc af_rule.h network.h parser.h profile.h immunix.h parser_yacc.h rule.h $(APPARMOR_H) +af_rule.o: af_rule.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -af_unix.o: af_unix.cc af_unix.h network.h af_rule.h parser.h profile.h immunix.h parser_yacc.h $(APPARMOR_H) +af_unix.o: af_unix.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -profile.o: profile.cc profile.h parser.h network.h +profile.o: profile.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -rule.o: rule.cc rule.h policydb.h +rule.o: rule.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -userns.o: userns.cc userns.h parser.h parser_yacc.h rule.h $(APPARMOR_H) +userns.o: userns.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< -mqueue.o: mqueue.cc mqueue.h parser.h immunix.h profile.h parser_yacc.h rule.h $(APPARMOR_H) +mqueue.o: mqueue.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< parser_version.h: Makefile @@ -320,7 +330,7 @@ generated_af_names.h: ../common/list_af_names.sh ../common/list_af_names.sh > $@ af_names.h: generated_af_names.h base_af_names.h - cat base_af_names.h | diff -u - generated_af_names.h | grep -v '^.AF_MAX' | grep '^\+[^+]' ; \ + @cat base_af_names.h | diff -u - generated_af_names.h | grep -v '^.AF_MAX' | grep '^\+[^+]' ; \ if [ $$? -eq 1 ] ; then \ cat base_af_names.h | LC_ALL=C sed -n -e 's/[ \t]\?AF_MAX[ \t]\+[0-9]\+,//g' -e 's/[ \t]\+\?AF_\([A-Z0-9_]\+\)[ \t]\+\([0-9]\+\),/#ifndef AF_\1\n# define AF_\1 \2\n#endif\nAA_GEN_NET_ENT("\L\1", \UAF_\1)\n/pg' > $@ ; \ cat base_af_names.h | LC_ALL=C sed -n -e 's/AF_MAX[ \t]\+\([0-9]\+\),\?.*/\n#define AA_AF_MAX \1\n/p' >> $@ ; \ @@ -450,10 +460,8 @@ clean: pod_clean rm -f $(TOOLS) $(TESTS) rm -f $(LEX_C_FILES) rm -f $(YACC_C_FILES) - rm -f parser_version.h rm -f $(NAME)*.tar.gz $(NAME)*.tgz - rm -f af_names.h generated_af_names.h - rm -f cap_names.h generated_cap_names.h + rm -f $(GENERATED_HDRS) rm -rf techdoc.aux techdoc.out techdoc.log techdoc.pdf techdoc.toc techdoc.txt techdoc/ $(MAKE) -s -C $(AAREDIR) clean $(MAKE) -s -C po clean From fd9a6fe13350c05126c2f44aa1344f94dcb69c34 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 9 Jun 2021 00:56:59 -0700 Subject: [PATCH 02/25] parser: int mode to perms Move from using and int for permissions bit mask to a perms_t type. Also move any perms mask that uses the name mode to perms to avoid confusing it with other uses of mode. Signed-off-by: John Johansen --- parser/af_rule.cc | 26 +++---- parser/af_rule.h | 4 +- parser/af_unix.cc | 26 +++---- parser/af_unix.h | 4 +- parser/dbus.cc | 54 ++++++------- parser/dbus.h | 6 +- parser/immunix.h | 2 +- parser/mount.cc | 8 +- parser/mqueue.cc | 52 ++++++------- parser/mqueue.h | 6 +- parser/network.c | 4 +- parser/network.h | 2 +- parser/parser.h | 12 +-- parser/parser_alias.c | 2 +- parser/parser_merge.c | 4 +- parser/parser_misc.c | 172 ++++++++++++++++++++--------------------- parser/parser_policy.c | 28 +++---- parser/parser_regex.c | 34 ++++---- parser/parser_yacc.y | 166 +++++++++++++++++++-------------------- parser/profile.h | 5 +- parser/ptrace.cc | 30 +++---- parser/ptrace.h | 6 +- parser/signal.cc | 26 +++---- parser/signal.h | 6 +- parser/userns.cc | 20 ++--- parser/userns.h | 4 +- 26 files changed, 356 insertions(+), 353 deletions(-) diff --git a/parser/af_rule.cc b/parser/af_rule.cc index dc86c590b..3c46543ae 100644 --- a/parser/af_rule.cc +++ b/parser/af_rule.cc @@ -101,32 +101,32 @@ ostream &af_rule::dump_prefix(ostream &os) ostream &af_rule::dump_local(ostream &os) { - if (mode != AA_VALID_NET_PERMS) { + if (perms != AA_VALID_NET_PERMS) { os << " ("; - if (mode & AA_NET_SEND) + if (perms & AA_NET_SEND) os << "send "; - if (mode & AA_NET_RECEIVE) + if (perms & AA_NET_RECEIVE) os << "receive "; - if (mode & AA_NET_CREATE) + if (perms & AA_NET_CREATE) os << "create "; - if (mode & AA_NET_SHUTDOWN) + if (perms & AA_NET_SHUTDOWN) os << "shutdown "; - if (mode & AA_NET_CONNECT) + if (perms & AA_NET_CONNECT) os << "connect "; - if (mode & AA_NET_SETATTR) + if (perms & AA_NET_SETATTR) os << "setattr "; - if (mode & AA_NET_GETATTR) + if (perms & AA_NET_GETATTR) os << "getattr "; - if (mode & AA_NET_BIND) + if (perms & AA_NET_BIND) os << "bind "; - if (mode & AA_NET_ACCEPT) + if (perms & AA_NET_ACCEPT) os << "accept "; - if (mode & AA_NET_LISTEN) + if (perms & AA_NET_LISTEN) os << "listen "; - if (mode & AA_NET_SETOPT) + if (perms & AA_NET_SETOPT) os << "setopt "; - if (mode & AA_NET_GETOPT) + if (perms & AA_NET_GETOPT) os << "getopt "; os << ")"; } diff --git a/parser/af_rule.h b/parser/af_rule.h index ef4080550..400402205 100644 --- a/parser/af_rule.h +++ b/parser/af_rule.h @@ -44,13 +44,13 @@ public: int proto_n; char *label; char *peer_label; - int mode; + perms_t perms; int audit; bool deny; af_rule(const char *name): af_name(name), sock_type(NULL), sock_type_n(-1), proto(NULL), proto_n(0), label(NULL), - peer_label(NULL), mode(0), audit(0), deny(0) + peer_label(NULL), perms(0), audit(0), deny(0) {} virtual ~af_rule() diff --git a/parser/af_unix.cc b/parser/af_unix.cc index db3aa08ca..2e469e3fd 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -32,9 +32,9 @@ /* See unix(7) for autobind address definition */ #define autobind_address_pattern "\\x00[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]"; -int parse_unix_mode(const char *str_mode, int *mode, int fail) +int parse_unix_perms(const char *str_perms, perms_t *perms, int fail) { - return parse_X_mode("unix", AA_VALID_NET_PERMS, str_mode, mode, fail); + return parse_X_perms("unix", AA_VALID_NET_PERMS, str_perms, perms, fail); } @@ -104,26 +104,26 @@ unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied): if (!sock_type) yyerror("socket rule: invalid socket type '%d'", type_p); } - mode = AA_VALID_NET_PERMS; + perms = AA_VALID_NET_PERMS; audit = audit_p ? AA_VALID_NET_PERMS : 0; deny = denied; } -unix_rule::unix_rule(int mode_p, struct cond_entry *conds, +unix_rule::unix_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds): af_rule("unix"), addr(NULL), peer_addr(NULL) { move_conditionals(conds); move_peer_conditionals(peer_conds); - if (mode_p) { - mode = mode_p; - if (mode & ~AA_VALID_NET_PERMS) - yyerror("mode contains invalid permissions for unix socket rules\n"); - else if ((mode & ~AA_PEER_NET_PERMS) && has_peer_conds()) + if (perms_p) { + perms = perms_p; + if (perms & ~AA_VALID_NET_PERMS) + yyerror("perms contains invalid permissions for unix socket rules\n"); + else if ((perms & ~AA_PEER_NET_PERMS) && has_peer_conds()) yyerror("unix socket 'create', 'shutdown', 'setattr', 'getattr', 'bind', 'listen', 'setopt', and/or 'getopt' accesses cannot be used with peer socket conditionals\n"); } else { - mode = AA_VALID_NET_PERMS; + perms = AA_VALID_NET_PERMS; } free_cond_list(conds); @@ -187,7 +187,7 @@ static void writeu16(std::ostringstream &o, int v) #define CMD_OPT 4 void unix_rule::downgrade_rule(Profile &prof) { - unsigned int mask = (unsigned int) -1; + perms_t mask = (perms_t) -1; if (!prof.net.allow && !prof.alloc_net_table()) yyerror(_("Memory allocation error.")); @@ -309,7 +309,7 @@ int unix_rule::gen_policy_re(Profile &prof) std::ostringstream buffer; std::string buf; - int mask = mode; + perms_t mask = perms; /* always generate a downgraded rule. This doesn't change generated * policy size and allows the binary policy to be loaded against @@ -432,7 +432,7 @@ int unix_rule::gen_policy_re(Profile &prof) goto fail; buf = buffer.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(mode & AA_PEER_NET_PERMS), map_perms(audit), dfaflags)) + if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit), dfaflags)) goto fail; } diff --git a/parser/af_unix.h b/parser/af_unix.h index 2d2d70e1f..e36168072 100644 --- a/parser/af_unix.h +++ b/parser/af_unix.h @@ -24,7 +24,7 @@ #include "profile.h" #include "af_rule.h" -int parse_unix_mode(const char *str_mode, int *mode, int fail); +int parse_unix_perms(const char *str_mode, perms_t *perms, int fail); class unix_rule: public af_rule { void write_to_prot(std::ostringstream &buffer); @@ -38,7 +38,7 @@ public: char *peer_addr; unix_rule(unsigned int type_p, bool audit_p, bool denied); - unix_rule(int mode, struct cond_entry *conds, + unix_rule(perms_t perms, struct cond_entry *conds, struct cond_entry *peer_conds); virtual ~unix_rule() { diff --git a/parser/dbus.cc b/parser/dbus.cc index d02b90dd2..9ea17ff32 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -30,9 +30,9 @@ #include "dbus.h" -int parse_dbus_mode(const char *str_mode, int *mode, int fail) +int parse_dbus_perms(const char *str_perms, perms_t *perms, int fail) { - return parse_X_mode("DBus", AA_VALID_DBUS_PERMS, str_mode, mode, fail); + return parse_X_perms("DBus", AA_VALID_DBUS_PERMS, str_perms, perms, fail); } void dbus_rule::move_conditionals(struct cond_entry *conds) @@ -66,10 +66,10 @@ void dbus_rule::move_conditionals(struct cond_entry *conds) } } -dbus_rule::dbus_rule(int mode_p, struct cond_entry *conds, +dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds): bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL), - mode(0), audit(0), deny(0) + perms(0), audit(0), deny(0) { int name_is_subject_cond = 0, message_rule = 0, service_rule = 0; @@ -93,27 +93,27 @@ dbus_rule::dbus_rule(int mode_p, struct cond_entry *conds, if (message_rule && service_rule) yyerror("dbus rule contains message conditionals and service conditionals\n"); - /* Copy mode. If no mode was specified, assign an implied mode. */ - if (mode_p) { - mode = mode_p; - if (mode & ~AA_VALID_DBUS_PERMS) - yyerror("mode contains unknown dbus access\n"); - else if (message_rule && (mode & AA_DBUS_BIND)) + /* Copy perms. If no perms was specified, assign an implied perms. */ + if (perms_p) { + perms = perms_p; + if (perms & ~AA_VALID_DBUS_PERMS) + yyerror("perms contains unknown dbus access\n"); + else if (message_rule && (perms & AA_DBUS_BIND)) yyerror("dbus \"bind\" access cannot be used with message rule conditionals\n"); - else if (service_rule && (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE))) + else if (service_rule && (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE))) yyerror("dbus \"send\" and/or \"receive\" accesses cannot be used with service rule conditionals\n"); - else if (mode & AA_DBUS_EAVESDROP && + else if (perms & AA_DBUS_EAVESDROP && (path || interface || member || peer_label || name)) { yyerror("dbus \"eavesdrop\" access can only contain a bus conditional\n"); } } else { if (message_rule) - mode = (AA_DBUS_SEND | AA_DBUS_RECEIVE); + perms = (AA_DBUS_SEND | AA_DBUS_RECEIVE); else if (service_rule) - mode = (AA_DBUS_BIND); + perms = (AA_DBUS_BIND); else - mode = AA_VALID_DBUS_PERMS; + perms = AA_VALID_DBUS_PERMS; } free_cond_list(conds); @@ -129,19 +129,19 @@ ostream &dbus_rule::dump(ostream &os) os << "dbus ( "; - if (mode & AA_DBUS_SEND) + if (perms & AA_DBUS_SEND) os << "send "; - if (mode & AA_DBUS_RECEIVE) + if (perms & AA_DBUS_RECEIVE) os << "receive "; - if (mode & AA_DBUS_BIND) + if (perms & AA_DBUS_BIND) os << "bind "; - if (mode & AA_DBUS_EAVESDROP) + if (perms & AA_DBUS_EAVESDROP) os << "eavesdrop "; os << ")"; if (bus) os << " bus=\"" << bus << "\""; - if ((mode & AA_DBUS_BIND) && name) + if ((perms & AA_DBUS_BIND) && name) os << " name=\"" << name << "\""; if (path) os << " path=\"" << path << "\""; @@ -150,7 +150,7 @@ ostream &dbus_rule::dump(ostream &os) if (member) os << " member=\"" << member << "\""; - if (!(mode & AA_DBUS_BIND) && (peer_label || name)) { + if (!(perms & AA_DBUS_BIND) && (peer_label || name)) { os << " peer=( "; if (peer_label) os << "label=\"" << peer_label << "\" "; @@ -277,22 +277,22 @@ int dbus_rule::gen_policy_re(Profile &prof) vec[5] = default_match_pattern; } - if (mode & AA_DBUS_BIND) { - if (!prof.policy.rules->add_rule_vec(deny, mode & AA_DBUS_BIND, + if (perms & AA_DBUS_BIND) { + if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_BIND, audit & AA_DBUS_BIND, 2, vec, dfaflags, false)) goto fail; } - if (mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { + if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { if (!prof.policy.rules->add_rule_vec(deny, - mode & (AA_DBUS_SEND | AA_DBUS_RECEIVE), + perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE), audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE), 6, vec, dfaflags, false)) goto fail; } - if (mode & AA_DBUS_EAVESDROP) { + if (perms & AA_DBUS_EAVESDROP) { if (!prof.policy.rules->add_rule_vec(deny, - mode & AA_DBUS_EAVESDROP, + perms & AA_DBUS_EAVESDROP, audit & AA_DBUS_EAVESDROP, 1, vec, dfaflags, false)) goto fail; diff --git a/parser/dbus.h b/parser/dbus.h index f736cc3e4..7345e88aa 100644 --- a/parser/dbus.h +++ b/parser/dbus.h @@ -23,7 +23,7 @@ #include "rule.h" #include "profile.h" -extern int parse_dbus_mode(const char *str_mode, int *mode, int fail); +extern int parse_dbus_perms(const char *str_mode, perms_t *mode, int fail); class dbus_rule: public rule_t { void move_conditionals(struct cond_entry *conds); @@ -39,11 +39,11 @@ public: char *path; char *interface; char *member; - int mode; + perms_t perms; int audit; int deny; - dbus_rule(int mode_p, struct cond_entry *conds, + dbus_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds); virtual ~dbus_rule() { free(bus); diff --git a/parser/immunix.h b/parser/immunix.h index 9039817b9..357a2d16a 100644 --- a/parser/immunix.h +++ b/parser/immunix.h @@ -98,7 +98,7 @@ #define AA_LINK_BITS ((AA_OLD_MAY_LINK << AA_USER_SHIFT) | \ (AA_OLD_MAY_LINK << AA_OTHER_SHIFT)) -#define SHIFT_MODE(MODE, SHIFT) ((((MODE) & AA_BASE_PERMS) << (SHIFT))\ +#define SHIFT_PERMS(MODE, SHIFT) ((((MODE) & AA_BASE_PERMS) << (SHIFT))\ | ((MODE) & ~AA_FILE_PERMS)) #define SHIFT_TO_BASE(MODE, SHIFT) ((((MODE) & AA_FILE_PERMS) >> (SHIFT))\ | ((MODE) & ~AA_FILE_PERMS)) diff --git a/parser/mount.cc b/parser/mount.cc index 4716c3049..533aef202 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -1057,7 +1057,7 @@ fail: void mnt_rule::post_process(Profile &prof) { if (trans) { - unsigned int mode = 0; + perms_t perms = 0; int n = add_entry_to_x_table(&prof, trans); if (!n) { PERROR("Profile %s has too many specified profile transitions.\n", prof.name); @@ -1065,11 +1065,11 @@ void mnt_rule::post_process(Profile &prof) } if (allow & AA_USER_EXEC) - mode |= SHIFT_MODE(n << 10, AA_USER_SHIFT); + perms |= SHIFT_PERMS(n << 10, AA_USER_SHIFT); if (allow & AA_OTHER_EXEC) - mode |= SHIFT_MODE(n << 10, AA_OTHER_SHIFT); + perms |= SHIFT_PERMS(n << 10, AA_OTHER_SHIFT); allow = ((allow & ~AA_ALL_EXEC_MODIFIERS) | - (mode & AA_ALL_EXEC_MODIFIERS)); + (perms & AA_ALL_EXEC_MODIFIERS)); trans = NULL; } diff --git a/parser/mqueue.cc b/parser/mqueue.cc index 1fde03c2a..ae8efe8f1 100644 --- a/parser/mqueue.cc +++ b/parser/mqueue.cc @@ -25,9 +25,9 @@ #include #include -int parse_mqueue_mode(const char *str_mode, int *mode, int fail) +int parse_mqueue_perms(const char *str_perms, perms_t *perms, int fail) { - return parse_X_mode("mqueue", AA_VALID_MQUEUE_PERMS, str_mode, mode, fail); + return parse_X_perms("mqueue", AA_VALID_MQUEUE_PERMS, str_perms, perms, fail); } static bool is_all_digits(char *str) @@ -86,7 +86,7 @@ void mqueue_rule::move_conditionals(struct cond_entry *conds) } } -mqueue_rule::mqueue_rule(int mode_p, struct cond_entry *conds, char *qname_p): +mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p): qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit(0), deny(0) { move_conditionals(conds); @@ -94,20 +94,20 @@ mqueue_rule::mqueue_rule(int mode_p, struct cond_entry *conds, char *qname_p): if (qname) validate_qname(); - if (mode_p) { + if (perms_p) { // do we want to allow perms to imply type like we do for // qname? - if (qtype == mqueue_posix && (mode_p & ~AA_VALID_POSIX_MQ_PERMS)) { - yyerror("mode contains invalid permissions for mqueue type=posix\n"); - } else if (qtype == mqueue_sysv && (mode_p & ~AA_VALID_SYSV_MQ_PERMS)) { - yyerror("mode contains invalid permissions for mqueue type=sysv\n"); - } else if (mode_p & ~AA_VALID_MQUEUE_PERMS) { - yyerror("mode contains invalid permissions for mqueue\n"); + if (qtype == mqueue_posix && (perms_p & ~AA_VALID_POSIX_MQ_PERMS)) { + yyerror("perms contains invalid permissions for mqueue type=posix\n"); + } else if (qtype == mqueue_sysv && (perms_p & ~AA_VALID_SYSV_MQ_PERMS)) { + yyerror("perms contains invalid permissions for mqueue type=sysv\n"); + } else if (perms_p & ~AA_VALID_MQUEUE_PERMS) { + yyerror("perms contains invalid permissions for mqueue\n"); } - mode = mode_p; + perms = perms_p; } else { // default to all perms - mode = AA_VALID_MQUEUE_PERMS; + perms = AA_VALID_MQUEUE_PERMS; } qname = qname_p; @@ -129,22 +129,22 @@ ostream &mqueue_rule::dump(ostream &os) else if (qtype == mqueue_sysv) os << "type=sysv"; - if (mode != AA_VALID_MQUEUE_PERMS) { + if (perms != AA_VALID_MQUEUE_PERMS) { os << "("; - if (mode & AA_MQUEUE_WRITE) + if (perms & AA_MQUEUE_WRITE) os << "write "; - if (mode & AA_MQUEUE_READ) + if (perms & AA_MQUEUE_READ) os << "read "; - if (mode & AA_MQUEUE_OPEN) + if (perms & AA_MQUEUE_OPEN) os << "open "; - if (mode & AA_MQUEUE_CREATE) + if (perms & AA_MQUEUE_CREATE) os << "create "; - if (mode & AA_MQUEUE_DELETE) + if (perms & AA_MQUEUE_DELETE) os << "delete "; - if (mode & AA_MQUEUE_SETATTR) + if (perms & AA_MQUEUE_SETATTR) os << "setattr "; - if (mode & AA_MQUEUE_GETATTR) + if (perms & AA_MQUEUE_GETATTR) os << "getattr "; os << ")"; @@ -229,14 +229,14 @@ int mqueue_rule::gen_policy_re(Profile &prof) vec[1] = anyone_match_pattern; } - if (mode & AA_VALID_POSIX_MQ_PERMS) { + if (perms & AA_VALID_POSIX_MQ_PERMS) { /* store perms at name match so label doesn't need * to be checked */ - if (!label && !prof.policy.rules->add_rule_vec(deny, mode, audit, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, mode, audit, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit, size, vec, dfaflags, false)) goto fail; } } @@ -267,11 +267,11 @@ int mqueue_rule::gen_policy_re(Profile &prof) vec[1] = anyone_match_pattern; } - if (mode & AA_VALID_SYSV_MQ_PERMS) { - if (!label && !prof.policy.rules->add_rule_vec(deny, mode, audit, 1, vec, dfaflags, false)) + if (perms & AA_VALID_SYSV_MQ_PERMS) { + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, mode, audit, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit, size, vec, dfaflags, false)) goto fail; } } diff --git a/parser/mqueue.h b/parser/mqueue.h index fdbc0d38d..d1be8de62 100644 --- a/parser/mqueue.h +++ b/parser/mqueue.h @@ -79,7 +79,7 @@ typedef enum mqueue_type { } mqueue_type; -int parse_mqueue_mode(const char *str_mode, int *mode, int fail); +int parse_mqueue_perms(const char *str_perms, perms_t *perms, int fail); class mqueue_rule: public rule_t { void move_conditionals(struct cond_entry *conds); @@ -87,11 +87,11 @@ public: mqueue_type qtype; char *qname; char *label; - int mode; + perms_t perms; int audit; int deny; - mqueue_rule(int mode, struct cond_entry *conds, char *qname = NULL); + mqueue_rule(perms_t perms, struct cond_entry *conds, char *qname = NULL); virtual ~mqueue_rule() { free(qname); diff --git a/parser/network.c b/parser/network.c index 043aa1b9d..756bcf186 100644 --- a/parser/network.c +++ b/parser/network.c @@ -32,9 +32,9 @@ #include "network.h" -int parse_net_mode(const char *str_mode, int *mode, int fail) +int parse_net_perms(const char *str_mode, perms_t *mode, int fail) { - return parse_X_mode("net", AA_VALID_NET_PERMS, str_mode, mode, fail); + return parse_X_perms("net", AA_VALID_NET_PERMS, str_mode, mode, fail); } /* Bleah C++ doesn't have non-trivial designated initializers so we just diff --git a/parser/network.h b/parser/network.h index d51c5299e..3481cb72c 100644 --- a/parser/network.h +++ b/parser/network.h @@ -100,7 +100,7 @@ static inline uint32_t map_perms(uint32_t mask) }; -int parse_net_mode(const char *str_mode, int *mode, int fail); +int parse_net_perms(const char *str_mode, perms_t *perms, int fail); extern struct aa_network_entry *new_network_ent(unsigned int family, unsigned int type, unsigned int protocol); diff --git a/parser/parser.h b/parser/parser.h index ac8103b6c..c460c30c7 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -45,6 +45,8 @@ using namespace std; class Profile; class rule_t; +typedef uint32_t perms_t; + #define MODULE_NAME "apparmor" /* Global variable to pass token to lexer. Will be replaced by parameter @@ -127,8 +129,8 @@ struct cod_entry { char *nt_name; Profile *prof; /* Special profile defined * just for this executable */ - int mode; /* mode is 'or' of AA_* bits */ - int audit; /* audit flags for mode */ + perms_t perms; /* perms is 'or' of AA_* bits */ + int audit; /* audit flags for perms */ int deny; /* TRUE or FALSE */ int alias_ignore; /* ignore for alias processing */ @@ -449,12 +451,12 @@ extern char *processunquoted(const char *string, int len); extern int get_keyword_token(const char *keyword); extern int get_rlimit(const char *name); extern char *process_var(const char *var); -extern int parse_mode(const char *mode); -extern int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int fail); +extern perms_t parse_perms(const char *permstr); +extern int parse_X_perms(const char *X, int valid, const char *str_perms, perms_t *perms, int fail); bool label_contains_ns(const char *label); bool parse_label(bool *_stack, char **_ns, char **_name, const char *label, bool yyerr); -extern struct cod_entry *new_entry(char *id, int mode, char *link_id); +extern struct cod_entry *new_entry(char *id, perms_t perms, char *link_id); /* returns -1 if value != true or false, otherwise 0 == false, 1 == true */ extern int str_to_boolean(const char* str); diff --git a/parser/parser_alias.c b/parser/parser_alias.c index b96d18f87..6dacb076e 100644 --- a/parser/parser_alias.c +++ b/parser/parser_alias.c @@ -120,7 +120,7 @@ static void process_entries(const void *nodep, VISIT value, int level unused) len = strlen((*t)->from); list_for_each(target_list, entry) { - if ((entry->mode & AA_SHARED_PERMS) || entry->alias_ignore) + if ((entry->perms & AA_SHARED_PERMS) || entry->alias_ignore) continue; if (entry->name && strncmp((*t)->from, entry->name, len) == 0) { char *n = do_alias(*t, entry->name); diff --git a/parser/parser_merge.c b/parser/parser_merge.c index 489821841..edce208db 100644 --- a/parser/parser_merge.c +++ b/parser/parser_merge.c @@ -89,12 +89,12 @@ static int process_file_entries(Profile *prof) } /* check for merged x consistency */ - if (!is_merged_x_consistent(cur->mode, next->mode)) { + if (!is_merged_x_consistent(cur->perms, next->perms)) { PERROR(_("profile %s: has merged rule %s with conflicting x modifiers\n"), prof->name, cur->name); return -1; } - cur->mode |= next->mode; + cur->perms |= next->perms; cur->audit |= next->audit; cur->next = next->next; diff --git a/parser/parser_misc.c b/parser/parser_misc.c index 36d847ca2..7c38a9c3d 100644 --- a/parser/parser_misc.c +++ b/parser/parser_misc.c @@ -540,139 +540,139 @@ void warn_uppercase(void) } } -static int parse_sub_mode(const char *str_mode, const char *mode_desc unused) +static perms_t parse_sub_perms(const char *str_perms, const char *perms_desc unused) { -#define IS_DIFF_QUAL(mode, q) (((mode) & AA_MAY_EXEC) && (((mode) & AA_EXEC_TYPE) != ((q) & AA_EXEC_TYPE))) +#define IS_DIFF_QUAL(perms, q) (((perms) & AA_MAY_EXEC) && (((perms) & AA_EXEC_TYPE) != ((q) & AA_EXEC_TYPE))) - int mode = 0; + perms_t perms = 0; const char *p; - PDEBUG("Parsing mode: %s\n", str_mode); + PDEBUG("Parsing perms: %s\n", str_perms); - if (!str_mode) + if (!str_perms) return 0; - p = str_mode; + p = str_perms; while (*p) { char thisc = *p; char next = *(p + 1); char lower; - int tmode = 0; + perms_t tperms = 0; reeval: switch (thisc) { case COD_READ_CHAR: if (read_implies_exec) { - PDEBUG("Parsing mode: found %s READ imply X\n", mode_desc); - mode |= AA_MAY_READ | AA_OLD_EXEC_MMAP; + PDEBUG("Parsing perms: found %s READ imply X\n", perms_desc); + perms |= AA_MAY_READ | AA_OLD_EXEC_MMAP; } else { - PDEBUG("Parsing mode: found %s READ\n", mode_desc); - mode |= AA_MAY_READ; + PDEBUG("Parsing perms: found %s READ\n", perms_desc); + perms |= AA_MAY_READ; } break; case COD_WRITE_CHAR: - PDEBUG("Parsing mode: found %s WRITE\n", mode_desc); - if ((mode & AA_MAY_APPEND) && !(mode & AA_MAY_WRITE)) + PDEBUG("Parsing perms: found %s WRITE\n", perms_desc); + if ((perms & AA_MAY_APPEND) && !(perms & AA_MAY_WRITE)) yyerror(_("Conflict 'a' and 'w' perms are mutually exclusive.")); - mode |= AA_MAY_WRITE | AA_MAY_APPEND; + perms |= AA_MAY_WRITE | AA_MAY_APPEND; break; case COD_APPEND_CHAR: - PDEBUG("Parsing mode: found %s APPEND\n", mode_desc); - if (mode & AA_MAY_WRITE) + PDEBUG("Parsing perms: found %s APPEND\n", perms_desc); + if (perms & AA_MAY_WRITE) yyerror(_("Conflict 'a' and 'w' perms are mutually exclusive.")); - mode |= AA_MAY_APPEND; + perms |= AA_MAY_APPEND; break; case COD_LINK_CHAR: - PDEBUG("Parsing mode: found %s LINK\n", mode_desc); - mode |= AA_OLD_MAY_LINK; + PDEBUG("Parsing perms: found %s LINK\n", perms_desc); + perms |= AA_OLD_MAY_LINK; break; case COD_LOCK_CHAR: - PDEBUG("Parsing mode: found %s LOCK\n", mode_desc); - mode |= AA_OLD_MAY_LOCK; + PDEBUG("Parsing perms: found %s LOCK\n", perms_desc); + perms |= AA_OLD_MAY_LOCK; break; case COD_INHERIT_CHAR: - PDEBUG("Parsing mode: found INHERIT\n"); - if (mode & AA_EXEC_MODIFIERS) { + PDEBUG("Parsing perms: found INHERIT\n"); + if (perms & AA_EXEC_MODIFIERS) { yyerror(_("Exec qualifier 'i' invalid, conflicting qualifier already specified")); } else { if (next != tolower(next)) warn_uppercase(); - mode |= (AA_EXEC_INHERIT | AA_MAY_EXEC); + perms |= (AA_EXEC_INHERIT | AA_MAY_EXEC); p++; /* skip 'x' */ } break; case COD_UNSAFE_UNCONFINED_CHAR: - tmode = AA_EXEC_UNSAFE; + tperms = AA_EXEC_UNSAFE; pwarn(WARN_DANGEROUS, _("Unconfined exec qualifier (%c%c) allows some dangerous environment variables " "to be passed to the unconfined process; 'man 5 apparmor.d' for details.\n"), COD_UNSAFE_UNCONFINED_CHAR, COD_EXEC_CHAR); /* fall through */ case COD_UNCONFINED_CHAR: - tmode |= AA_EXEC_UNCONFINED | AA_MAY_EXEC; - PDEBUG("Parsing mode: found UNCONFINED\n"); - if (IS_DIFF_QUAL(mode, tmode)) { + tperms |= AA_EXEC_UNCONFINED | AA_MAY_EXEC; + PDEBUG("Parsing perms: found UNCONFINED\n"); + if (IS_DIFF_QUAL(perms, tperms)) { yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"), thisc); } else { if (next != tolower(next)) warn_uppercase(); - mode |= tmode; + perms |= tperms; p++; /* skip 'x' */ } - tmode = 0; + tperms = 0; break; case COD_UNSAFE_PROFILE_CHAR: case COD_UNSAFE_LOCAL_CHAR: - tmode = AA_EXEC_UNSAFE; + tperms = AA_EXEC_UNSAFE; /* fall through */ case COD_PROFILE_CHAR: case COD_LOCAL_CHAR: if (tolower(thisc) == COD_UNSAFE_PROFILE_CHAR) - tmode |= AA_EXEC_PROFILE | AA_MAY_EXEC; + tperms |= AA_EXEC_PROFILE | AA_MAY_EXEC; else { - tmode |= AA_EXEC_LOCAL | AA_MAY_EXEC; + tperms |= AA_EXEC_LOCAL | AA_MAY_EXEC; } - PDEBUG("Parsing mode: found PROFILE\n"); + PDEBUG("Parsing perms: found PROFILE\n"); if (tolower(next) == COD_INHERIT_CHAR) { - tmode |= AA_EXEC_INHERIT; - if (IS_DIFF_QUAL(mode, tmode)) { + tperms |= AA_EXEC_INHERIT; + if (IS_DIFF_QUAL(perms, tperms)) { yyerror(_("Exec qualifier '%c%c' invalid, conflicting qualifier already specified"), thisc, next); } else { - mode |= tmode; + perms |= tperms; p += 2; /* skip x */ } } else if (tolower(next) == COD_UNSAFE_UNCONFINED_CHAR) { - tmode |= AA_EXEC_PUX; - if (IS_DIFF_QUAL(mode, tmode)) { + tperms |= AA_EXEC_PUX; + if (IS_DIFF_QUAL(perms, tperms)) { yyerror(_("Exec qualifier '%c%c' invalid, conflicting qualifier already specified"), thisc, next); } else { - mode |= tmode; + perms |= tperms; p += 2; /* skip x */ } - } else if (IS_DIFF_QUAL(mode, tmode)) { + } else if (IS_DIFF_QUAL(perms, tperms)) { yyerror(_("Exec qualifier '%c' invalid, conflicting qualifier already specified"), thisc); } else { if (next != tolower(next)) warn_uppercase(); - mode |= tmode; + perms |= tperms; p++; /* skip 'x' */ } - tmode = 0; + tperms = 0; break; case COD_MMAP_CHAR: - PDEBUG("Parsing mode: found %s MMAP\n", mode_desc); - mode |= AA_OLD_EXEC_MMAP; + PDEBUG("Parsing perms: found %s MMAP\n", perms_desc); + perms |= AA_OLD_EXEC_MMAP; break; case COD_EXEC_CHAR: @@ -680,7 +680,7 @@ reeval: * but invalid for regular x transitions * sort it out later. */ - mode |= AA_MAY_EXEC; + perms |= AA_MAY_EXEC; break; /* error cases */ @@ -695,13 +695,13 @@ reeval: case COD_INHERIT_CHAR: case COD_MMAP_CHAR: case COD_EXEC_CHAR: - PDEBUG("Parsing mode: found invalid upper case char %c\n", thisc); + PDEBUG("Parsing perms: found invalid upper case char %c\n", thisc); warn_uppercase(); thisc = lower; goto reeval; break; default: - yyerror(_("Internal: unexpected mode character '%c' in input"), + yyerror(_("Internal: unexpected perms character '%c' in input"), thisc); break; } @@ -711,33 +711,33 @@ reeval: p++; } - PDEBUG("Parsed mode: %s 0x%x\n", str_mode, mode); + PDEBUG("Parsed perms: %s 0x%x\n", str_perms, perms); - return mode; + return perms; } -int parse_mode(const char *str_mode) +perms_t parse_perms(const char *str_perms) { - int tmp, mode = 0; - tmp = parse_sub_mode(str_mode, ""); - mode = SHIFT_MODE(tmp, AA_USER_SHIFT); - mode |= SHIFT_MODE(tmp, AA_OTHER_SHIFT); - if (mode & ~AA_VALID_PERMS) - yyerror(_("Internal error generated invalid perm 0x%llx\n"), mode); - return mode; + perms_t tmp, perms = 0; + tmp = parse_sub_perms(str_perms, ""); + perms = SHIFT_PERMS(tmp, AA_USER_SHIFT); + perms |= SHIFT_PERMS(tmp, AA_OTHER_SHIFT); + if (perms & ~AA_VALID_PERMS) + yyerror(_("Internal error generated invalid perm 0x%llx\n"), perms); + return perms; } -static int parse_X_sub_mode(const char *X, const char *str_mode, int *result, int fail, const char *mode_desc unused) +static int parse_X_sub_perms(const char *X, const char *str_perms, perms_t *result, int fail, const char *perms_desc unused) { - int mode = 0; + perms_t perms = 0; const char *p; - PDEBUG("Parsing %s mode: %s\n", X, str_mode); + PDEBUG("Parsing %s perms: %s\n", X, str_perms); - if (!str_mode) + if (!str_perms) return 0; - p = str_mode; + p = str_perms; while (*p) { char current = *p; char lower; @@ -745,14 +745,14 @@ static int parse_X_sub_mode(const char *X, const char *str_mode, int *result, in reeval: switch (current) { case COD_READ_CHAR: - PDEBUG("Parsing %s mode: found %s READ\n", X, mode_desc); - mode |= AA_DBUS_RECEIVE; + PDEBUG("Parsing %s perms: found %s READ\n", X, perms_desc); + perms |= AA_DBUS_RECEIVE; break; case COD_WRITE_CHAR: - PDEBUG("Parsing %s mode: found %s WRITE\n", X, - mode_desc); - mode |= AA_DBUS_SEND; + PDEBUG("Parsing %s perms: found %s WRITE\n", X, + perms_desc); + perms |= AA_DBUS_SEND; break; /* error cases */ @@ -762,7 +762,7 @@ reeval: switch (lower) { case COD_READ_CHAR: case COD_WRITE_CHAR: - PDEBUG("Parsing %s mode: found invalid upper case char %c\n", + PDEBUG("Parsing %s perms: found invalid upper case char %c\n", X, current); warn_uppercase(); current = lower; @@ -770,7 +770,7 @@ reeval: break; default: if (fail) - yyerror(_("Internal: unexpected %s mode character '%c' in input"), + yyerror(_("Internal: unexpected %s perms character '%c' in input"), X, current); else return 0; @@ -781,21 +781,21 @@ reeval: p++; } - PDEBUG("Parsed %s mode: %s 0x%x\n", X, str_mode, mode); + PDEBUG("Parsed %s perms: %s 0x%x\n", X, str_perms, perms); - *result = mode; + *result = perms; return 1; } -int parse_X_mode(const char *X, int valid, const char *str_mode, int *mode, int fail) +int parse_X_perms(const char *X, int valid, const char *str_perms, perms_t *perms, int fail) { - *mode = 0; - if (!parse_X_sub_mode(X, str_mode, mode, fail, "")) + *perms = 0; + if (!parse_X_sub_perms(X, str_perms, perms, fail, "")) return 0; - if (*mode & ~valid) { + if (*perms & ~valid) { if (fail) yyerror(_("Internal error generated invalid %s perm 0x%x\n"), - X, mode); + X, perms); else return 0; } @@ -950,7 +950,7 @@ alloc_fail: return false; } -struct cod_entry *new_entry(char *id, int mode, char *link_id) +struct cod_entry *new_entry(char *id, perms_t perms, char *link_id) { struct cod_entry *entry = NULL; @@ -960,7 +960,7 @@ struct cod_entry *new_entry(char *id, int mode, char *link_id) entry->name = id; entry->link_name = link_id; - entry->mode = mode; + entry->perms = perms; entry->audit = 0; entry->deny = FALSE; @@ -984,7 +984,7 @@ struct cod_entry *copy_cod_entry(struct cod_entry *orig) DUP_STRING(orig, entry, name, err); DUP_STRING(orig, entry, link_name, err); DUP_STRING(orig, entry, nt_name, err); - entry->mode = orig->mode; + entry->perms = orig->perms; entry->audit = orig->audit; entry->deny = orig->deny; @@ -1043,20 +1043,20 @@ void debug_cod_entries(struct cod_entry *list) printf("--- Entries ---\n"); list_for_each(list, item) { - printf("Mode:\t"); - if (HAS_CHANGE_PROFILE(item->mode)) + printf("Perms:\t"); + if (HAS_CHANGE_PROFILE(item->perms)) printf(" change_profile"); - if (HAS_EXEC_UNSAFE(item->mode)) + if (HAS_EXEC_UNSAFE(item->perms)) printf(" unsafe"); - debug_base_perm_mask(SHIFT_TO_BASE(item->mode, AA_USER_SHIFT)); + debug_base_perm_mask(SHIFT_TO_BASE(item->perms, AA_USER_SHIFT)); printf(":"); - debug_base_perm_mask(SHIFT_TO_BASE(item->mode, AA_OTHER_SHIFT)); + debug_base_perm_mask(SHIFT_TO_BASE(item->perms, AA_OTHER_SHIFT)); if (item->name) printf("\tName:\t(%s)\n", item->name); else printf("\tName:\tNULL\n"); - if (AA_LINK_BITS & item->mode) + if (AA_LINK_BITS & item->perms) printf("\tlink:\t(%s)\n", item->link_name ? item->link_name : "/**"); } diff --git a/parser/parser_policy.c b/parser/parser_policy.c index 2f66ab26f..cbf17677c 100644 --- a/parser/parser_policy.c +++ b/parser/parser_policy.c @@ -101,10 +101,10 @@ static int add_named_transition(Profile *prof, struct cod_entry *entry) free(entry->nt_name); entry->nt_name = NULL; return AA_EXEC_LOCAL >> 10; - } else if (((entry->mode & AA_USER_EXEC_MODIFIERS) == - SHIFT_MODE(AA_EXEC_LOCAL, AA_USER_SHIFT)) || - ((entry->mode & AA_OTHER_EXEC_MODIFIERS) == - SHIFT_MODE(AA_EXEC_LOCAL, AA_OTHER_SHIFT))) { + } else if (((entry->perms & AA_USER_EXEC_MODIFIERS) == + SHIFT_PERMS(AA_EXEC_LOCAL, AA_USER_SHIFT)) || + ((entry->perms & AA_OTHER_EXEC_MODIFIERS) == + SHIFT_PERMS(AA_EXEC_LOCAL, AA_OTHER_SHIFT))) { if (strcmp(entry->nt_name, entry->name) == 0) { free(entry->nt_name); entry->nt_name = NULL; @@ -199,31 +199,31 @@ static bool add_proc_access(Profile *prof, const char *rule) void post_process_file_entries(Profile *prof) { struct cod_entry *entry; - int cp_mode = 0; + perms_t cp_perms = 0; list_for_each(prof->entries, entry) { if (entry->nt_name) { - int mode = 0; + perms_t perms = 0; int n = add_named_transition(prof, entry); if (!n) { PERROR("Profile %s has too many specified profile transitions.\n", prof->name); exit(1); } - if (entry->mode & AA_USER_EXEC) - mode |= SHIFT_MODE(n << 10, AA_USER_SHIFT); - if (entry->mode & AA_OTHER_EXEC) - mode |= SHIFT_MODE(n << 10, AA_OTHER_SHIFT); - entry->mode = ((entry->mode & ~AA_ALL_EXEC_MODIFIERS) | - (mode & AA_ALL_EXEC_MODIFIERS)); + if (entry->perms & AA_USER_EXEC) + perms |= SHIFT_PERMS(n << 10, AA_USER_SHIFT); + if (entry->perms & AA_OTHER_EXEC) + perms |= SHIFT_PERMS(n << 10, AA_OTHER_SHIFT); + entry->perms = ((entry->perms & ~AA_ALL_EXEC_MODIFIERS) | + (perms & AA_ALL_EXEC_MODIFIERS)); } /* FIXME: currently change_profile also implies onexec */ - cp_mode |= entry->mode & (AA_CHANGE_PROFILE); + cp_perms |= entry->perms & (AA_CHANGE_PROFILE); } /* if there are change_profile rules, this implies that we need * access to some /proc/ interfaces */ - if (cp_mode & AA_CHANGE_PROFILE) { + if (cp_perms & AA_CHANGE_PROFILE) { if (!add_proc_access(prof, CHANGEPROFILE_PATH)) exit(1); } diff --git a/parser/parser_regex.c b/parser/parser_regex.c index 8cd8f15d3..517b7e472 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -575,7 +575,7 @@ build: static int warn_change_profile = 1; -static bool is_change_profile_mode(int mode) +static bool is_change_profile_perms(perms_t perms) { /** * A change_profile entry will have the AA_CHANGE_PROFILE bit set. @@ -583,13 +583,13 @@ static bool is_change_profile_mode(int mode) * set by the frontend parser. That means that it is incorrect to * identify change_profile modes using a test like this: * - * (mode & ~AA_CHANGE_PROFILE) + * (perms & ~AA_CHANGE_PROFILE) * * The above test would incorrectly return true on a * change_profile mode that has the * (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE) bits set. */ - return mode & AA_CHANGE_PROFILE; + return perms & AA_CHANGE_PROFILE; } static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) @@ -602,7 +602,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) return TRUE; - if (!is_change_profile_mode(entry->mode)) + if (!is_change_profile_perms(entry->perms)) filter_slashes(entry->name); ptype = convert_aaregex_to_pcre(entry->name, 0, glob_default, tbuf, &pos); if (ptype == ePatternInvalid) @@ -613,10 +613,10 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) /* ix implies m but the apparmor module does not add m bit to * dfa states like it does for pcre */ - if ((entry->mode >> AA_OTHER_SHIFT) & AA_EXEC_INHERIT) - entry->mode |= AA_OLD_EXEC_MMAP << AA_OTHER_SHIFT; - if ((entry->mode >> AA_USER_SHIFT) & AA_EXEC_INHERIT) - entry->mode |= AA_OLD_EXEC_MMAP << AA_USER_SHIFT; + if ((entry->perms >> AA_OTHER_SHIFT) & AA_EXEC_INHERIT) + entry->perms |= AA_OLD_EXEC_MMAP << AA_OTHER_SHIFT; + if ((entry->perms >> AA_USER_SHIFT) & AA_EXEC_INHERIT) + entry->perms |= AA_OLD_EXEC_MMAP << AA_USER_SHIFT; /* the link bit on the first pair entry should not get masked * out by a deny rule, as both pieces of the link pair must @@ -628,23 +628,23 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) * TODO: split link and change_profile entries earlier */ if (entry->deny) { - if ((entry->mode & ~AA_LINK_BITS) && - !is_change_profile_mode(entry->mode) && + if ((entry->perms & ~AA_LINK_BITS) && + !is_change_profile_perms(entry->perms) && !dfarules->add_rule(tbuf.c_str(), entry->deny, - entry->mode & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), + entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), entry->audit & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), dfaflags)) return FALSE; - } else if (!is_change_profile_mode(entry->mode)) { - if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->mode, + } else if (!is_change_profile_perms(entry->perms)) { + if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms, entry->audit, dfaflags)) return FALSE; } - if (entry->mode & (AA_LINK_BITS)) { + if (entry->perms & (AA_LINK_BITS)) { /* add the pair rule */ std::string lbuf; - int perms = AA_LINK_BITS & entry->mode; + int perms = AA_LINK_BITS & entry->perms; const char *vec[2]; int pos; vec[0] = tbuf.c_str(); @@ -663,7 +663,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit & AA_LINK_BITS, 2, vec, dfaflags, false)) return FALSE; } - if (is_change_profile_mode(entry->mode)) { + if (is_change_profile_perms(entry->perms)) { const char *vec[3]; std::string lbuf, xbuf; autofree char *ns = NULL; @@ -725,7 +725,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) * pick up any exec bits, from the frontend parser, related to * unsafe exec transitions */ - onexec_perms |= (entry->mode & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE)); + onexec_perms |= (entry->perms & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE)); if (!dfarules->add_rule_vec(entry->deny, onexec_perms, 0, index, vec, dfaflags, false)) return FALSE; diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index f8a6baa59..c325b0249 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -63,10 +63,10 @@ int parser_token = 0; -struct cod_entry *do_file_rule(char *id, int mode, char *link_id, char *nt); +struct cod_entry *do_file_rule(char *id, perms_t perms, char *link_id, char *nt); mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src, struct cond_entry *dst_conds, char *dst, - int mode); + perms_t perms); mnt_rule *do_pivot_rule(struct cond_entry *old, char *root, char *transition); static void abi_features(char *filename, bool search); @@ -202,7 +202,7 @@ void add_local_entry(Profile *prof); mqueue_rule *mqueue_entry; flagvals flags; - int fmode; + perms_t fperms; uint64_t cap; unsigned int allowed_protocol; char *set_var; @@ -220,7 +220,7 @@ void add_local_entry(Profile *prof); %type TOK_CONDID %type TOK_CONDLISTID %type TOK_MODE -%type file_mode +%type file_perms %type profile_base %type profile %type rules @@ -259,33 +259,33 @@ void add_local_entry(Profile *prof); %type opt_perm_mode %type opt_id %type opt_prefix -%type dbus_perm -%type dbus_perms -%type opt_dbus_perm +%type dbus_perm +%type dbus_perms +%type opt_dbus_perm %type dbus_rule -%type signal_perm -%type signal_perms -%type opt_signal_perm +%type signal_perm +%type signal_perms +%type opt_signal_perm %type signal_rule -%type ptrace_perm -%type ptrace_perms -%type opt_ptrace_perm +%type ptrace_perm +%type ptrace_perms +%type opt_ptrace_perm %type ptrace_rule -%type net_perm -%type net_perms -%type opt_net_perm +%type net_perm +%type net_perms +%type opt_net_perm %type unix_rule %type opt_target %type opt_named_transition %type opt_exec_mode %type opt_file -%type userns_perm -%type userns_perms -%type opt_userns_perm +%type userns_perm +%type userns_perms +%type opt_userns_perm %type userns_rule -%type mqueue_perm -%type mqueue_perms -%type opt_mqueue_perm +%type mqueue_perm +%type mqueue_perms +%type opt_mqueue_perm %type mqueue_rule %% @@ -686,21 +686,21 @@ rules: rules opt_prefix rule if (!$3) yyerror(_("Assert: `rule' returned NULL.")); $3->deny = $2.deny; - if (($2.deny && ($3->mode & AA_EXEC_BITS) && - ($3->mode & ALL_AA_EXEC_TYPE))) - yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); - else if (!$2.deny && ($3->mode & AA_EXEC_BITS) && - !($3->mode & ALL_AA_EXEC_TYPE) && + if (($2.deny && ($3->perms & AA_EXEC_BITS) && + ($3->perms & ALL_AA_EXEC_TYPE))) + yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); + else if (!$2.deny && ($3->perms & AA_EXEC_BITS) && + !($3->perms & ALL_AA_EXEC_TYPE) && !($3->nt_name)) - yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'")); + yyerror(_("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'")); if ($2.owner == 1) - $3->mode &= (AA_USER_PERMS | AA_SHARED_PERMS); + $3->perms &= (AA_USER_PERMS | AA_SHARED_PERMS); else if ($2.owner == 2) - $3->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS); + $3->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); /* only set audit ctl quieting if the rule is not audited */ if (($2.deny && !$2.audit) || (!$2.deny && $2.audit)) - $3->audit = $3->mode & ~ALL_AA_EXEC_TYPE; + $3->audit = $3->perms & ~ALL_AA_EXEC_TYPE; add_entry_to_policy($1, $3); $$ = $1; @@ -717,23 +717,23 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE $2.deny ? "deny " : "", $2.owner ? "owner " : ""); list_for_each_safe($4->entries, entry, tmp) { entry->next = NULL; - if (entry->mode & AA_EXEC_BITS) { + if (entry->perms & AA_EXEC_BITS) { if (entry->deny && - (entry->mode & ALL_AA_EXEC_TYPE)) - yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); + (entry->perms & ALL_AA_EXEC_TYPE)) + yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); else if (!entry->deny && - !(entry->mode & ALL_AA_EXEC_TYPE)) - yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'")); + !(entry->perms & ALL_AA_EXEC_TYPE)) + yyerror(_("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'")); } if ($2.owner == 1) - entry->mode &= (AA_USER_PERMS | AA_SHARED_PERMS); + entry->perms &= (AA_USER_PERMS | AA_SHARED_PERMS); else if ($2.owner == 2) - entry->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS); + entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); if ($2.audit && !entry->deny) - entry->audit = entry->mode & ~ALL_AA_EXEC_TYPE; + entry->audit = entry->perms & ~ALL_AA_EXEC_TYPE; else if (!$2.audit && entry->deny) - entry->audit = entry->mode & ~ALL_AA_EXEC_TYPE; + entry->audit = entry->perms & ~ALL_AA_EXEC_TYPE; add_entry_to_policy($1, entry); } $4->entries = NULL; @@ -817,9 +817,9 @@ rules: rules opt_prefix dbus_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->mode; + $3->audit = $3->perms; } else if ($2.audit) { - $3->audit = $3->mode; + $3->audit = $3->perms; } $1->rule_ents.push_back($3); $$ = $1; @@ -833,9 +833,9 @@ rules: rules opt_prefix signal_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->mode; + $3->audit = $3->perms; } else if ($2.audit) { - $3->audit = $3->mode; + $3->audit = $3->perms; } $1->rule_ents.push_back($3); $$ = $1; @@ -849,9 +849,9 @@ rules: rules opt_prefix ptrace_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->mode; + $3->audit = $3->perms; } else if ($2.audit) { - $3->audit = $3->mode; + $3->audit = $3->perms; } $1->rule_ents.push_back($3); $$ = $1; @@ -865,9 +865,9 @@ rules: rules opt_prefix unix_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->mode; + $3->audit = $3->perms; } else if ($2.audit) { - $3->audit = $3->mode; + $3->audit = $3->perms; } $1->rule_ents.push_back($3); $$ = $1; @@ -881,9 +881,9 @@ rules: rules opt_prefix userns_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->mode; + $3->audit = $3->perms; } else if ($2.audit) { - $3->audit = $3->mode; + $3->audit = $3->perms; } $1->rule_ents.push_back($3); $$ = $1; @@ -901,9 +901,9 @@ rules: rules opt_prefix change_profile $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->mode; + $3->audit = $3->perms; } else if ($2.audit) { - $3->audit = $3->mode; + $3->audit = $3->perms; } add_entry_to_policy($1, $3); $$ = $1; @@ -936,9 +936,9 @@ rules: rules opt_prefix mqueue_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->mode; + $3->audit = $3->perms; } else if ($2.audit) { - $3->audit = $3->mode; + $3->audit = $3->perms; } $1->rule_ents.push_back($3); $$ = $1; @@ -1183,12 +1183,12 @@ opt_exec_mode: { /* nothing */ $$ = EXEC_MODE_EMPTY; } opt_file: { /* nothing */ $$ = 0; } | TOK_FILE { $$ = 1; } -frule: id_or_var file_mode opt_named_transition TOK_END_OF_RULE +frule: id_or_var file_perms opt_named_transition TOK_END_OF_RULE { $$ = do_file_rule($1, $2, NULL, $3); }; -frule: file_mode opt_subset_flag id_or_var opt_named_transition TOK_END_OF_RULE +frule: file_perms opt_subset_flag id_or_var opt_named_transition TOK_END_OF_RULE { if ($2 && ($1 & ~AA_LINK_BITS)) yyerror(_("subset can only be used with link rules.")); @@ -1223,19 +1223,19 @@ file_rule: TOK_FILE TOK_END_OF_RULE file_rule_tail: opt_exec_mode frule { if ($1 != EXEC_MODE_EMPTY) { - if (!($2->mode & AA_EXEC_BITS)) + if (!($2->perms & AA_EXEC_BITS)) yyerror(_("unsafe rule missing exec permissions")); if ($1 == EXEC_MODE_UNSAFE) { - $2->mode |= (($2->mode & AA_EXEC_BITS) << 8) & + $2->perms |= (($2->perms & AA_EXEC_BITS) << 8) & ALL_AA_EXEC_UNSAFE; } else if ($1 == EXEC_MODE_SAFE) - $2->mode &= ~ALL_AA_EXEC_UNSAFE; + $2->perms &= ~ALL_AA_EXEC_UNSAFE; } $$ = $2; }; -file_rule_tail: opt_exec_mode id_or_var file_mode id_or_var +file_rule_tail: opt_exec_mode id_or_var file_perms id_or_var { /* Oopsie, we appear to be missing an EOL marker. If we * were *smart*, we could work around it. Since we're @@ -1387,7 +1387,7 @@ dbus_perm: TOK_VALUE else if (strcmp($1, "eavesdrop") == 0) $$ = AA_DBUS_EAVESDROP; else if ($1) { - parse_dbus_mode($1, &$$, 1); + parse_dbus_perms($1, &$$, 1); } else $$ = 0; @@ -1402,7 +1402,7 @@ dbus_perm: TOK_VALUE | TOK_EAVESDROP { $$ = AA_DBUS_EAVESDROP; } | TOK_MODE { - parse_dbus_mode($1, &$$, 1); + parse_dbus_perms($1, &$$, 1); free($1); } @@ -1457,7 +1457,7 @@ net_perm: TOK_VALUE else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0) $$ = AA_NET_RECEIVE; else if ($1) { - parse_net_mode($1, &$$, 1); + parse_net_perms($1, &$$, 1); } else $$ = 0; @@ -1480,7 +1480,7 @@ net_perm: TOK_VALUE | TOK_WRITE { $$ = AA_NET_SEND; } | TOK_MODE { - parse_unix_mode($1, &$$, 1); + parse_unix_perms($1, &$$, 1); free($1); } @@ -1515,7 +1515,7 @@ signal_perm: TOK_VALUE else if (strcmp($1, "receive") == 0 || strcmp($1, "read") == 0) $$ = AA_MAY_RECEIVE; else if ($1) { - parse_signal_mode($1, &$$, 1); + parse_signal_perms($1, &$$, 1); } else $$ = 0; @@ -1528,7 +1528,7 @@ signal_perm: TOK_VALUE | TOK_WRITE { $$ = AA_MAY_SEND; } | TOK_MODE { - parse_signal_mode($1, &$$, 1); + parse_signal_perms($1, &$$, 1); free($1); } @@ -1557,7 +1557,7 @@ ptrace_perm: TOK_VALUE else if (strcmp($1, "readby") == 0) $$ = AA_MAY_READBY; else if ($1) - parse_ptrace_mode($1, &$$, 1); + parse_ptrace_perms($1, &$$, 1); else $$ = 0; @@ -1571,7 +1571,7 @@ ptrace_perm: TOK_VALUE | TOK_READBY { $$ = AA_MAY_READBY; } | TOK_MODE { - parse_ptrace_mode($1, &$$, 1); + parse_ptrace_perms($1, &$$, 1); free($1); } @@ -1632,7 +1632,7 @@ mqueue_perm: TOK_VALUE else if (strcmp($1, "read") == 0) $$ = AA_MQUEUE_READ; else if ($1) { - parse_mqueue_mode($1, &$$, 1); + parse_mqueue_perms($1, &$$, 1); } else $$ = 0; @@ -1648,7 +1648,7 @@ mqueue_perm: TOK_VALUE | TOK_READ { $$ = AA_MQUEUE_READ; } | TOK_MODE { - parse_mqueue_mode($1, &$$, 1); + parse_mqueue_perms($1, &$$, 1); free($1); } @@ -1674,18 +1674,18 @@ mqueue_rule: TOK_MQUEUE opt_mqueue_perm opt_conds TOK_END_OF_RULE hat_start: TOK_CARET {} | TOK_HAT {} -file_mode: TOK_MODE +file_perms: TOK_MODE { /* A single TOK_MODE maps to the same permission in all * of user::other */ - $$ = parse_mode($1); + $$ = parse_perms($1); free($1); } change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK_END_OF_RULE { struct cod_entry *entry; - int mode = AA_CHANGE_PROFILE; + perms_t perms = AA_CHANGE_PROFILE; int exec_mode = $2; char *exec = $3; char *target = $4; @@ -1694,9 +1694,9 @@ change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK /* exec bits required to trigger rule conflict if * for overlapping safe and unsafe exec rules */ - mode |= AA_EXEC_BITS; + perms |= AA_EXEC_BITS; if (exec_mode == EXEC_MODE_UNSAFE) - mode |= ALL_AA_EXEC_UNSAFE; + perms |= ALL_AA_EXEC_UNSAFE; else if (exec_mode == EXEC_MODE_SAFE && !features_supports_stacking) { pwarn(WARN_RULE_DOWNGRADED, "downgrading change_profile safe rule to unsafe due to lack of necessary kernel support\n"); @@ -1720,7 +1720,7 @@ change_profile: TOK_CHANGE_PROFILE opt_exec_mode opt_id opt_named_transition TOK yyerror(_("Memory allocation error.")); } - entry = new_entry(target, mode, exec); + entry = new_entry(target, perms, exec); if (!entry) yyerror(_("Memory allocation error.")); @@ -1793,11 +1793,11 @@ void yyerror(const char *msg, ...) exit(1); } -struct cod_entry *do_file_rule(char *id, int mode, char *link_id, char *nt) +struct cod_entry *do_file_rule(char *id, perms_t perms, char *link_id, char *nt) { struct cod_entry *entry; - PDEBUG("Matched: tok_id (%s) tok_mode (0x%x)\n", id, mode); - entry = new_entry(id, mode, link_id); + PDEBUG("Matched: tok_id (%s) tok_perms (0x%x)\n", id, perms); + entry = new_entry(id, perms, link_id); if (!entry) yyerror(_("Memory allocation error.")); entry->nt_name = nt; @@ -1811,7 +1811,7 @@ struct cod_entry *do_file_rule(char *id, int mode, char *link_id, char *nt) void add_local_entry(Profile *prof) { /* ugh this has to be called after the hat is attached to its parent */ - if (prof->local_mode) { + if (prof->local_perms) { struct cod_entry *entry; char *trans = (char *) malloc(strlen(prof->parent->name) + strlen(prof->name) + 3); @@ -1820,7 +1820,7 @@ void add_local_entry(Profile *prof) yyerror(_("Memory allocation error.")); sprintf(name, "%s//%s", prof->parent->name, prof->name); - entry = new_entry(name, prof->local_mode, NULL); + entry = new_entry(name, prof->local_perms, NULL); entry->audit = prof->local_audit; entry->nt_name = trans; if (!entry) @@ -1859,7 +1859,7 @@ int verify_mnt_conds(struct cond_entry *conds, int src) mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src, struct cond_entry *dst_conds, char *dst, - int mode) + perms_t perms) { if (verify_mnt_conds(src_conds, MNT_SRC_OPT) != 0) yyerror(_("bad mount rule")); @@ -1871,7 +1871,7 @@ mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src, if (dst_conds) yyerror(_("mount point conditions not currently supported")); - mnt_rule *ent = new mnt_rule(src_conds, src, dst_conds, dst, mode); + mnt_rule *ent = new mnt_rule(src_conds, src, dst_conds, dst, perms); if (!ent) { yyerror(_("Memory allocation error.")); } diff --git a/parser/profile.h b/parser/profile.h index 5606baa46..59ba23309 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -190,7 +190,7 @@ public: /* char *sub_name; */ /* subdomain name or NULL */ /* int default_deny; */ /* TRUE or FALSE */ int local; - int local_mode; /* true if local, not hat */ + perms_t local_perms; int local_audit; Profile *parent; @@ -221,7 +221,8 @@ public: xattrs.list = NULL; xattrs.name = NULL; - local = local_mode = local_audit = 0; + local_perms = 0; + local = local_audit = 0; parent = NULL; diff --git a/parser/ptrace.cc b/parser/ptrace.cc index d13a7fade..19005cc51 100644 --- a/parser/ptrace.cc +++ b/parser/ptrace.cc @@ -24,9 +24,9 @@ #include #include -int parse_ptrace_mode(const char *str_mode, int *mode, int fail) +int parse_ptrace_perms(const char *str_perms, perms_t *perms, int fail) { - return parse_X_mode("ptrace", AA_VALID_PTRACE_PERMS, str_mode, mode, fail); + return parse_X_perms("ptrace", AA_VALID_PTRACE_PERMS, str_perms, perms, fail); } void ptrace_rule::move_conditionals(struct cond_entry *conds) @@ -47,15 +47,15 @@ void ptrace_rule::move_conditionals(struct cond_entry *conds) } } -ptrace_rule::ptrace_rule(int mode_p, struct cond_entry *conds): +ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): peer_label(NULL), audit(0), deny(0) { - if (mode_p) { - if (mode_p & ~AA_VALID_PTRACE_PERMS) - yyerror("mode contains invalid permissions for ptrace\n"); - mode = mode_p; + if (perms_p) { + if (perms_p & ~AA_VALID_PTRACE_PERMS) + yyerror("perms contains invalid permissions for ptrace\n"); + perms = perms_p; } else { - mode = AA_VALID_PTRACE_PERMS; + perms = AA_VALID_PTRACE_PERMS; } move_conditionals(conds); @@ -71,16 +71,16 @@ ostream &ptrace_rule::dump(ostream &os) os << "ptrace"; - if (mode != AA_VALID_PTRACE_PERMS) { + if (perms != AA_VALID_PTRACE_PERMS) { os << " ("; - if (mode & AA_MAY_READ) + if (perms & AA_MAY_READ) os << "read "; - if (mode & AA_MAY_READBY) + if (perms & AA_MAY_READBY) os << "readby "; - if (mode & AA_MAY_TRACE) + if (perms & AA_MAY_TRACE) os << "trace "; - if (mode & AA_MAY_TRACEDBY) + if (perms & AA_MAY_TRACEDBY) os << "tracedby "; os << ")"; } @@ -136,8 +136,8 @@ int ptrace_rule::gen_policy_re(Profile &prof) } buf = buffer.str(); - if (mode & AA_VALID_PTRACE_PERMS) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit, + if (perms & AA_VALID_PTRACE_PERMS) { + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit, dfaflags)) goto fail; } diff --git a/parser/ptrace.h b/parser/ptrace.h index 8c320c076..966ab2bd8 100644 --- a/parser/ptrace.h +++ b/parser/ptrace.h @@ -27,17 +27,17 @@ #define AA_VALID_PTRACE_PERMS (AA_MAY_READ | AA_MAY_TRACE | AA_MAY_READBY | \ AA_MAY_TRACEDBY) -int parse_ptrace_mode(const char *str_mode, int *mode, int fail); +int parse_ptrace_perms(const char *str_perms, perms_t *perms, int fail); class ptrace_rule: public rule_t { void move_conditionals(struct cond_entry *conds); public: char *peer_label; - int mode; + perms_t perms; int audit; int deny; - ptrace_rule(int mode, struct cond_entry *conds); + ptrace_rule(perms_t perms, struct cond_entry *conds); virtual ~ptrace_rule() { free(peer_label); diff --git a/parser/signal.cc b/parser/signal.cc index c80dab6fb..629459224 100644 --- a/parser/signal.cc +++ b/parser/signal.cc @@ -116,9 +116,9 @@ static const char *const sig_names[MAXMAPPED_SIG + 1] = { }; -int parse_signal_mode(const char *str_mode, int *mode, int fail) +int parse_signal_perms(const char *str_perms, perms_t *perms, int fail) { - return parse_X_mode("signal", AA_VALID_SIGNAL_PERMS, str_mode, mode, fail); + return parse_X_perms("signal", AA_VALID_SIGNAL_PERMS, str_perms, perms, fail); } static int find_signal_mapping(const char *sig) @@ -173,15 +173,15 @@ void signal_rule::move_conditionals(struct cond_entry *conds) } } -signal_rule::signal_rule(int mode_p, struct cond_entry *conds): +signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): signals(), peer_label(NULL), audit(0), deny(0) { - if (mode_p) { - mode = mode_p; - if (mode & ~AA_VALID_SIGNAL_PERMS) - yyerror("mode contains invalid permission for signals\n"); + if (perms_p) { + perms = perms_p; + if (perms & ~AA_VALID_SIGNAL_PERMS) + yyerror("perms contains invalid permission for signals\n"); } else { - mode = AA_VALID_SIGNAL_PERMS; + perms = AA_VALID_SIGNAL_PERMS; } move_conditionals(conds); @@ -198,12 +198,12 @@ ostream &signal_rule::dump(ostream &os) os << "signal"; - if (mode != AA_VALID_SIGNAL_PERMS) { + if (perms != AA_VALID_SIGNAL_PERMS) { os << " ("; - if (mode & AA_MAY_SEND) + if (perms & AA_MAY_SEND) os << "send "; - if (mode & AA_MAY_RECEIVE) + if (perms & AA_MAY_RECEIVE) os << "receive "; os << ")"; } @@ -291,8 +291,8 @@ int signal_rule::gen_policy_re(Profile &prof) } buf = buffer.str(); - if (mode & (AA_MAY_SEND | AA_MAY_RECEIVE)) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit, + if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) { + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit, dfaflags)) goto fail; } diff --git a/parser/signal.h b/parser/signal.h index b73aeb68a..dc5d19368 100644 --- a/parser/signal.h +++ b/parser/signal.h @@ -31,7 +31,7 @@ typedef set Signals; -int parse_signal_mode(const char *str_mode, int *mode, int fail); +int parse_signal_perms(const char *str_perms, perms_t *perms, int fail); class signal_rule: public rule_t { void extract_sigs(struct value_list **list); @@ -39,11 +39,11 @@ class signal_rule: public rule_t { public: Signals signals; char *peer_label; - int mode; + perms_t perms; int audit; int deny; - signal_rule(int mode, struct cond_entry *conds); + signal_rule(perms_t perms, struct cond_entry *conds); virtual ~signal_rule() { signals.clear(); free(peer_label); diff --git a/parser/userns.cc b/parser/userns.cc index a83d05904..203726d3d 100644 --- a/parser/userns.cc +++ b/parser/userns.cc @@ -40,17 +40,17 @@ void userns_rule::move_conditionals(struct cond_entry *conds) } } -userns_rule::userns_rule(int mode_p, struct cond_entry *conds): +userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): audit(0), deny(0) { - if (mode_p) { - if (mode_p & ~AA_VALID_USERNS_PERMS) - yyerror("mode contains invalid permissions for userns\n"); - mode = mode_p; + if (perms_p) { + if (perms_p & ~AA_VALID_USERNS_PERMS) + yyerror("perms contains invalid permissions for userns\n"); + perms = perms_p; } else { /* default to all perms */ - mode = AA_VALID_USERNS_PERMS; + perms = AA_VALID_USERNS_PERMS; } move_conditionals(conds); @@ -66,8 +66,8 @@ ostream &userns_rule::dump(ostream &os) os << "userns "; - if (mode != AA_VALID_USERNS_PERMS) { - if (mode & AA_USERNS_CREATE) + if (perms != AA_VALID_USERNS_PERMS) { + if (perms & AA_USERNS_CREATE) os << "create "; } @@ -99,8 +99,8 @@ int userns_rule::gen_policy_re(Profile &prof) buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NS; buf = buffer.str(); - if (mode & AA_VALID_USERNS_PERMS) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, mode, audit, + if (perms & AA_VALID_USERNS_PERMS) { + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit, dfaflags)) goto fail; } diff --git a/parser/userns.h b/parser/userns.h index 9337da285..52f727841 100644 --- a/parser/userns.h +++ b/parser/userns.h @@ -26,11 +26,11 @@ class userns_rule: public rule_t { void move_conditionals(struct cond_entry *conds); public: - int mode; + perms_t perms; int audit; int deny; - userns_rule(int mode, struct cond_entry *conds); + userns_rule(perms_t perms, struct cond_entry *conds); virtual ~userns_rule() { }; From 6f5dc0e176730593806a7d6a4e2e4a827f468b5d Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 9 Jun 2021 14:47:52 -0700 Subject: [PATCH 03/25] parser: Don't merge rules based on audit flags This is a step towards restructuring how "audit" is handled so we can add quiet support and push mapping of audit bits later. Signed-off-by: John Johansen --- parser/parser_merge.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/parser/parser_merge.c b/parser/parser_merge.c index edce208db..b93103aa1 100644 --- a/parser/parser_merge.c +++ b/parser/parser_merge.c @@ -51,6 +51,9 @@ static int file_comp(const void *c1, const void *c2) if ((*e1)->deny != (*e2)->deny) return (*e1)->deny < (*e2)->deny ? -1 : 1; + if ((*e1)->audit != (*e2)->audit) + return (*e1)->audit < (*e2)->audit ? -1 : 1; + return strcmp((*e1)->name, (*e2)->name); } @@ -95,7 +98,6 @@ static int process_file_entries(Profile *prof) return -1; } cur->perms |= next->perms; - cur->audit |= next->audit; cur->next = next->next; next->next = NULL; From 4fd1f97102ec64f740ff7e41664c367a49b452b1 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Fri, 11 Jun 2021 03:20:18 -0700 Subject: [PATCH 04/25] parser: rename mount->allow to mount->perms and switch to perm_t Make mount permission set consistent with the other rule types. This is a step towards refactoring. Signed-off-by: John Johansen --- parser/mount.cc | 74 ++++++++++++++++++++++---------------------- parser/mount.h | 5 +-- parser/parser_yacc.y | 4 +-- 3 files changed, 42 insertions(+), 41 deletions(-) diff --git a/parser/mount.cc b/parser/mount.cc index 533aef202..3d094e332 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -467,7 +467,7 @@ static void process_one_option(struct cond_entry *&opts, unsigned int &flags, mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, - int allow_p): + perms_t perms_p): mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL), flagsv(0), opt_flagsv(0), audit(0), deny(0) { @@ -506,7 +506,7 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, /* throw away tmpinv_flags, only needed in * consistancy check */ - if (allow_p & AA_DUMMY_REMOUNT) + if (perms_p & AA_DUMMY_REMOUNT) tmpflags |= MS_REMOUNT; if (conflicting_flags(tmpflags, tmpinv_flags)) { @@ -526,7 +526,7 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, if (!(flagsv.size() + opt_flagsv.size())) { /* no flag options, and not remount, allow everything */ - if (allow_p & AA_DUMMY_REMOUNT) { + if (perms_p & AA_DUMMY_REMOUNT) { flagsv.push_back(MS_REMOUNT); opt_flagsv.push_back(MS_REMOUNT_FLAGS & ~MS_REMOUNT); } else { @@ -535,7 +535,7 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, } } else if (!(flagsv.size())) { /* no flags but opts set */ - if (allow_p & AA_DUMMY_REMOUNT) + if (perms_p & AA_DUMMY_REMOUNT) flagsv.push_back(MS_REMOUNT); else flagsv.push_back(0); @@ -543,19 +543,19 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, opt_flagsv.push_back(0); } - if (allow_p & AA_DUMMY_REMOUNT) { - allow_p = AA_MAY_MOUNT; + if (perms_p & AA_DUMMY_REMOUNT) { + perms_p = AA_MAY_MOUNT; } - allow = allow_p; + perms = perms_p; } ostream &mnt_rule::dump(ostream &os) { - if (allow & AA_MAY_MOUNT) + if (perms & AA_MAY_MOUNT) os << "mount"; - else if (allow & AA_MAY_UMOUNT) + else if (perms & AA_MAY_UMOUNT) os << "umount"; - else if (allow & AA_MAY_PIVOTROOT) + else if (perms & AA_MAY_PIVOTROOT) os << "pivotroot"; else os << "error: unknown mount perm"; @@ -581,7 +581,7 @@ ostream &mnt_rule::dump(ostream &os) os << " -> " << trans; const char *prefix = deny ? "deny" : ""; - os << " " << prefix << "(0x" << hex << allow << "/0x" << audit << ")"; + os << " " << prefix << "(0x" << hex << perms << "/0x" << audit << ")"; os << ",\n"; return os; @@ -699,7 +699,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, std::string optsbuf; char class_mount_hdr[64]; const char *vec[5]; - int tmpallow; + perms_t tmpperms; sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT); @@ -728,12 +728,12 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, vec[3] = flagsbuf; if (opts) - tmpallow = AA_MATCH_CONT; + tmpperms = AA_MATCH_CONT; else - tmpallow = allow; + tmpperms = perms; /* rule for match without required data || data MATCH_CONT */ - if (!prof.policy.rules->add_rule_vec(deny, tmpallow, + if (!prof.policy.rules->add_rule_vec(deny, tmpperms, audit | AA_AUDIT_MNT_DATA, 4, vec, dfaflags, false)) goto fail; @@ -745,7 +745,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, if (!build_mnt_opts(optsbuf, opts)) goto fail; vec[4] = optsbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, allow, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit | AA_AUDIT_MNT_DATA, 5, vec, dfaflags, false)) goto fail; @@ -787,7 +787,7 @@ int mnt_rule::gen_policy_bind_mount(Profile &prof, int &count, opt_flags & MS_BIND_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 4, vec, dfaflags, false)) goto fail; count++; @@ -828,7 +828,7 @@ int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count, opt_flags & MS_MAKE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 4, vec, dfaflags, false)) goto fail; count++; @@ -870,7 +870,7 @@ int mnt_rule::gen_policy_move_mount(Profile &prof, int &count, opt_flags & MS_MOVE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 4, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 4, vec, dfaflags, false)) goto fail; count++; @@ -891,7 +891,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, std::string optsbuf; char class_mount_hdr[64]; const char *vec[5]; - int tmpallow; + perms_t tmpperms; sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT); @@ -914,12 +914,12 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, vec[3] = flagsbuf; if (opts) - tmpallow = AA_MATCH_CONT; + tmpperms = AA_MATCH_CONT; else - tmpallow = allow; + tmpperms = perms; /* rule for match without required data || data MATCH_CONT */ - if (!prof.policy.rules->add_rule_vec(deny, tmpallow, + if (!prof.policy.rules->add_rule_vec(deny, tmpperms, audit | AA_AUDIT_MNT_DATA, 4, vec, dfaflags, false)) goto fail; @@ -931,7 +931,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, if (!build_mnt_opts(optsbuf, opts)) goto fail; vec[4] = optsbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, allow, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit | AA_AUDIT_MNT_DATA, 5, vec, dfaflags, false)) goto fail; @@ -951,7 +951,7 @@ int mnt_rule::gen_flag_rules(Profile &prof, int &count, unsigned int flags, * XXX: added !flags to cover cases like: * mount options in (bind) /d -> /4, */ - if ((allow & AA_MAY_MOUNT) && (!flags || flags == MS_ALL_FLAGS)) { + if ((perms & AA_MAY_MOUNT) && (!flags || flags == MS_ALL_FLAGS)) { /* no mount flags specified, generate multiple rules */ if (!device && !dev_type && gen_policy_remount(prof, count, flags, opt_flags) == RULE_ERROR) @@ -967,20 +967,20 @@ int mnt_rule::gen_flag_rules(Profile &prof, int &count, unsigned int flags, return RULE_ERROR; return gen_policy_new_mount(prof, count, flags, opt_flags); - } else if ((allow & AA_MAY_MOUNT) && (flags & MS_REMOUNT) + } else if ((perms & AA_MAY_MOUNT) && (flags & MS_REMOUNT) && !device && !dev_type) { return gen_policy_remount(prof, count, flags, opt_flags); - } else if ((allow & AA_MAY_MOUNT) && (flags & MS_BIND) + } else if ((perms & AA_MAY_MOUNT) && (flags & MS_BIND) && !dev_type && !opts) { return gen_policy_bind_mount(prof, count, flags, opt_flags); - } else if ((allow & AA_MAY_MOUNT) && + } else if ((perms & AA_MAY_MOUNT) && (flags & (MS_MAKE_CMDS)) && !device && !dev_type && !opts) { return gen_policy_change_mount_type(prof, count, flags, opt_flags); - } else if ((allow & AA_MAY_MOUNT) && (flags & MS_MOVE) + } else if ((perms & AA_MAY_MOUNT) && (flags & MS_MOVE) && !dev_type && !opts) { return gen_policy_move_mount(prof, count, flags, opt_flags); - } else if ((allow & AA_MAY_MOUNT) && + } else if ((perms & AA_MAY_MOUNT) && ((flags | opt_flags) & ~MS_CMDS)) { /* generic mount if flags are set that are not covered by * above commands @@ -1017,18 +1017,18 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; } } - if (allow & AA_MAY_UMOUNT) { + if (perms & AA_MAY_UMOUNT) { /* rule class single byte header */ mntbuf.assign(class_mount_hdr); if (!convert_entry(mntbuf, mnt_point)) goto fail; vec[0] = mntbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 1, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 1, vec, dfaflags, false)) goto fail; count++; } - if (allow & AA_MAY_PIVOTROOT) { + if (perms & AA_MAY_PIVOTROOT) { /* rule class single byte header */ mntbuf.assign(class_mount_hdr); if (!convert_entry(mntbuf, mnt_point)) @@ -1037,7 +1037,7 @@ int mnt_rule::gen_policy_re(Profile &prof) if (!clear_and_convert_entry(devbuf, device)) goto fail; vec[1] = devbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, allow, audit, 2, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 2, vec, dfaflags, false)) goto fail; count++; @@ -1064,11 +1064,11 @@ void mnt_rule::post_process(Profile &prof) exit(1); } - if (allow & AA_USER_EXEC) + if (perms & AA_USER_EXEC) perms |= SHIFT_PERMS(n << 10, AA_USER_SHIFT); - if (allow & AA_OTHER_EXEC) + if (perms & AA_OTHER_EXEC) perms |= SHIFT_PERMS(n << 10, AA_OTHER_SHIFT); - allow = ((allow & ~AA_ALL_EXEC_MODIFIERS) | + perms = ((perms & ~AA_ALL_EXEC_MODIFIERS) | (perms & AA_ALL_EXEC_MODIFIERS)); trans = NULL; diff --git a/parser/mount.h b/parser/mount.h index 2bba7616a..2a6640c36 100644 --- a/parser/mount.h +++ b/parser/mount.h @@ -143,12 +143,13 @@ public: std::vector flagsv, opt_flagsv; - int allow, audit; + perms_t perms; + int audit; int deny; mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, - int allow_p); + perms_t perms_p); virtual ~mnt_rule() { free_value_list(opts); diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index c325b0249..7da3ade93 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -800,9 +800,9 @@ rules: rules opt_prefix mnt_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->allow; + $3->audit = $3->perms; } else if ($2.audit) { - $3->audit = $3->allow; + $3->audit = $3->perms; } $1->rule_ents.push_back($3); From 44f3be091a8dc19f3027547bd1fe091a34fb6a33 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Fri, 11 Jun 2021 03:07:54 -0700 Subject: [PATCH 05/25] parser: convert the stored audit from a bit mask to a bool This delays the convertion of the audit flag until passing to the backend. This is a step towards fix the parser front end so that it doesn't use encoded permission mappings. Note: the patch embedds the bool conversion into a struct to ensure the compiler will fail to build unless every use is fixed. The struct is removed in the following patch. Signed-off-by: John Johansen --- parser/af_rule.cc | 2 +- parser/af_rule.h | 4 ++-- parser/af_unix.cc | 18 +++++++------- parser/dbus.cc | 10 ++++---- parser/dbus.h | 2 +- parser/mount.cc | 56 ++++++++++++++++++++++++------------------- parser/mount.h | 2 +- parser/mqueue.cc | 12 +++++----- parser/mqueue.h | 2 +- parser/parser.h | 2 +- parser/parser_merge.c | 4 ++-- parser/parser_misc.c | 2 +- parser/parser_regex.c | 8 +++---- parser/parser_yacc.y | 40 +++++++++++++++---------------- parser/profile.h | 5 ++-- parser/ptrace.cc | 6 ++--- parser/ptrace.h | 2 +- parser/signal.cc | 6 ++--- parser/signal.h | 2 +- parser/userns.cc | 7 +++--- parser/userns.h | 2 +- 21 files changed, 102 insertions(+), 92 deletions(-) diff --git a/parser/af_rule.cc b/parser/af_rule.cc index 3c46543ae..0fdbac106 100644 --- a/parser/af_rule.cc +++ b/parser/af_rule.cc @@ -92,7 +92,7 @@ int af_rule::move_base_cond(struct cond_entry *ent, bool peer) ostream &af_rule::dump_prefix(ostream &os) { - if (audit) + if (audit.audit) os << "audit "; if (deny) os << "deny "; diff --git a/parser/af_rule.h b/parser/af_rule.h index 400402205..ffd4cf371 100644 --- a/parser/af_rule.h +++ b/parser/af_rule.h @@ -45,12 +45,12 @@ public: char *label; char *peer_label; perms_t perms; - int audit; + struct { bool audit; } audit; bool deny; af_rule(const char *name): af_name(name), sock_type(NULL), sock_type_n(-1), proto(NULL), proto_n(0), label(NULL), - peer_label(NULL), perms(0), audit(0), deny(0) + peer_label(NULL), perms(0), audit({ false }), deny(0) {} virtual ~af_rule() diff --git a/parser/af_unix.cc b/parser/af_unix.cc index 2e469e3fd..cf286b537 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -105,7 +105,7 @@ unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied): yyerror("socket rule: invalid socket type '%d'", type_p); } perms = AA_VALID_NET_PERMS; - audit = audit_p ? AA_VALID_NET_PERMS : 0; + audit.audit = audit_p; deny = denied; } @@ -195,7 +195,7 @@ void unix_rule::downgrade_rule(Profile &prof) { mask = 1 << sock_type_n; if (!deny) { prof.net.allow[AF_UNIX] |= mask; - if (audit) + if (audit.audit) prof.net.audit[AF_UNIX] |= mask; } else { /* deny rules have to be dropped because the downgrade makes @@ -336,7 +336,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_CREATE), - map_perms(audit & AA_NET_CREATE), + map_perms(audit.audit ? AA_NET_CREATE : 0), dfaflags)) goto fail; mask &= ~AA_NET_CREATE; @@ -361,7 +361,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_BIND), - map_perms(audit & AA_NET_BIND), + map_perms(audit.audit ? AA_NET_BIND : 0), dfaflags)) goto fail; /* clear if auto, else generic need to generate addr below */ @@ -386,7 +386,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(mask & local_mask), - map_perms(audit & local_mask), + map_perms(audit.audit ? mask & local_mask : 0), dfaflags)) goto fail; } @@ -400,7 +400,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_LISTEN), - map_perms(audit & AA_NET_LISTEN), + map_perms(audit.audit ? AA_NET_LISTEN : 0), dfaflags)) goto fail; } @@ -412,8 +412,8 @@ int unix_rule::gen_policy_re(Profile &prof) tmp << ".."; buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, - map_perms(mask & AA_NET_OPT), - map_perms(audit & AA_NET_OPT), + map_perms(AA_NET_OPT), + map_perms(audit.audit ? AA_NET_OPT : 0), dfaflags)) goto fail; } @@ -432,7 +432,7 @@ int unix_rule::gen_policy_re(Profile &prof) goto fail; buf = buffer.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit), dfaflags)) + if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit.audit ? perms & AA_PEER_NET_PERMS : 0), dfaflags)) goto fail; } diff --git a/parser/dbus.cc b/parser/dbus.cc index 9ea17ff32..2dc926445 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -69,7 +69,7 @@ void dbus_rule::move_conditionals(struct cond_entry *conds) dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds): bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL), - perms(0), audit(0), deny(0) + perms(0), audit( { false } ), deny(0) { int name_is_subject_cond = 0, message_rule = 0, service_rule = 0; @@ -122,7 +122,7 @@ dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, ostream &dbus_rule::dump(ostream &os) { - if (audit) + if (audit.audit) os << "audit "; if (deny) os << "deny "; @@ -279,21 +279,21 @@ int dbus_rule::gen_policy_re(Profile &prof) if (perms & AA_DBUS_BIND) { if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_BIND, - audit & AA_DBUS_BIND, + audit.audit ? perms & AA_DBUS_BIND : 0, 2, vec, dfaflags, false)) goto fail; } if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { if (!prof.policy.rules->add_rule_vec(deny, perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE), - audit & (AA_DBUS_SEND | AA_DBUS_RECEIVE), + audit.audit ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0, 6, vec, dfaflags, false)) goto fail; } if (perms & AA_DBUS_EAVESDROP) { if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_EAVESDROP, - audit & AA_DBUS_EAVESDROP, + audit.audit ? perms & AA_DBUS_EAVESDROP : 0, 1, vec, dfaflags, false)) goto fail; } diff --git a/parser/dbus.h b/parser/dbus.h index 7345e88aa..7ed671808 100644 --- a/parser/dbus.h +++ b/parser/dbus.h @@ -40,7 +40,7 @@ public: char *interface; char *member; perms_t perms; - int audit; + struct { bool audit; } audit; int deny; dbus_rule(perms_t perms_p, struct cond_entry *conds, diff --git a/parser/mount.cc b/parser/mount.cc index 3d094e332..afe5f38e6 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -469,7 +469,7 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, perms_t perms_p): mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL), - flagsv(0), opt_flagsv(0), audit(0), deny(0) + flagsv(0), opt_flagsv(0), audit( { false } ), deny(0) { /* FIXME: dst_conds are ignored atm */ dev_type = extract_fstype(&src_conds); @@ -581,7 +581,7 @@ ostream &mnt_rule::dump(ostream &os) os << " -> " << trans; const char *prefix = deny ? "deny" : ""; - os << " " << prefix << "(0x" << hex << perms << "/0x" << audit << ")"; + os << " " << prefix << "(0x" << hex << perms << "/0x" << (audit.audit ? perms : 0) << ")"; os << ",\n"; return os; @@ -699,7 +699,6 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, std::string optsbuf; char class_mount_hdr[64]; const char *vec[5]; - perms_t tmpperms; sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT); @@ -727,14 +726,20 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, vec[3] = flagsbuf; - if (opts) + perms_t tmpperms, tmpaudit; + if (opts) { tmpperms = AA_MATCH_CONT; - else + tmpaudit = 0; + } else { + /* dependent on full expansion of any data match perms */ tmpperms = perms; - - /* rule for match without required data || data MATCH_CONT */ - if (!prof.policy.rules->add_rule_vec(deny, tmpperms, - audit | AA_AUDIT_MNT_DATA, 4, + tmpaudit = audit.audit ? perms : 0; + } + /* match for up to but not including data + * if a data match is required this only has AA_MATCH_CONT perms + * else it has full perms + */ + if (!prof.policy.rules->add_rule_vec(deny, tmpperms, tmpaudit, 4, vec, dfaflags, false)) goto fail; count++; @@ -746,7 +751,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, goto fail; vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - audit | AA_AUDIT_MNT_DATA, + (audit.audit ? perms : 0), 5, vec, dfaflags, false)) goto fail; count++; @@ -787,7 +792,7 @@ int mnt_rule::gen_policy_bind_mount(Profile &prof, int &count, opt_flags & MS_BIND_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 4, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 4, vec, dfaflags, false)) goto fail; count++; @@ -828,7 +833,7 @@ int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count, opt_flags & MS_MAKE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 4, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 4, vec, dfaflags, false)) goto fail; count++; @@ -870,7 +875,7 @@ int mnt_rule::gen_policy_move_mount(Profile &prof, int &count, opt_flags & MS_MOVE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 4, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 4, vec, dfaflags, false)) goto fail; count++; @@ -891,7 +896,6 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, std::string optsbuf; char class_mount_hdr[64]; const char *vec[5]; - perms_t tmpperms; sprintf(class_mount_hdr, "\\x%02x", AA_CLASS_MOUNT); @@ -913,14 +917,16 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, goto fail; vec[3] = flagsbuf; - if (opts) + perms_t tmpperms, tmpaudit; + if (opts) { tmpperms = AA_MATCH_CONT; - else + tmpaudit = 0; + } else { tmpperms = perms; - + tmpaudit = audit.audit ? perms : 0; + } /* rule for match without required data || data MATCH_CONT */ - if (!prof.policy.rules->add_rule_vec(deny, tmpperms, - audit | AA_AUDIT_MNT_DATA, 4, + if (!prof.policy.rules->add_rule_vec(deny, tmpperms, tmpaudit, 4, vec, dfaflags, false)) goto fail; count++; @@ -932,7 +938,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, goto fail; vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - audit | AA_AUDIT_MNT_DATA, + audit.audit ? perms : 0, 5, vec, dfaflags, false)) goto fail; count++; @@ -1023,8 +1029,9 @@ int mnt_rule::gen_policy_re(Profile &prof) if (!convert_entry(mntbuf, mnt_point)) goto fail; vec[0] = mntbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 1, vec, - dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, + (audit.audit ? perms : 0), 1, vec, + dfaflags, false)) goto fail; count++; } @@ -1037,8 +1044,9 @@ int mnt_rule::gen_policy_re(Profile &prof) if (!clear_and_convert_entry(devbuf, device)) goto fail; vec[1] = devbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, perms, audit, 2, vec, - dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, + (audit.audit ? perms : 0), 2, vec, + dfaflags, false)) goto fail; count++; } diff --git a/parser/mount.h b/parser/mount.h index 2a6640c36..c98fb3e4f 100644 --- a/parser/mount.h +++ b/parser/mount.h @@ -144,7 +144,7 @@ public: std::vector flagsv, opt_flagsv; perms_t perms; - int audit; + struct { bool audit; } audit; int deny; mnt_rule(struct cond_entry *src_conds, char *device_p, diff --git a/parser/mqueue.cc b/parser/mqueue.cc index ae8efe8f1..41972d208 100644 --- a/parser/mqueue.cc +++ b/parser/mqueue.cc @@ -87,7 +87,7 @@ void mqueue_rule::move_conditionals(struct cond_entry *conds) } mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p): - qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit(0), deny(0) + qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit({false}), deny(0) { move_conditionals(conds); free_cond_list(conds); @@ -115,7 +115,7 @@ mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_ ostream &mqueue_rule::dump(ostream &os) { - if (audit) + if (audit.audit) os << "audit "; if (deny) os << "deny "; @@ -233,10 +233,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) /* store perms at name match so label doesn't need * to be checked */ - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, size, vec, dfaflags, false)) goto fail; } } @@ -268,10 +268,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) } if (perms & AA_VALID_SYSV_MQ_PERMS) { - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, size, vec, dfaflags, false)) goto fail; } } diff --git a/parser/mqueue.h b/parser/mqueue.h index d1be8de62..42d6c1c91 100644 --- a/parser/mqueue.h +++ b/parser/mqueue.h @@ -88,7 +88,7 @@ public: char *qname; char *label; perms_t perms; - int audit; + struct { bool audit; } audit; int deny; mqueue_rule(perms_t perms, struct cond_entry *conds, char *qname = NULL); diff --git a/parser/parser.h b/parser/parser.h index c460c30c7..aa4f83abf 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -130,7 +130,7 @@ struct cod_entry { Profile *prof; /* Special profile defined * just for this executable */ perms_t perms; /* perms is 'or' of AA_* bits */ - int audit; /* audit flags for perms */ + struct { bool audit; } audit; /* audit flags for perms */ int deny; /* TRUE or FALSE */ int alias_ignore; /* ignore for alias processing */ diff --git a/parser/parser_merge.c b/parser/parser_merge.c index b93103aa1..ef043a683 100644 --- a/parser/parser_merge.c +++ b/parser/parser_merge.c @@ -51,8 +51,8 @@ static int file_comp(const void *c1, const void *c2) if ((*e1)->deny != (*e2)->deny) return (*e1)->deny < (*e2)->deny ? -1 : 1; - if ((*e1)->audit != (*e2)->audit) - return (*e1)->audit < (*e2)->audit ? -1 : 1; + if ((*e1)->audit.audit != (*e2)->audit.audit) + return (*e1)->audit.audit < (*e2)->audit.audit ? -1 : 1; return strcmp((*e1)->name, (*e2)->name); } diff --git a/parser/parser_misc.c b/parser/parser_misc.c index 7c38a9c3d..6bab51896 100644 --- a/parser/parser_misc.c +++ b/parser/parser_misc.c @@ -961,7 +961,7 @@ struct cod_entry *new_entry(char *id, perms_t perms, char *link_id) entry->name = id; entry->link_name = link_id; entry->perms = perms; - entry->audit = 0; + entry->audit.audit = false; entry->deny = FALSE; entry->pattern_type = ePatternInvalid; diff --git a/parser/parser_regex.c b/parser/parser_regex.c index 517b7e472..e1268e644 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -632,12 +632,12 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) !is_change_profile_perms(entry->perms) && !dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), - entry->audit & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), + entry->audit.audit ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0, dfaflags)) return FALSE; } else if (!is_change_profile_perms(entry->perms)) { if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms, - entry->audit, dfaflags)) + entry->audit.audit ? entry->perms : 0, dfaflags)) return FALSE; } @@ -660,7 +660,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) perms |= LINK_TO_LINK_SUBSET(perms); vec[1] = "/[^/].*"; } - if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit & AA_LINK_BITS, 2, vec, dfaflags, false)) + if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit.audit ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false)) return FALSE; } if (is_change_profile_perms(entry->perms)) { @@ -671,7 +671,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) int index = 1; uint32_t onexec_perms = AA_ONEXEC; - if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit && warn_change_profile) { + if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit.audit && warn_change_profile) { /* don't have profile name here, so until this code * gets refactored just throw out a generic warning */ diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 7da3ade93..2070f7e7f 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -700,7 +700,7 @@ rules: rules opt_prefix rule $3->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); /* only set audit ctl quieting if the rule is not audited */ if (($2.deny && !$2.audit) || (!$2.deny && $2.audit)) - $3->audit = $3->perms & ~ALL_AA_EXEC_TYPE; + $3->audit.audit = true; add_entry_to_policy($1, $3); $$ = $1; @@ -731,9 +731,9 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); if ($2.audit && !entry->deny) - entry->audit = entry->perms & ~ALL_AA_EXEC_TYPE; + entry->audit.audit = true; else if (!$2.audit && entry->deny) - entry->audit = entry->perms & ~ALL_AA_EXEC_TYPE; + entry->audit.audit = true; add_entry_to_policy($1, entry); } $4->entries = NULL; @@ -800,9 +800,9 @@ rules: rules opt_prefix mnt_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->perms; + $3->audit.audit = true; } else if ($2.audit) { - $3->audit = $3->perms; + $3->audit.audit = true; } $1->rule_ents.push_back($3); @@ -817,9 +817,9 @@ rules: rules opt_prefix dbus_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->perms; + $3->audit.audit = true; } else if ($2.audit) { - $3->audit = $3->perms; + $3->audit.audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -833,9 +833,9 @@ rules: rules opt_prefix signal_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->perms; + $3->audit.audit = true; } else if ($2.audit) { - $3->audit = $3->perms; + $3->audit.audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -849,9 +849,9 @@ rules: rules opt_prefix ptrace_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->perms; + $3->audit.audit = true; } else if ($2.audit) { - $3->audit = $3->perms; + $3->audit.audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -865,9 +865,9 @@ rules: rules opt_prefix unix_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->perms; + $3->audit.audit = true; } else if ($2.audit) { - $3->audit = $3->perms; + $3->audit.audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -881,9 +881,9 @@ rules: rules opt_prefix userns_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->perms; + $3->audit.audit = true; } else if ($2.audit) { - $3->audit = $3->perms; + $3->audit.audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -901,9 +901,9 @@ rules: rules opt_prefix change_profile $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->perms; + $3->audit.audit = true; } else if ($2.audit) { - $3->audit = $3->perms; + $3->audit.audit = true; } add_entry_to_policy($1, $3); $$ = $1; @@ -936,9 +936,9 @@ rules: rules opt_prefix mqueue_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = $3->perms; + $3->audit.audit = true; } else if ($2.audit) { - $3->audit = $3->perms; + $3->audit.audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -1821,7 +1821,7 @@ void add_local_entry(Profile *prof) sprintf(name, "%s//%s", prof->parent->name, prof->name); entry = new_entry(name, prof->local_perms, NULL); - entry->audit = prof->local_audit; + entry->audit.audit = prof->local_audit.local_audit; entry->nt_name = trans; if (!entry) yyerror(_("Memory allocation error.")); diff --git a/parser/profile.h b/parser/profile.h index 59ba23309..096dc047f 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -191,7 +191,7 @@ public: /* int default_deny; */ /* TRUE or FALSE */ int local; perms_t local_perms; - int local_audit; + struct { bool local_audit; } local_audit; Profile *parent; @@ -222,7 +222,8 @@ public: xattrs.name = NULL; local_perms = 0; - local = local_audit = 0; + local = 0; + local_audit.local_audit = false; parent = NULL; diff --git a/parser/ptrace.cc b/parser/ptrace.cc index 19005cc51..ef0c9320b 100644 --- a/parser/ptrace.cc +++ b/parser/ptrace.cc @@ -48,7 +48,7 @@ void ptrace_rule::move_conditionals(struct cond_entry *conds) } ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): - peer_label(NULL), audit(0), deny(0) + peer_label(NULL), audit( { false } ), deny(0) { if (perms_p) { if (perms_p & ~AA_VALID_PTRACE_PERMS) @@ -64,7 +64,7 @@ ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): ostream &ptrace_rule::dump(ostream &os) { - if (audit) + if (audit.audit) os << "audit "; if (deny) os << "deny "; @@ -137,7 +137,7 @@ int ptrace_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & AA_VALID_PTRACE_PERMS) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit, + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit.audit ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/ptrace.h b/parser/ptrace.h index 966ab2bd8..104ed2f60 100644 --- a/parser/ptrace.h +++ b/parser/ptrace.h @@ -34,7 +34,7 @@ class ptrace_rule: public rule_t { public: char *peer_label; perms_t perms; - int audit; + struct { bool audit; } audit; int deny; ptrace_rule(perms_t perms, struct cond_entry *conds); diff --git a/parser/signal.cc b/parser/signal.cc index 629459224..3cee44c8b 100644 --- a/parser/signal.cc +++ b/parser/signal.cc @@ -174,7 +174,7 @@ void signal_rule::move_conditionals(struct cond_entry *conds) } signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): - signals(), peer_label(NULL), audit(0), deny(0) + signals(), peer_label(NULL), audit( { false} ), deny(0) { if (perms_p) { perms = perms_p; @@ -191,7 +191,7 @@ signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): ostream &signal_rule::dump(ostream &os) { - if (audit) + if (audit.audit) os << "audit "; if (deny) os << "deny "; @@ -292,7 +292,7 @@ int signal_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit, + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit.audit ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/signal.h b/parser/signal.h index dc5d19368..1e2b6427c 100644 --- a/parser/signal.h +++ b/parser/signal.h @@ -40,7 +40,7 @@ public: Signals signals; char *peer_label; perms_t perms; - int audit; + struct { bool audit; } audit; int deny; signal_rule(perms_t perms, struct cond_entry *conds); diff --git a/parser/userns.cc b/parser/userns.cc index 203726d3d..4b8eb06ee 100644 --- a/parser/userns.cc +++ b/parser/userns.cc @@ -41,7 +41,7 @@ void userns_rule::move_conditionals(struct cond_entry *conds) } userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): - audit(0), deny(0) + audit({false}), deny(0) { if (perms_p) { if (perms_p & ~AA_VALID_USERNS_PERMS) @@ -59,7 +59,7 @@ userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): ostream &userns_rule::dump(ostream &os) { - if (audit) + if (audit.audit) os << "audit "; if (deny) os << "deny "; @@ -100,7 +100,8 @@ int userns_rule::gen_policy_re(Profile &prof) buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NS; buf = buffer.str(); if (perms & AA_VALID_USERNS_PERMS) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit, + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, + audit.audit ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/userns.h b/parser/userns.h index 52f727841..caab4b0bc 100644 --- a/parser/userns.h +++ b/parser/userns.h @@ -27,7 +27,7 @@ class userns_rule: public rule_t { void move_conditionals(struct cond_entry *conds); public: perms_t perms; - int audit; + struct { bool audit; } audit; int deny; userns_rule(perms_t perms, struct cond_entry *conds); From 134e95f7830dc97ac97c3cac5fc49be617a4f251 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Fri, 11 Jun 2021 03:49:06 -0700 Subject: [PATCH 06/25] parser: fixup remove struct from the audit bool conversion This removes the struct wrapper used in the previous patch to ensure that all uses are properly converted. Signed-off-by: John Johansen --- parser/af_rule.cc | 2 +- parser/af_rule.h | 4 ++-- parser/af_unix.cc | 16 ++++++++-------- parser/dbus.cc | 10 +++++----- parser/dbus.h | 2 +- parser/mount.cc | 25 ++++++++++++++----------- parser/mount.h | 2 +- parser/mqueue.cc | 12 ++++++------ parser/mqueue.h | 2 +- parser/parser.h | 2 +- parser/parser_merge.c | 4 ++-- parser/parser_misc.c | 2 +- parser/parser_regex.c | 8 ++++---- parser/parser_yacc.y | 40 ++++++++++++++++++++-------------------- parser/profile.h | 4 ++-- parser/ptrace.cc | 6 +++--- parser/ptrace.h | 2 +- parser/signal.cc | 6 +++--- parser/signal.h | 2 +- parser/userns.cc | 6 +++--- parser/userns.h | 2 +- 21 files changed, 81 insertions(+), 78 deletions(-) diff --git a/parser/af_rule.cc b/parser/af_rule.cc index 0fdbac106..3c46543ae 100644 --- a/parser/af_rule.cc +++ b/parser/af_rule.cc @@ -92,7 +92,7 @@ int af_rule::move_base_cond(struct cond_entry *ent, bool peer) ostream &af_rule::dump_prefix(ostream &os) { - if (audit.audit) + if (audit) os << "audit "; if (deny) os << "deny "; diff --git a/parser/af_rule.h b/parser/af_rule.h index ffd4cf371..8bd91626a 100644 --- a/parser/af_rule.h +++ b/parser/af_rule.h @@ -45,12 +45,12 @@ public: char *label; char *peer_label; perms_t perms; - struct { bool audit; } audit; + bool audit; bool deny; af_rule(const char *name): af_name(name), sock_type(NULL), sock_type_n(-1), proto(NULL), proto_n(0), label(NULL), - peer_label(NULL), perms(0), audit({ false }), deny(0) + peer_label(NULL), perms(0), audit(false ), deny(0) {} virtual ~af_rule() diff --git a/parser/af_unix.cc b/parser/af_unix.cc index cf286b537..2090fd29e 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -105,7 +105,7 @@ unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied): yyerror("socket rule: invalid socket type '%d'", type_p); } perms = AA_VALID_NET_PERMS; - audit.audit = audit_p; + audit = audit_p; deny = denied; } @@ -195,7 +195,7 @@ void unix_rule::downgrade_rule(Profile &prof) { mask = 1 << sock_type_n; if (!deny) { prof.net.allow[AF_UNIX] |= mask; - if (audit.audit) + if (audit) prof.net.audit[AF_UNIX] |= mask; } else { /* deny rules have to be dropped because the downgrade makes @@ -336,7 +336,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_CREATE), - map_perms(audit.audit ? AA_NET_CREATE : 0), + map_perms(audit ? AA_NET_CREATE : 0), dfaflags)) goto fail; mask &= ~AA_NET_CREATE; @@ -361,7 +361,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_BIND), - map_perms(audit.audit ? AA_NET_BIND : 0), + map_perms(audit ? AA_NET_BIND : 0), dfaflags)) goto fail; /* clear if auto, else generic need to generate addr below */ @@ -386,7 +386,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(mask & local_mask), - map_perms(audit.audit ? mask & local_mask : 0), + map_perms(audit ? mask & local_mask : 0), dfaflags)) goto fail; } @@ -400,7 +400,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_LISTEN), - map_perms(audit.audit ? AA_NET_LISTEN : 0), + map_perms(audit ? AA_NET_LISTEN : 0), dfaflags)) goto fail; } @@ -413,7 +413,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_OPT), - map_perms(audit.audit ? AA_NET_OPT : 0), + map_perms(audit ? AA_NET_OPT : 0), dfaflags)) goto fail; } @@ -432,7 +432,7 @@ int unix_rule::gen_policy_re(Profile &prof) goto fail; buf = buffer.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit.audit ? perms & AA_PEER_NET_PERMS : 0), dfaflags)) + if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit ? perms & AA_PEER_NET_PERMS : 0), dfaflags)) goto fail; } diff --git a/parser/dbus.cc b/parser/dbus.cc index 2dc926445..8fc8c4a9c 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -69,7 +69,7 @@ void dbus_rule::move_conditionals(struct cond_entry *conds) dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds): bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL), - perms(0), audit( { false } ), deny(0) + perms(0), audit(false), deny(0) { int name_is_subject_cond = 0, message_rule = 0, service_rule = 0; @@ -122,7 +122,7 @@ dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, ostream &dbus_rule::dump(ostream &os) { - if (audit.audit) + if (audit) os << "audit "; if (deny) os << "deny "; @@ -279,21 +279,21 @@ int dbus_rule::gen_policy_re(Profile &prof) if (perms & AA_DBUS_BIND) { if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_BIND, - audit.audit ? perms & AA_DBUS_BIND : 0, + audit ? perms & AA_DBUS_BIND : 0, 2, vec, dfaflags, false)) goto fail; } if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { if (!prof.policy.rules->add_rule_vec(deny, perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE), - audit.audit ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0, + audit ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0, 6, vec, dfaflags, false)) goto fail; } if (perms & AA_DBUS_EAVESDROP) { if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_EAVESDROP, - audit.audit ? perms & AA_DBUS_EAVESDROP : 0, + audit ? perms & AA_DBUS_EAVESDROP : 0, 1, vec, dfaflags, false)) goto fail; } diff --git a/parser/dbus.h b/parser/dbus.h index 7ed671808..a7d8f89af 100644 --- a/parser/dbus.h +++ b/parser/dbus.h @@ -40,7 +40,7 @@ public: char *interface; char *member; perms_t perms; - struct { bool audit; } audit; + bool audit; int deny; dbus_rule(perms_t perms_p, struct cond_entry *conds, diff --git a/parser/mount.cc b/parser/mount.cc index afe5f38e6..921625296 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -469,7 +469,7 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, perms_t perms_p): mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL), - flagsv(0), opt_flagsv(0), audit( { false } ), deny(0) + flagsv(0), opt_flagsv(0), audit(false), deny(0) { /* FIXME: dst_conds are ignored atm */ dev_type = extract_fstype(&src_conds); @@ -581,7 +581,7 @@ ostream &mnt_rule::dump(ostream &os) os << " -> " << trans; const char *prefix = deny ? "deny" : ""; - os << " " << prefix << "(0x" << hex << perms << "/0x" << (audit.audit ? perms : 0) << ")"; + os << " " << prefix << "(0x" << hex << perms << "/0x" << (audit ? perms : 0) << ")"; os << ",\n"; return os; @@ -733,7 +733,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, } else { /* dependent on full expansion of any data match perms */ tmpperms = perms; - tmpaudit = audit.audit ? perms : 0; + tmpaudit = audit ? perms : 0; } /* match for up to but not including data * if a data match is required this only has AA_MATCH_CONT perms @@ -751,7 +751,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, goto fail; vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - (audit.audit ? perms : 0), + (audit ? perms : 0), 5, vec, dfaflags, false)) goto fail; count++; @@ -792,7 +792,8 @@ int mnt_rule::gen_policy_bind_mount(Profile &prof, int &count, opt_flags & MS_BIND_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 4, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, + 4, vec, dfaflags, false)) goto fail; count++; @@ -833,7 +834,8 @@ int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count, opt_flags & MS_MAKE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 4, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, + 4, vec, dfaflags, false)) goto fail; count++; @@ -875,7 +877,8 @@ int mnt_rule::gen_policy_move_mount(Profile &prof, int &count, opt_flags & MS_MOVE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 4, vec, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, + 4, vec, dfaflags, false)) goto fail; count++; @@ -923,7 +926,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, tmpaudit = 0; } else { tmpperms = perms; - tmpaudit = audit.audit ? perms : 0; + tmpaudit = audit ? perms : 0; } /* rule for match without required data || data MATCH_CONT */ if (!prof.policy.rules->add_rule_vec(deny, tmpperms, tmpaudit, 4, @@ -938,7 +941,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, goto fail; vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - audit.audit ? perms : 0, + audit ? perms : 0, 5, vec, dfaflags, false)) goto fail; count++; @@ -1030,7 +1033,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[0] = mntbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - (audit.audit ? perms : 0), 1, vec, + (audit ? perms : 0), 1, vec, dfaflags, false)) goto fail; count++; @@ -1045,7 +1048,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[1] = devbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - (audit.audit ? perms : 0), 2, vec, + (audit ? perms : 0), 2, vec, dfaflags, false)) goto fail; count++; diff --git a/parser/mount.h b/parser/mount.h index c98fb3e4f..26dee1f17 100644 --- a/parser/mount.h +++ b/parser/mount.h @@ -144,7 +144,7 @@ public: std::vector flagsv, opt_flagsv; perms_t perms; - struct { bool audit; } audit; + bool audit; int deny; mnt_rule(struct cond_entry *src_conds, char *device_p, diff --git a/parser/mqueue.cc b/parser/mqueue.cc index 41972d208..6a84ca841 100644 --- a/parser/mqueue.cc +++ b/parser/mqueue.cc @@ -87,7 +87,7 @@ void mqueue_rule::move_conditionals(struct cond_entry *conds) } mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p): - qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit({false}), deny(0) + qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit(false), deny(0) { move_conditionals(conds); free_cond_list(conds); @@ -115,7 +115,7 @@ mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_ ostream &mqueue_rule::dump(ostream &os) { - if (audit.audit) + if (audit) os << "audit "; if (deny) os << "deny "; @@ -233,10 +233,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) /* store perms at name match so label doesn't need * to be checked */ - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, size, vec, dfaflags, false)) goto fail; } } @@ -268,10 +268,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) } if (perms & AA_VALID_SYSV_MQ_PERMS) { - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit ? perms : 0, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, size, vec, dfaflags, false)) goto fail; } } diff --git a/parser/mqueue.h b/parser/mqueue.h index 42d6c1c91..703544e74 100644 --- a/parser/mqueue.h +++ b/parser/mqueue.h @@ -88,7 +88,7 @@ public: char *qname; char *label; perms_t perms; - struct { bool audit; } audit; + bool audit; int deny; mqueue_rule(perms_t perms, struct cond_entry *conds, char *qname = NULL); diff --git a/parser/parser.h b/parser/parser.h index aa4f83abf..8fe08c551 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -130,7 +130,7 @@ struct cod_entry { Profile *prof; /* Special profile defined * just for this executable */ perms_t perms; /* perms is 'or' of AA_* bits */ - struct { bool audit; } audit; /* audit flags for perms */ + bool audit; /* audit flags for perms */ int deny; /* TRUE or FALSE */ int alias_ignore; /* ignore for alias processing */ diff --git a/parser/parser_merge.c b/parser/parser_merge.c index ef043a683..b93103aa1 100644 --- a/parser/parser_merge.c +++ b/parser/parser_merge.c @@ -51,8 +51,8 @@ static int file_comp(const void *c1, const void *c2) if ((*e1)->deny != (*e2)->deny) return (*e1)->deny < (*e2)->deny ? -1 : 1; - if ((*e1)->audit.audit != (*e2)->audit.audit) - return (*e1)->audit.audit < (*e2)->audit.audit ? -1 : 1; + if ((*e1)->audit != (*e2)->audit) + return (*e1)->audit < (*e2)->audit ? -1 : 1; return strcmp((*e1)->name, (*e2)->name); } diff --git a/parser/parser_misc.c b/parser/parser_misc.c index 6bab51896..9fe38c8c3 100644 --- a/parser/parser_misc.c +++ b/parser/parser_misc.c @@ -961,7 +961,7 @@ struct cod_entry *new_entry(char *id, perms_t perms, char *link_id) entry->name = id; entry->link_name = link_id; entry->perms = perms; - entry->audit.audit = false; + entry->audit = false; entry->deny = FALSE; entry->pattern_type = ePatternInvalid; diff --git a/parser/parser_regex.c b/parser/parser_regex.c index e1268e644..dd177ae41 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -632,12 +632,12 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) !is_change_profile_perms(entry->perms) && !dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), - entry->audit.audit ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0, + entry->audit ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0, dfaflags)) return FALSE; } else if (!is_change_profile_perms(entry->perms)) { if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms, - entry->audit.audit ? entry->perms : 0, dfaflags)) + entry->audit ? entry->perms : 0, dfaflags)) return FALSE; } @@ -660,7 +660,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) perms |= LINK_TO_LINK_SUBSET(perms); vec[1] = "/[^/].*"; } - if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit.audit ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false)) + if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false)) return FALSE; } if (is_change_profile_perms(entry->perms)) { @@ -671,7 +671,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) int index = 1; uint32_t onexec_perms = AA_ONEXEC; - if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit.audit && warn_change_profile) { + if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit && warn_change_profile) { /* don't have profile name here, so until this code * gets refactored just throw out a generic warning */ diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 2070f7e7f..4275bac43 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -700,7 +700,7 @@ rules: rules opt_prefix rule $3->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); /* only set audit ctl quieting if the rule is not audited */ if (($2.deny && !$2.audit) || (!$2.deny && $2.audit)) - $3->audit.audit = true; + $3->audit = true; add_entry_to_policy($1, $3); $$ = $1; @@ -731,9 +731,9 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); if ($2.audit && !entry->deny) - entry->audit.audit = true; + entry->audit = true; else if (!$2.audit && entry->deny) - entry->audit.audit = true; + entry->audit = true; add_entry_to_policy($1, entry); } $4->entries = NULL; @@ -800,9 +800,9 @@ rules: rules opt_prefix mnt_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit = true; + $3->audit = true; } else if ($2.audit) { - $3->audit.audit = true; + $3->audit = true; } $1->rule_ents.push_back($3); @@ -817,9 +817,9 @@ rules: rules opt_prefix dbus_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit = true; + $3->audit = true; } else if ($2.audit) { - $3->audit.audit = true; + $3->audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -833,9 +833,9 @@ rules: rules opt_prefix signal_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit = true; + $3->audit = true; } else if ($2.audit) { - $3->audit.audit = true; + $3->audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -849,9 +849,9 @@ rules: rules opt_prefix ptrace_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit = true; + $3->audit = true; } else if ($2.audit) { - $3->audit.audit = true; + $3->audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -865,9 +865,9 @@ rules: rules opt_prefix unix_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit = true; + $3->audit = true; } else if ($2.audit) { - $3->audit.audit = true; + $3->audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -881,9 +881,9 @@ rules: rules opt_prefix userns_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit = true; + $3->audit = true; } else if ($2.audit) { - $3->audit.audit = true; + $3->audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -901,9 +901,9 @@ rules: rules opt_prefix change_profile $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit = true; + $3->audit = true; } else if ($2.audit) { - $3->audit.audit = true; + $3->audit = true; } add_entry_to_policy($1, $3); $$ = $1; @@ -936,9 +936,9 @@ rules: rules opt_prefix mqueue_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit = true; + $3->audit = true; } else if ($2.audit) { - $3->audit.audit = true; + $3->audit = true; } $1->rule_ents.push_back($3); $$ = $1; @@ -1821,7 +1821,7 @@ void add_local_entry(Profile *prof) sprintf(name, "%s//%s", prof->parent->name, prof->name); entry = new_entry(name, prof->local_perms, NULL); - entry->audit.audit = prof->local_audit.local_audit; + entry->audit = prof->local_audit; entry->nt_name = trans; if (!entry) yyerror(_("Memory allocation error.")); diff --git a/parser/profile.h b/parser/profile.h index 096dc047f..feb655926 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -191,7 +191,7 @@ public: /* int default_deny; */ /* TRUE or FALSE */ int local; perms_t local_perms; - struct { bool local_audit; } local_audit; + bool local_audit; Profile *parent; @@ -223,7 +223,7 @@ public: local_perms = 0; local = 0; - local_audit.local_audit = false; + local_audit = false; parent = NULL; diff --git a/parser/ptrace.cc b/parser/ptrace.cc index ef0c9320b..bae55423f 100644 --- a/parser/ptrace.cc +++ b/parser/ptrace.cc @@ -48,7 +48,7 @@ void ptrace_rule::move_conditionals(struct cond_entry *conds) } ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): - peer_label(NULL), audit( { false } ), deny(0) + peer_label(NULL), audit(false), deny(0) { if (perms_p) { if (perms_p & ~AA_VALID_PTRACE_PERMS) @@ -64,7 +64,7 @@ ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): ostream &ptrace_rule::dump(ostream &os) { - if (audit.audit) + if (audit) os << "audit "; if (deny) os << "deny "; @@ -137,7 +137,7 @@ int ptrace_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & AA_VALID_PTRACE_PERMS) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit.audit ? perms : 0, + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/ptrace.h b/parser/ptrace.h index 104ed2f60..86383ff2f 100644 --- a/parser/ptrace.h +++ b/parser/ptrace.h @@ -34,7 +34,7 @@ class ptrace_rule: public rule_t { public: char *peer_label; perms_t perms; - struct { bool audit; } audit; + bool audit; int deny; ptrace_rule(perms_t perms, struct cond_entry *conds); diff --git a/parser/signal.cc b/parser/signal.cc index 3cee44c8b..ff913fb71 100644 --- a/parser/signal.cc +++ b/parser/signal.cc @@ -174,7 +174,7 @@ void signal_rule::move_conditionals(struct cond_entry *conds) } signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): - signals(), peer_label(NULL), audit( { false} ), deny(0) + signals(), peer_label(NULL), audit(false), deny(0) { if (perms_p) { perms = perms_p; @@ -191,7 +191,7 @@ signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): ostream &signal_rule::dump(ostream &os) { - if (audit.audit) + if (audit) os << "audit "; if (deny) os << "deny "; @@ -292,7 +292,7 @@ int signal_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit.audit ? perms : 0, + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/signal.h b/parser/signal.h index 1e2b6427c..1e7cf1ab0 100644 --- a/parser/signal.h +++ b/parser/signal.h @@ -40,7 +40,7 @@ public: Signals signals; char *peer_label; perms_t perms; - struct { bool audit; } audit; + bool audit; int deny; signal_rule(perms_t perms, struct cond_entry *conds); diff --git a/parser/userns.cc b/parser/userns.cc index 4b8eb06ee..5821e6fc3 100644 --- a/parser/userns.cc +++ b/parser/userns.cc @@ -41,7 +41,7 @@ void userns_rule::move_conditionals(struct cond_entry *conds) } userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): - audit({false}), deny(0) + audit(false), deny(0) { if (perms_p) { if (perms_p & ~AA_VALID_USERNS_PERMS) @@ -59,7 +59,7 @@ userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): ostream &userns_rule::dump(ostream &os) { - if (audit.audit) + if (audit) os << "audit "; if (deny) os << "deny "; @@ -101,7 +101,7 @@ int userns_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & AA_VALID_USERNS_PERMS) { if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, - audit.audit ? perms : 0, + audit ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/userns.h b/parser/userns.h index caab4b0bc..6308aff2f 100644 --- a/parser/userns.h +++ b/parser/userns.h @@ -27,7 +27,7 @@ class userns_rule: public rule_t { void move_conditionals(struct cond_entry *conds); public: perms_t perms; - struct { bool audit; } audit; + bool audit; int deny; userns_rule(perms_t perms, struct cond_entry *conds); From 7a318d99f2d8ef24a5a4079db680ff2d988c7151 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 28 Aug 2021 02:11:11 -0700 Subject: [PATCH 07/25] parser: convert audit from bool to enum Audit control support is going to be extended to support allowing policy to which rules should quiet auditing. Update the frontend internals to prepare for this. Signed-off-by: John Johansen --- parser/af_rule.cc | 2 +- parser/af_rule.h | 4 +- parser/af_unix.cc | 18 ++++---- parser/af_unix.h | 2 +- parser/dbus.cc | 10 ++--- parser/dbus.h | 2 +- parser/mount.cc | 22 +++++----- parser/mount.h | 2 +- parser/mqueue.cc | 12 +++--- parser/mqueue.h | 2 +- parser/parser.h | 5 ++- parser/parser_merge.c | 4 +- parser/parser_misc.c | 4 +- parser/parser_regex.c | 8 ++-- parser/parser_yacc.y | 95 ++++++++++++++++++++++--------------------- parser/profile.h | 4 +- parser/ptrace.cc | 6 +-- parser/ptrace.h | 2 +- parser/signal.cc | 6 +-- parser/signal.h | 2 +- parser/userns.cc | 6 +-- parser/userns.h | 2 +- 22 files changed, 111 insertions(+), 109 deletions(-) diff --git a/parser/af_rule.cc b/parser/af_rule.cc index 3c46543ae..9c0a9d04a 100644 --- a/parser/af_rule.cc +++ b/parser/af_rule.cc @@ -92,7 +92,7 @@ int af_rule::move_base_cond(struct cond_entry *ent, bool peer) ostream &af_rule::dump_prefix(ostream &os) { - if (audit) + if (audit.audit_mode == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; diff --git a/parser/af_rule.h b/parser/af_rule.h index 8bd91626a..88b1503fc 100644 --- a/parser/af_rule.h +++ b/parser/af_rule.h @@ -45,12 +45,12 @@ public: char *label; char *peer_label; perms_t perms; - bool audit; + struct { audit_t audit_mode; } audit; bool deny; af_rule(const char *name): af_name(name), sock_type(NULL), sock_type_n(-1), proto(NULL), proto_n(0), label(NULL), - peer_label(NULL), perms(0), audit(false ), deny(0) + peer_label(NULL), perms(0), audit({AUDIT_UNSPECIFIED}), deny(0) {} virtual ~af_rule() diff --git a/parser/af_unix.cc b/parser/af_unix.cc index 2090fd29e..f586a8f67 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -95,7 +95,7 @@ void unix_rule::move_peer_conditionals(struct cond_entry *conds) } } -unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied): +unix_rule::unix_rule(unsigned int type_p, audit_t audit_p, bool denied): af_rule("unix"), addr(NULL), peer_addr(NULL) { if (type_p != 0xffffffff) { @@ -105,7 +105,7 @@ unix_rule::unix_rule(unsigned int type_p, bool audit_p, bool denied): yyerror("socket rule: invalid socket type '%d'", type_p); } perms = AA_VALID_NET_PERMS; - audit = audit_p; + audit.audit_mode = audit_p; deny = denied; } @@ -195,7 +195,7 @@ void unix_rule::downgrade_rule(Profile &prof) { mask = 1 << sock_type_n; if (!deny) { prof.net.allow[AF_UNIX] |= mask; - if (audit) + if (audit.audit_mode == AUDIT_FORCE) prof.net.audit[AF_UNIX] |= mask; } else { /* deny rules have to be dropped because the downgrade makes @@ -336,7 +336,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_CREATE), - map_perms(audit ? AA_NET_CREATE : 0), + map_perms(audit.audit_mode == AUDIT_FORCE ? AA_NET_CREATE : 0), dfaflags)) goto fail; mask &= ~AA_NET_CREATE; @@ -361,7 +361,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_BIND), - map_perms(audit ? AA_NET_BIND : 0), + map_perms(audit.audit_mode == AUDIT_FORCE ? AA_NET_BIND : 0), dfaflags)) goto fail; /* clear if auto, else generic need to generate addr below */ @@ -386,7 +386,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(mask & local_mask), - map_perms(audit ? mask & local_mask : 0), + map_perms(audit.audit_mode == AUDIT_FORCE ? mask & local_mask : 0), dfaflags)) goto fail; } @@ -400,7 +400,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_LISTEN), - map_perms(audit ? AA_NET_LISTEN : 0), + map_perms(audit.audit_mode == AUDIT_FORCE ? AA_NET_LISTEN : 0), dfaflags)) goto fail; } @@ -413,7 +413,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_OPT), - map_perms(audit ? AA_NET_OPT : 0), + map_perms(audit.audit_mode == AUDIT_FORCE ? AA_NET_OPT : 0), dfaflags)) goto fail; } @@ -432,7 +432,7 @@ int unix_rule::gen_policy_re(Profile &prof) goto fail; buf = buffer.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit ? perms & AA_PEER_NET_PERMS : 0), dfaflags)) + if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit.audit_mode == AUDIT_FORCE ? perms & AA_PEER_NET_PERMS : 0), dfaflags)) goto fail; } diff --git a/parser/af_unix.h b/parser/af_unix.h index e36168072..26615d26c 100644 --- a/parser/af_unix.h +++ b/parser/af_unix.h @@ -37,7 +37,7 @@ public: char *addr; char *peer_addr; - unix_rule(unsigned int type_p, bool audit_p, bool denied); + unix_rule(unsigned int type_p, audit_t audit_p, bool denied); unix_rule(perms_t perms, struct cond_entry *conds, struct cond_entry *peer_conds); virtual ~unix_rule() diff --git a/parser/dbus.cc b/parser/dbus.cc index 8fc8c4a9c..8999acda0 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -69,7 +69,7 @@ void dbus_rule::move_conditionals(struct cond_entry *conds) dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds): bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL), - perms(0), audit(false), deny(0) + perms(0), audit({AUDIT_UNSPECIFIED}), deny(0) { int name_is_subject_cond = 0, message_rule = 0, service_rule = 0; @@ -122,7 +122,7 @@ dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, ostream &dbus_rule::dump(ostream &os) { - if (audit) + if (audit.audit_mode == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -279,21 +279,21 @@ int dbus_rule::gen_policy_re(Profile &prof) if (perms & AA_DBUS_BIND) { if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_BIND, - audit ? perms & AA_DBUS_BIND : 0, + audit.audit_mode == AUDIT_FORCE ? perms & AA_DBUS_BIND : 0, 2, vec, dfaflags, false)) goto fail; } if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { if (!prof.policy.rules->add_rule_vec(deny, perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE), - audit ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0, + audit.audit_mode == AUDIT_FORCE ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0, 6, vec, dfaflags, false)) goto fail; } if (perms & AA_DBUS_EAVESDROP) { if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_EAVESDROP, - audit ? perms & AA_DBUS_EAVESDROP : 0, + audit.audit_mode == AUDIT_FORCE ? perms & AA_DBUS_EAVESDROP : 0, 1, vec, dfaflags, false)) goto fail; } diff --git a/parser/dbus.h b/parser/dbus.h index a7d8f89af..37b83f5f9 100644 --- a/parser/dbus.h +++ b/parser/dbus.h @@ -40,7 +40,7 @@ public: char *interface; char *member; perms_t perms; - bool audit; + struct { audit_t audit_mode; } audit; int deny; dbus_rule(perms_t perms_p, struct cond_entry *conds, diff --git a/parser/mount.cc b/parser/mount.cc index 921625296..7a8cad7c9 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -469,7 +469,7 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, perms_t perms_p): mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL), - flagsv(0), opt_flagsv(0), audit(false), deny(0) + flagsv(0), opt_flagsv(0), audit({AUDIT_UNSPECIFIED}), deny(0) { /* FIXME: dst_conds are ignored atm */ dev_type = extract_fstype(&src_conds); @@ -581,7 +581,7 @@ ostream &mnt_rule::dump(ostream &os) os << " -> " << trans; const char *prefix = deny ? "deny" : ""; - os << " " << prefix << "(0x" << hex << perms << "/0x" << (audit ? perms : 0) << ")"; + os << " " << prefix << "(0x" << hex << perms << "/0x" << (audit.audit_mode != AUDIT_UNSPECIFIED ? perms : 0) << ")"; os << ",\n"; return os; @@ -733,7 +733,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, } else { /* dependent on full expansion of any data match perms */ tmpperms = perms; - tmpaudit = audit ? perms : 0; + tmpaudit = audit.audit_mode == AUDIT_FORCE ? perms : 0; } /* match for up to but not including data * if a data match is required this only has AA_MATCH_CONT perms @@ -751,7 +751,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, goto fail; vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - (audit ? perms : 0), + (audit.audit_mode == AUDIT_FORCE ? perms : 0), 5, vec, dfaflags, false)) goto fail; count++; @@ -792,7 +792,7 @@ int mnt_rule::gen_policy_bind_mount(Profile &prof, int &count, opt_flags & MS_BIND_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, 4, vec, dfaflags, false)) goto fail; @@ -834,7 +834,7 @@ int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count, opt_flags & MS_MAKE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, 4, vec, dfaflags, false)) goto fail; @@ -877,7 +877,7 @@ int mnt_rule::gen_policy_move_mount(Profile &prof, int &count, opt_flags & MS_MOVE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, 4, vec, dfaflags, false)) goto fail; @@ -926,7 +926,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, tmpaudit = 0; } else { tmpperms = perms; - tmpaudit = audit ? perms : 0; + tmpaudit = audit.audit_mode == AUDIT_FORCE ? perms : 0; } /* rule for match without required data || data MATCH_CONT */ if (!prof.policy.rules->add_rule_vec(deny, tmpperms, tmpaudit, 4, @@ -941,7 +941,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, goto fail; vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - audit ? perms : 0, + audit.audit_mode == AUDIT_FORCE ? perms : 0, 5, vec, dfaflags, false)) goto fail; count++; @@ -1033,7 +1033,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[0] = mntbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - (audit ? perms : 0), 1, vec, + (audit.audit_mode == AUDIT_FORCE ? perms : 0), 1, vec, dfaflags, false)) goto fail; count++; @@ -1048,7 +1048,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[1] = devbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - (audit ? perms : 0), 2, vec, + (audit.audit_mode == AUDIT_FORCE ? perms : 0), 2, vec, dfaflags, false)) goto fail; count++; diff --git a/parser/mount.h b/parser/mount.h index 26dee1f17..7d73e2d32 100644 --- a/parser/mount.h +++ b/parser/mount.h @@ -144,7 +144,7 @@ public: std::vector flagsv, opt_flagsv; perms_t perms; - bool audit; + struct { audit_t audit_mode; } audit; int deny; mnt_rule(struct cond_entry *src_conds, char *device_p, diff --git a/parser/mqueue.cc b/parser/mqueue.cc index 6a84ca841..1a54d1b37 100644 --- a/parser/mqueue.cc +++ b/parser/mqueue.cc @@ -87,7 +87,7 @@ void mqueue_rule::move_conditionals(struct cond_entry *conds) } mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p): - qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit(false), deny(0) + qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit({AUDIT_UNSPECIFIED}), deny(0) { move_conditionals(conds); free_cond_list(conds); @@ -115,7 +115,7 @@ mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_ ostream &mqueue_rule::dump(ostream &os) { - if (audit) + if (audit.audit_mode == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -233,10 +233,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) /* store perms at name match so label doesn't need * to be checked */ - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false)) goto fail; } } @@ -268,10 +268,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) } if (perms & AA_VALID_SYSV_MQ_PERMS) { - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit ? perms : 0, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode ? perms : 0, size, vec, dfaflags, false)) goto fail; } } diff --git a/parser/mqueue.h b/parser/mqueue.h index 703544e74..b8fd38ca0 100644 --- a/parser/mqueue.h +++ b/parser/mqueue.h @@ -88,7 +88,7 @@ public: char *qname; char *label; perms_t perms; - bool audit; + struct { audit_t audit_mode; } audit; int deny; mqueue_rule(perms_t perms, struct cond_entry *conds, char *qname = NULL); diff --git a/parser/parser.h b/parser/parser.h index 8fe08c551..6448b4a8a 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -46,6 +46,7 @@ class Profile; class rule_t; typedef uint32_t perms_t; +typedef enum { AUDIT_UNSPECIFIED, AUDIT_FORCE, AUDIT_QUIET } audit_t; #define MODULE_NAME "apparmor" @@ -91,7 +92,7 @@ extern dfaflags_t werrflags; typedef enum pattern_t pattern_t; struct prefixes { - int audit; + audit_t audit; int deny; int owner; }; @@ -130,7 +131,7 @@ struct cod_entry { Profile *prof; /* Special profile defined * just for this executable */ perms_t perms; /* perms is 'or' of AA_* bits */ - bool audit; /* audit flags for perms */ + struct { audit_t audit_mode; } audit; int deny; /* TRUE or FALSE */ int alias_ignore; /* ignore for alias processing */ diff --git a/parser/parser_merge.c b/parser/parser_merge.c index b93103aa1..d9ce9f629 100644 --- a/parser/parser_merge.c +++ b/parser/parser_merge.c @@ -51,8 +51,8 @@ static int file_comp(const void *c1, const void *c2) if ((*e1)->deny != (*e2)->deny) return (*e1)->deny < (*e2)->deny ? -1 : 1; - if ((*e1)->audit != (*e2)->audit) - return (*e1)->audit < (*e2)->audit ? -1 : 1; + if ((*e1)->audit.audit_mode != (*e2)->audit.audit_mode) + return (*e1)->audit.audit_mode < (*e2)->audit.audit_mode ? -1 : 1; return strcmp((*e1)->name, (*e2)->name); } diff --git a/parser/parser_misc.c b/parser/parser_misc.c index 9fe38c8c3..1af6f996f 100644 --- a/parser/parser_misc.c +++ b/parser/parser_misc.c @@ -961,7 +961,7 @@ struct cod_entry *new_entry(char *id, perms_t perms, char *link_id) entry->name = id; entry->link_name = link_id; entry->perms = perms; - entry->audit = false; + entry->audit.audit_mode = AUDIT_UNSPECIFIED; entry->deny = FALSE; entry->pattern_type = ePatternInvalid; @@ -985,7 +985,7 @@ struct cod_entry *copy_cod_entry(struct cod_entry *orig) DUP_STRING(orig, entry, link_name, err); DUP_STRING(orig, entry, nt_name, err); entry->perms = orig->perms; - entry->audit = orig->audit; + entry->audit.audit_mode = orig->audit.audit_mode; entry->deny = orig->deny; /* XXX - need to create copies of the patterns, too */ diff --git a/parser/parser_regex.c b/parser/parser_regex.c index dd177ae41..f459b80d5 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -632,12 +632,12 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) !is_change_profile_perms(entry->perms) && !dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), - entry->audit ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0, + entry->audit.audit_mode == AUDIT_FORCE ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0, dfaflags)) return FALSE; } else if (!is_change_profile_perms(entry->perms)) { if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms, - entry->audit ? entry->perms : 0, dfaflags)) + entry->audit.audit_mode == AUDIT_FORCE ? entry->perms : 0, dfaflags)) return FALSE; } @@ -660,7 +660,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) perms |= LINK_TO_LINK_SUBSET(perms); vec[1] = "/[^/].*"; } - if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false)) + if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit.audit_mode == AUDIT_FORCE ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false)) return FALSE; } if (is_change_profile_perms(entry->perms)) { @@ -671,7 +671,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) int index = 1; uint32_t onexec_perms = AA_ONEXEC; - if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit && warn_change_profile) { + if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit.audit_mode == AUDIT_FORCE && warn_change_profile) { /* don't have profile name here, so until this code * gets refactored just throw out a generic warning */ diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 4275bac43..8cfa8eb8f 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -214,6 +214,7 @@ void add_local_entry(Profile *prof); int boolean; struct prefixes prefix; IncludeCache_t *includecache; + audit_t audit; } %type TOK_ID @@ -252,7 +253,7 @@ void add_local_entry(Profile *prof); %type id_or_var %type opt_id_or_var %type opt_subset_flag -%type opt_audit_flag +%type opt_audit_flag %type opt_owner_flag %type opt_profile_flag %type opt_flags @@ -650,8 +651,8 @@ opt_subset_flag: { /* nothing */ $$ = 0; } | TOK_SUBSET { $$ = 1; } | TOK_LE { $$ = 1; } -opt_audit_flag: { /* nothing */ $$ = 0; } - | TOK_AUDIT { $$ = 1; }; +opt_audit_flag: { /* nothing */ $$ = AUDIT_UNSPECIFIED; } + | TOK_AUDIT { $$ = AUDIT_FORCE; }; opt_owner_flag: { /* nothing */ $$ = 0; } | TOK_OWNER { $$ = 1; }; @@ -699,8 +700,8 @@ rules: rules opt_prefix rule else if ($2.owner == 2) $3->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); /* only set audit ctl quieting if the rule is not audited */ - if (($2.deny && !$2.audit) || (!$2.deny && $2.audit)) - $3->audit = true; + if (($2.deny && $2.audit != AUDIT_FORCE) || (!$2.deny && $2.audit == AUDIT_FORCE)) + $3->audit.audit_mode = AUDIT_FORCE; add_entry_to_policy($1, $3); $$ = $1; @@ -713,7 +714,7 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE if ($2.deny) yyerror(_("deny prefix not allowed")); - PDEBUG("matched: %s%s%sblock\n", $2.audit ? "audit " : "", + PDEBUG("matched: %s%s%sblock\n", $2.audit == AUDIT_FORCE ? "audit " : "", $2.deny ? "deny " : "", $2.owner ? "owner " : ""); list_for_each_safe($4->entries, entry, tmp) { entry->next = NULL; @@ -730,10 +731,10 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE else if ($2.owner == 2) entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); - if ($2.audit && !entry->deny) - entry->audit = true; - else if (!$2.audit && entry->deny) - entry->audit = true; + if ($2.audit == AUDIT_FORCE && !entry->deny) + entry->audit.audit_mode = AUDIT_FORCE; + else if ($2.audit != AUDIT_FORCE && entry->deny) + entry->audit.audit_mode = AUDIT_FORCE; add_entry_to_policy($1, entry); } $4->entries = NULL; @@ -768,21 +769,21 @@ rules: rules opt_prefix network_rule /* setting mask instead of a bit */ if ($2.deny) { $1->net.deny[entry->family] |= entry->type; - if (!$2.audit) + if ($2.audit != AUDIT_FORCE) $1->net.quiet[entry->family] |= entry->type; } else { $1->net.allow[entry->family] |= entry->type; - if ($2.audit) + if ($2.audit == AUDIT_FORCE) $1->net.audit[entry->family] |= entry->type; } } else { if ($2.deny) { $1->net.deny[entry->family] |= 1 << entry->type; - if (!$2.audit) + if ($2.audit != AUDIT_FORCE) $1->net.quiet[entry->family] |= 1 << entry->type; } else { $1->net.allow[entry->family] |= 1 << entry->type; - if ($2.audit) + if ($2.audit == AUDIT_FORCE) $1->net.audit[entry->family] |= 1 << entry->type; } } @@ -796,13 +797,13 @@ rules: rules opt_prefix mnt_rule { if ($2.owner) yyerror(_("owner prefix not allowed on mount rules")); - if ($2.deny && $2.audit) { + if ($2.deny && $2.audit == AUDIT_FORCE) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = true; - } else if ($2.audit) { - $3->audit = true; + $3->audit.audit_mode = AUDIT_FORCE; + } else if ($2.audit != AUDIT_UNSPECIFIED) { + $3->audit.audit_mode = $2.audit; } $1->rule_ents.push_back($3); @@ -813,13 +814,13 @@ rules: rules opt_prefix dbus_rule { if ($2.owner) yyerror(_("owner prefix not allowed on dbus rules")); - if ($2.deny && $2.audit) { + if ($2.deny && $2.audit == AUDIT_FORCE) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = true; - } else if ($2.audit) { - $3->audit = true; + $3->audit.audit_mode = AUDIT_FORCE; + } else if ($2.audit != AUDIT_UNSPECIFIED) { + $3->audit.audit_mode = $2.audit; } $1->rule_ents.push_back($3); $$ = $1; @@ -829,13 +830,13 @@ rules: rules opt_prefix signal_rule { if ($2.owner) yyerror(_("owner prefix not allowed on signal rules")); - if ($2.deny && $2.audit) { + if ($2.deny && $2.audit == AUDIT_FORCE) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = true; - } else if ($2.audit) { - $3->audit = true; + $3->audit.audit_mode = AUDIT_FORCE; + } else if ($2.audit != AUDIT_UNSPECIFIED) { + $3->audit.audit_mode = $2.audit; } $1->rule_ents.push_back($3); $$ = $1; @@ -845,13 +846,13 @@ rules: rules opt_prefix ptrace_rule { if ($2.owner) yyerror(_("owner prefix not allowed on ptrace rules")); - if ($2.deny && $2.audit) { + if ($2.deny && $2.audit == AUDIT_FORCE) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = true; - } else if ($2.audit) { - $3->audit = true; + $3->audit.audit_mode = AUDIT_FORCE; + } else if ($2.audit != AUDIT_UNSPECIFIED) { + $3->audit.audit_mode = $2.audit; } $1->rule_ents.push_back($3); $$ = $1; @@ -861,13 +862,13 @@ rules: rules opt_prefix unix_rule { if ($2.owner) yyerror(_("owner prefix not allowed on unix rules")); - if ($2.deny && $2.audit) { + if ($2.deny && $2.audit == AUDIT_FORCE) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = true; - } else if ($2.audit) { - $3->audit = true; + $3->audit.audit_mode = AUDIT_FORCE; + } else if ($2.audit != AUDIT_UNSPECIFIED) { + $3->audit.audit_mode = $2.audit; } $1->rule_ents.push_back($3); $$ = $1; @@ -881,9 +882,9 @@ rules: rules opt_prefix userns_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = true; - } else if ($2.audit) { - $3->audit = true; + $3->audit.audit_mode = AUDIT_FORCE; + } else if ($2.audit == AUDIT_FORCE) { + $3->audit.audit_mode = AUDIT_FORCE; } $1->rule_ents.push_back($3); $$ = $1; @@ -897,13 +898,13 @@ rules: rules opt_prefix change_profile yyerror(_("Assert: `change_profile' returned NULL.")); if ($2.owner) yyerror(_("owner prefix not allowed on unix rules")); - if ($2.deny && $2.audit) { + if ($2.deny && $2.audit == AUDIT_FORCE) { $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = true; - } else if ($2.audit) { - $3->audit = true; + $3->audit.audit_mode = AUDIT_FORCE; + } else if ($2.audit != AUDIT_UNSPECIFIED) { + $3->audit.audit_mode = $2.audit; } add_entry_to_policy($1, $3); $$ = $1; @@ -914,14 +915,14 @@ rules: rules opt_prefix capability if ($2.owner) yyerror(_("owner prefix not allowed on capability rules")); - if ($2.deny && $2.audit) { + if ($2.deny && $2.audit == AUDIT_FORCE) { $1->caps.deny |= $3; } else if ($2.deny) { $1->caps.deny |= $3; $1->caps.quiet |= $3; } else { $1->caps.allow |= $3; - if ($2.audit) + if ($2.audit != AUDIT_UNSPECIFIED) $1->caps.audit |= $3; } @@ -936,9 +937,9 @@ rules: rules opt_prefix mqueue_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit = true; - } else if ($2.audit) { - $3->audit = true; + $3->audit.audit_mode = AUDIT_FORCE; + } else if ($2.audit == AUDIT_FORCE) { + $3->audit.audit_mode = AUDIT_FORCE; } $1->rule_ents.push_back($3); $$ = $1; @@ -1821,7 +1822,7 @@ void add_local_entry(Profile *prof) sprintf(name, "%s//%s", prof->parent->name, prof->name); entry = new_entry(name, prof->local_perms, NULL); - entry->audit = prof->local_audit; + entry->audit.audit_mode = prof->local_audit.audit_mode; entry->nt_name = trans; if (!entry) yyerror(_("Memory allocation error.")); diff --git a/parser/profile.h b/parser/profile.h index feb655926..9e8c0f3c9 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -191,7 +191,7 @@ public: /* int default_deny; */ /* TRUE or FALSE */ int local; perms_t local_perms; - bool local_audit; + struct { audit_t audit_mode; } local_audit; Profile *parent; @@ -223,7 +223,7 @@ public: local_perms = 0; local = 0; - local_audit = false; + local_audit.audit_mode = AUDIT_UNSPECIFIED; parent = NULL; diff --git a/parser/ptrace.cc b/parser/ptrace.cc index bae55423f..2875f1088 100644 --- a/parser/ptrace.cc +++ b/parser/ptrace.cc @@ -48,7 +48,7 @@ void ptrace_rule::move_conditionals(struct cond_entry *conds) } ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): - peer_label(NULL), audit(false), deny(0) + peer_label(NULL), audit({AUDIT_UNSPECIFIED}), deny(0) { if (perms_p) { if (perms_p & ~AA_VALID_PTRACE_PERMS) @@ -64,7 +64,7 @@ ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): ostream &ptrace_rule::dump(ostream &os) { - if (audit) + if (audit.audit_mode == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -137,7 +137,7 @@ int ptrace_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & AA_VALID_PTRACE_PERMS) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit ? perms : 0, + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/ptrace.h b/parser/ptrace.h index 86383ff2f..217a0bee8 100644 --- a/parser/ptrace.h +++ b/parser/ptrace.h @@ -34,7 +34,7 @@ class ptrace_rule: public rule_t { public: char *peer_label; perms_t perms; - bool audit; + struct { audit_t audit_mode; } audit; int deny; ptrace_rule(perms_t perms, struct cond_entry *conds); diff --git a/parser/signal.cc b/parser/signal.cc index ff913fb71..84a27a758 100644 --- a/parser/signal.cc +++ b/parser/signal.cc @@ -174,7 +174,7 @@ void signal_rule::move_conditionals(struct cond_entry *conds) } signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): - signals(), peer_label(NULL), audit(false), deny(0) + signals(), peer_label(NULL), audit({AUDIT_UNSPECIFIED}), deny(0) { if (perms_p) { perms = perms_p; @@ -191,7 +191,7 @@ signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): ostream &signal_rule::dump(ostream &os) { - if (audit) + if (audit.audit_mode == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -292,7 +292,7 @@ int signal_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit ? perms : 0, + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/signal.h b/parser/signal.h index 1e7cf1ab0..26a7dab6d 100644 --- a/parser/signal.h +++ b/parser/signal.h @@ -40,7 +40,7 @@ public: Signals signals; char *peer_label; perms_t perms; - bool audit; + struct { audit_t audit_mode; } audit; int deny; signal_rule(perms_t perms, struct cond_entry *conds); diff --git a/parser/userns.cc b/parser/userns.cc index 5821e6fc3..a6fbd94f4 100644 --- a/parser/userns.cc +++ b/parser/userns.cc @@ -41,7 +41,7 @@ void userns_rule::move_conditionals(struct cond_entry *conds) } userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): - audit(false), deny(0) + audit({AUDIT_UNSPECIFIED}), deny(0) { if (perms_p) { if (perms_p & ~AA_VALID_USERNS_PERMS) @@ -59,7 +59,7 @@ userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): ostream &userns_rule::dump(ostream &os) { - if (audit) + if (audit.audit_mode == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -101,7 +101,7 @@ int userns_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & AA_VALID_USERNS_PERMS) { if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, - audit ? perms : 0, + audit.audit_mode == AUDIT_FORCE ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/userns.h b/parser/userns.h index 6308aff2f..11fd082fb 100644 --- a/parser/userns.h +++ b/parser/userns.h @@ -27,7 +27,7 @@ class userns_rule: public rule_t { void move_conditionals(struct cond_entry *conds); public: perms_t perms; - bool audit; + struct { audit_t audit_mode; } audit; int deny; userns_rule(perms_t perms, struct cond_entry *conds); From fdf5b062a980de54ab97a72a5af3e35fad303376 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Mon, 30 Aug 2021 14:31:03 -0700 Subject: [PATCH 08/25] parser: fixup audit struct to audit enum This removes the struct wrapper used in the previous patch to ensure that all uses are properly converted. Signed-off-by: John Johansen --- parser/af_rule.cc | 2 +- parser/af_rule.h | 4 ++-- parser/af_unix.cc | 16 ++++++++-------- parser/dbus.cc | 10 +++++----- parser/dbus.h | 2 +- parser/mount.cc | 22 +++++++++++----------- parser/mount.h | 2 +- parser/mqueue.cc | 12 ++++++------ parser/mqueue.h | 2 +- parser/parser.h | 2 +- parser/parser_merge.c | 4 ++-- parser/parser_misc.c | 4 ++-- parser/parser_regex.c | 8 ++++---- parser/parser_yacc.y | 41 ++++++++++++++++++++--------------------- parser/profile.h | 4 ++-- parser/ptrace.cc | 6 +++--- parser/ptrace.h | 2 +- parser/signal.cc | 6 +++--- parser/signal.h | 2 +- parser/userns.cc | 6 +++--- parser/userns.h | 2 +- 21 files changed, 79 insertions(+), 80 deletions(-) diff --git a/parser/af_rule.cc b/parser/af_rule.cc index 9c0a9d04a..c974d5ce6 100644 --- a/parser/af_rule.cc +++ b/parser/af_rule.cc @@ -92,7 +92,7 @@ int af_rule::move_base_cond(struct cond_entry *ent, bool peer) ostream &af_rule::dump_prefix(ostream &os) { - if (audit.audit_mode == AUDIT_FORCE) + if (audit == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; diff --git a/parser/af_rule.h b/parser/af_rule.h index 88b1503fc..99253a834 100644 --- a/parser/af_rule.h +++ b/parser/af_rule.h @@ -45,12 +45,12 @@ public: char *label; char *peer_label; perms_t perms; - struct { audit_t audit_mode; } audit; + audit_t audit; bool deny; af_rule(const char *name): af_name(name), sock_type(NULL), sock_type_n(-1), proto(NULL), proto_n(0), label(NULL), - peer_label(NULL), perms(0), audit({AUDIT_UNSPECIFIED}), deny(0) + peer_label(NULL), perms(0), audit(AUDIT_UNSPECIFIED), deny(0) {} virtual ~af_rule() diff --git a/parser/af_unix.cc b/parser/af_unix.cc index f586a8f67..8fbdce9af 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -105,7 +105,7 @@ unix_rule::unix_rule(unsigned int type_p, audit_t audit_p, bool denied): yyerror("socket rule: invalid socket type '%d'", type_p); } perms = AA_VALID_NET_PERMS; - audit.audit_mode = audit_p; + audit = audit_p; deny = denied; } @@ -195,7 +195,7 @@ void unix_rule::downgrade_rule(Profile &prof) { mask = 1 << sock_type_n; if (!deny) { prof.net.allow[AF_UNIX] |= mask; - if (audit.audit_mode == AUDIT_FORCE) + if (audit == AUDIT_FORCE) prof.net.audit[AF_UNIX] |= mask; } else { /* deny rules have to be dropped because the downgrade makes @@ -336,7 +336,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_CREATE), - map_perms(audit.audit_mode == AUDIT_FORCE ? AA_NET_CREATE : 0), + map_perms(audit == AUDIT_FORCE ? AA_NET_CREATE : 0), dfaflags)) goto fail; mask &= ~AA_NET_CREATE; @@ -361,7 +361,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_BIND), - map_perms(audit.audit_mode == AUDIT_FORCE ? AA_NET_BIND : 0), + map_perms(audit == AUDIT_FORCE ? AA_NET_BIND : 0), dfaflags)) goto fail; /* clear if auto, else generic need to generate addr below */ @@ -386,7 +386,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(mask & local_mask), - map_perms(audit.audit_mode == AUDIT_FORCE ? mask & local_mask : 0), + map_perms(audit == AUDIT_FORCE ? mask & local_mask : 0), dfaflags)) goto fail; } @@ -400,7 +400,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_LISTEN), - map_perms(audit.audit_mode == AUDIT_FORCE ? AA_NET_LISTEN : 0), + map_perms(audit == AUDIT_FORCE ? AA_NET_LISTEN : 0), dfaflags)) goto fail; } @@ -413,7 +413,7 @@ int unix_rule::gen_policy_re(Profile &prof) buf = tmp.str(); if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(AA_NET_OPT), - map_perms(audit.audit_mode == AUDIT_FORCE ? AA_NET_OPT : 0), + map_perms(audit == AUDIT_FORCE ? AA_NET_OPT : 0), dfaflags)) goto fail; } @@ -432,7 +432,7 @@ int unix_rule::gen_policy_re(Profile &prof) goto fail; buf = buffer.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit.audit_mode == AUDIT_FORCE ? perms & AA_PEER_NET_PERMS : 0), dfaflags)) + if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit == AUDIT_FORCE ? perms & AA_PEER_NET_PERMS : 0), dfaflags)) goto fail; } diff --git a/parser/dbus.cc b/parser/dbus.cc index 8999acda0..e597d0338 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -69,7 +69,7 @@ void dbus_rule::move_conditionals(struct cond_entry *conds) dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds): bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL), - perms(0), audit({AUDIT_UNSPECIFIED}), deny(0) + perms(0), audit(AUDIT_UNSPECIFIED), deny(0) { int name_is_subject_cond = 0, message_rule = 0, service_rule = 0; @@ -122,7 +122,7 @@ dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, ostream &dbus_rule::dump(ostream &os) { - if (audit.audit_mode == AUDIT_FORCE) + if (audit == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -279,21 +279,21 @@ int dbus_rule::gen_policy_re(Profile &prof) if (perms & AA_DBUS_BIND) { if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_BIND, - audit.audit_mode == AUDIT_FORCE ? perms & AA_DBUS_BIND : 0, + audit == AUDIT_FORCE ? perms & AA_DBUS_BIND : 0, 2, vec, dfaflags, false)) goto fail; } if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { if (!prof.policy.rules->add_rule_vec(deny, perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE), - audit.audit_mode == AUDIT_FORCE ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0, + audit == AUDIT_FORCE ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0, 6, vec, dfaflags, false)) goto fail; } if (perms & AA_DBUS_EAVESDROP) { if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_EAVESDROP, - audit.audit_mode == AUDIT_FORCE ? perms & AA_DBUS_EAVESDROP : 0, + audit == AUDIT_FORCE ? perms & AA_DBUS_EAVESDROP : 0, 1, vec, dfaflags, false)) goto fail; } diff --git a/parser/dbus.h b/parser/dbus.h index 37b83f5f9..cdd1f5cb1 100644 --- a/parser/dbus.h +++ b/parser/dbus.h @@ -40,7 +40,7 @@ public: char *interface; char *member; perms_t perms; - struct { audit_t audit_mode; } audit; + audit_t audit; int deny; dbus_rule(perms_t perms_p, struct cond_entry *conds, diff --git a/parser/mount.cc b/parser/mount.cc index 7a8cad7c9..3c2db1ecd 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -469,7 +469,7 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, perms_t perms_p): mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL), - flagsv(0), opt_flagsv(0), audit({AUDIT_UNSPECIFIED}), deny(0) + flagsv(0), opt_flagsv(0), audit(AUDIT_UNSPECIFIED), deny(0) { /* FIXME: dst_conds are ignored atm */ dev_type = extract_fstype(&src_conds); @@ -581,7 +581,7 @@ ostream &mnt_rule::dump(ostream &os) os << " -> " << trans; const char *prefix = deny ? "deny" : ""; - os << " " << prefix << "(0x" << hex << perms << "/0x" << (audit.audit_mode != AUDIT_UNSPECIFIED ? perms : 0) << ")"; + os << " " << prefix << "(0x" << hex << perms << "/0x" << (audit != AUDIT_UNSPECIFIED ? perms : 0) << ")"; os << ",\n"; return os; @@ -733,7 +733,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, } else { /* dependent on full expansion of any data match perms */ tmpperms = perms; - tmpaudit = audit.audit_mode == AUDIT_FORCE ? perms : 0; + tmpaudit = audit == AUDIT_FORCE ? perms : 0; } /* match for up to but not including data * if a data match is required this only has AA_MATCH_CONT perms @@ -751,7 +751,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, goto fail; vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - (audit.audit_mode == AUDIT_FORCE ? perms : 0), + (audit == AUDIT_FORCE ? perms : 0), 5, vec, dfaflags, false)) goto fail; count++; @@ -792,7 +792,7 @@ int mnt_rule::gen_policy_bind_mount(Profile &prof, int &count, opt_flags & MS_BIND_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, 4, vec, dfaflags, false)) goto fail; @@ -834,7 +834,7 @@ int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count, opt_flags & MS_MAKE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, 4, vec, dfaflags, false)) goto fail; @@ -877,7 +877,7 @@ int mnt_rule::gen_policy_move_mount(Profile &prof, int &count, opt_flags & MS_MOVE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, 4, vec, dfaflags, false)) goto fail; @@ -926,7 +926,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, tmpaudit = 0; } else { tmpperms = perms; - tmpaudit = audit.audit_mode == AUDIT_FORCE ? perms : 0; + tmpaudit = audit == AUDIT_FORCE ? perms : 0; } /* rule for match without required data || data MATCH_CONT */ if (!prof.policy.rules->add_rule_vec(deny, tmpperms, tmpaudit, 4, @@ -941,7 +941,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, goto fail; vec[4] = optsbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - audit.audit_mode == AUDIT_FORCE ? perms : 0, + audit == AUDIT_FORCE ? perms : 0, 5, vec, dfaflags, false)) goto fail; count++; @@ -1033,7 +1033,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[0] = mntbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - (audit.audit_mode == AUDIT_FORCE ? perms : 0), 1, vec, + (audit == AUDIT_FORCE ? perms : 0), 1, vec, dfaflags, false)) goto fail; count++; @@ -1048,7 +1048,7 @@ int mnt_rule::gen_policy_re(Profile &prof) goto fail; vec[1] = devbuf.c_str(); if (!prof.policy.rules->add_rule_vec(deny, perms, - (audit.audit_mode == AUDIT_FORCE ? perms : 0), 2, vec, + (audit == AUDIT_FORCE ? perms : 0), 2, vec, dfaflags, false)) goto fail; count++; diff --git a/parser/mount.h b/parser/mount.h index 7d73e2d32..650628544 100644 --- a/parser/mount.h +++ b/parser/mount.h @@ -144,7 +144,7 @@ public: std::vector flagsv, opt_flagsv; perms_t perms; - struct { audit_t audit_mode; } audit; + audit_t audit; int deny; mnt_rule(struct cond_entry *src_conds, char *device_p, diff --git a/parser/mqueue.cc b/parser/mqueue.cc index 1a54d1b37..5b9da33d8 100644 --- a/parser/mqueue.cc +++ b/parser/mqueue.cc @@ -87,7 +87,7 @@ void mqueue_rule::move_conditionals(struct cond_entry *conds) } mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p): - qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit({AUDIT_UNSPECIFIED}), deny(0) + qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit(AUDIT_UNSPECIFIED), deny(0) { move_conditionals(conds); free_cond_list(conds); @@ -115,7 +115,7 @@ mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_ ostream &mqueue_rule::dump(ostream &os) { - if (audit.audit_mode == AUDIT_FORCE) + if (audit == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -233,10 +233,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) /* store perms at name match so label doesn't need * to be checked */ - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false)) goto fail; } } @@ -268,10 +268,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) } if (perms & AA_VALID_SYSV_MQ_PERMS) { - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode ? perms : 0, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit.audit_mode ? perms : 0, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false)) goto fail; } } diff --git a/parser/mqueue.h b/parser/mqueue.h index b8fd38ca0..b7d827687 100644 --- a/parser/mqueue.h +++ b/parser/mqueue.h @@ -88,7 +88,7 @@ public: char *qname; char *label; perms_t perms; - struct { audit_t audit_mode; } audit; + audit_t audit; int deny; mqueue_rule(perms_t perms, struct cond_entry *conds, char *qname = NULL); diff --git a/parser/parser.h b/parser/parser.h index 6448b4a8a..07ed75b73 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -131,7 +131,7 @@ struct cod_entry { Profile *prof; /* Special profile defined * just for this executable */ perms_t perms; /* perms is 'or' of AA_* bits */ - struct { audit_t audit_mode; } audit; + audit_t audit; int deny; /* TRUE or FALSE */ int alias_ignore; /* ignore for alias processing */ diff --git a/parser/parser_merge.c b/parser/parser_merge.c index d9ce9f629..b93103aa1 100644 --- a/parser/parser_merge.c +++ b/parser/parser_merge.c @@ -51,8 +51,8 @@ static int file_comp(const void *c1, const void *c2) if ((*e1)->deny != (*e2)->deny) return (*e1)->deny < (*e2)->deny ? -1 : 1; - if ((*e1)->audit.audit_mode != (*e2)->audit.audit_mode) - return (*e1)->audit.audit_mode < (*e2)->audit.audit_mode ? -1 : 1; + if ((*e1)->audit != (*e2)->audit) + return (*e1)->audit < (*e2)->audit ? -1 : 1; return strcmp((*e1)->name, (*e2)->name); } diff --git a/parser/parser_misc.c b/parser/parser_misc.c index 1af6f996f..ee304d7d6 100644 --- a/parser/parser_misc.c +++ b/parser/parser_misc.c @@ -961,7 +961,7 @@ struct cod_entry *new_entry(char *id, perms_t perms, char *link_id) entry->name = id; entry->link_name = link_id; entry->perms = perms; - entry->audit.audit_mode = AUDIT_UNSPECIFIED; + entry->audit = AUDIT_UNSPECIFIED; entry->deny = FALSE; entry->pattern_type = ePatternInvalid; @@ -985,7 +985,7 @@ struct cod_entry *copy_cod_entry(struct cod_entry *orig) DUP_STRING(orig, entry, link_name, err); DUP_STRING(orig, entry, nt_name, err); entry->perms = orig->perms; - entry->audit.audit_mode = orig->audit.audit_mode; + entry->audit = orig->audit; entry->deny = orig->deny; /* XXX - need to create copies of the patterns, too */ diff --git a/parser/parser_regex.c b/parser/parser_regex.c index f459b80d5..9ad25eb41 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -632,12 +632,12 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) !is_change_profile_perms(entry->perms) && !dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), - entry->audit.audit_mode == AUDIT_FORCE ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0, + entry->audit == AUDIT_FORCE ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0, dfaflags)) return FALSE; } else if (!is_change_profile_perms(entry->perms)) { if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms, - entry->audit.audit_mode == AUDIT_FORCE ? entry->perms : 0, dfaflags)) + entry->audit == AUDIT_FORCE ? entry->perms : 0, dfaflags)) return FALSE; } @@ -660,7 +660,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) perms |= LINK_TO_LINK_SUBSET(perms); vec[1] = "/[^/].*"; } - if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit.audit_mode == AUDIT_FORCE ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false)) + if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit == AUDIT_FORCE ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false)) return FALSE; } if (is_change_profile_perms(entry->perms)) { @@ -671,7 +671,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) int index = 1; uint32_t onexec_perms = AA_ONEXEC; - if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit.audit_mode == AUDIT_FORCE && warn_change_profile) { + if ((warnflags & WARN_RULE_DOWNGRADED) && entry->audit == AUDIT_FORCE && warn_change_profile) { /* don't have profile name here, so until this code * gets refactored just throw out a generic warning */ diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 8cfa8eb8f..b4101f090 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -701,8 +701,7 @@ rules: rules opt_prefix rule $3->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); /* only set audit ctl quieting if the rule is not audited */ if (($2.deny && $2.audit != AUDIT_FORCE) || (!$2.deny && $2.audit == AUDIT_FORCE)) - $3->audit.audit_mode = AUDIT_FORCE; - + $3->audit = AUDIT_FORCE; add_entry_to_policy($1, $3); $$ = $1; }; @@ -732,9 +731,9 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); if ($2.audit == AUDIT_FORCE && !entry->deny) - entry->audit.audit_mode = AUDIT_FORCE; + entry->audit = AUDIT_FORCE; else if ($2.audit != AUDIT_FORCE && entry->deny) - entry->audit.audit_mode = AUDIT_FORCE; + entry->audit = AUDIT_FORCE; add_entry_to_policy($1, entry); } $4->entries = NULL; @@ -801,9 +800,9 @@ rules: rules opt_prefix mnt_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit.audit_mode = $2.audit; + $3->audit = $2.audit; } $1->rule_ents.push_back($3); @@ -818,9 +817,9 @@ rules: rules opt_prefix dbus_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit.audit_mode = $2.audit; + $3->audit = $2.audit; } $1->rule_ents.push_back($3); $$ = $1; @@ -834,9 +833,9 @@ rules: rules opt_prefix signal_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit.audit_mode = $2.audit; + $3->audit = $2.audit; } $1->rule_ents.push_back($3); $$ = $1; @@ -850,9 +849,9 @@ rules: rules opt_prefix ptrace_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit.audit_mode = $2.audit; + $3->audit = $2.audit; } $1->rule_ents.push_back($3); $$ = $1; @@ -866,9 +865,9 @@ rules: rules opt_prefix unix_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit.audit_mode = $2.audit; + $3->audit = $2.audit; } $1->rule_ents.push_back($3); $$ = $1; @@ -882,9 +881,9 @@ rules: rules opt_prefix userns_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } else if ($2.audit == AUDIT_FORCE) { - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } $1->rule_ents.push_back($3); $$ = $1; @@ -902,9 +901,9 @@ rules: rules opt_prefix change_profile $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit.audit_mode = $2.audit; + $3->audit = $2.audit; } add_entry_to_policy($1, $3); $$ = $1; @@ -937,9 +936,9 @@ rules: rules opt_prefix mqueue_rule $3->deny = 1; } else if ($2.deny) { $3->deny = 1; - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } else if ($2.audit == AUDIT_FORCE) { - $3->audit.audit_mode = AUDIT_FORCE; + $3->audit = AUDIT_FORCE; } $1->rule_ents.push_back($3); $$ = $1; @@ -1822,7 +1821,7 @@ void add_local_entry(Profile *prof) sprintf(name, "%s//%s", prof->parent->name, prof->name); entry = new_entry(name, prof->local_perms, NULL); - entry->audit.audit_mode = prof->local_audit.audit_mode; + entry->audit = prof->local_audit; entry->nt_name = trans; if (!entry) yyerror(_("Memory allocation error.")); diff --git a/parser/profile.h b/parser/profile.h index 9e8c0f3c9..bf9ca2308 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -191,7 +191,7 @@ public: /* int default_deny; */ /* TRUE or FALSE */ int local; perms_t local_perms; - struct { audit_t audit_mode; } local_audit; + audit_t local_audit; Profile *parent; @@ -223,7 +223,7 @@ public: local_perms = 0; local = 0; - local_audit.audit_mode = AUDIT_UNSPECIFIED; + local_audit = AUDIT_UNSPECIFIED; parent = NULL; diff --git a/parser/ptrace.cc b/parser/ptrace.cc index 2875f1088..fda719705 100644 --- a/parser/ptrace.cc +++ b/parser/ptrace.cc @@ -48,7 +48,7 @@ void ptrace_rule::move_conditionals(struct cond_entry *conds) } ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): - peer_label(NULL), audit({AUDIT_UNSPECIFIED}), deny(0) + peer_label(NULL), audit(AUDIT_UNSPECIFIED), deny(0) { if (perms_p) { if (perms_p & ~AA_VALID_PTRACE_PERMS) @@ -64,7 +64,7 @@ ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): ostream &ptrace_rule::dump(ostream &os) { - if (audit.audit_mode == AUDIT_FORCE) + if (audit == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -137,7 +137,7 @@ int ptrace_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & AA_VALID_PTRACE_PERMS) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit == AUDIT_FORCE ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/ptrace.h b/parser/ptrace.h index 217a0bee8..2f54b0fd5 100644 --- a/parser/ptrace.h +++ b/parser/ptrace.h @@ -34,7 +34,7 @@ class ptrace_rule: public rule_t { public: char *peer_label; perms_t perms; - struct { audit_t audit_mode; } audit; + audit_t audit; int deny; ptrace_rule(perms_t perms, struct cond_entry *conds); diff --git a/parser/signal.cc b/parser/signal.cc index 84a27a758..0799ff5d4 100644 --- a/parser/signal.cc +++ b/parser/signal.cc @@ -174,7 +174,7 @@ void signal_rule::move_conditionals(struct cond_entry *conds) } signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): - signals(), peer_label(NULL), audit({AUDIT_UNSPECIFIED}), deny(0) + signals(), peer_label(NULL), audit(AUDIT_UNSPECIFIED), deny(0) { if (perms_p) { perms = perms_p; @@ -191,7 +191,7 @@ signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): ostream &signal_rule::dump(ostream &os) { - if (audit.audit_mode == AUDIT_FORCE) + if (audit == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -292,7 +292,7 @@ int signal_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit.audit_mode == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit == AUDIT_FORCE ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/signal.h b/parser/signal.h index 26a7dab6d..8e3526d89 100644 --- a/parser/signal.h +++ b/parser/signal.h @@ -40,7 +40,7 @@ public: Signals signals; char *peer_label; perms_t perms; - struct { audit_t audit_mode; } audit; + audit_t audit; int deny; signal_rule(perms_t perms, struct cond_entry *conds); diff --git a/parser/userns.cc b/parser/userns.cc index a6fbd94f4..e8b3b5320 100644 --- a/parser/userns.cc +++ b/parser/userns.cc @@ -41,7 +41,7 @@ void userns_rule::move_conditionals(struct cond_entry *conds) } userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): - audit({AUDIT_UNSPECIFIED}), deny(0) + audit(AUDIT_UNSPECIFIED), deny(0) { if (perms_p) { if (perms_p & ~AA_VALID_USERNS_PERMS) @@ -59,7 +59,7 @@ userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): ostream &userns_rule::dump(ostream &os) { - if (audit.audit_mode == AUDIT_FORCE) + if (audit == AUDIT_FORCE) os << "audit "; if (deny) os << "deny "; @@ -101,7 +101,7 @@ int userns_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & AA_VALID_USERNS_PERMS) { if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, - audit.audit_mode == AUDIT_FORCE ? perms : 0, + audit == AUDIT_FORCE ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/userns.h b/parser/userns.h index 11fd082fb..d7776dc5b 100644 --- a/parser/userns.h +++ b/parser/userns.h @@ -27,7 +27,7 @@ class userns_rule: public rule_t { void move_conditionals(struct cond_entry *conds); public: perms_t perms; - struct { audit_t audit_mode; } audit; + audit_t audit; int deny; userns_rule(perms_t perms, struct cond_entry *conds); From d3714585335916e92da2886f0af3d2bb608a35fe Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 4 Sep 2021 03:28:18 -0700 Subject: [PATCH 09/25] parser: make base classes for rules using prefixes and perms and use them Cleanup the parse code by making shared prefix and perms classes for rules and convert rules to use them. Signed-off-by: John Johansen --- parser/af_rule.cc | 11 +---- parser/af_rule.h | 8 +--- parser/af_unix.h | 7 +++ parser/dbus.cc | 9 ++-- parser/dbus.h | 12 +++-- parser/mount.cc | 8 ++-- parser/mount.h | 12 +++-- parser/mqueue.cc | 7 +-- parser/mqueue.h | 13 +++-- parser/parser.h | 10 +--- parser/parser_yacc.y | 92 +++++++++--------------------------- parser/ptrace.cc | 8 ++-- parser/ptrace.h | 13 +++-- parser/rule.h | 110 +++++++++++++++++++++++++++++++++++++++++++ parser/signal.cc | 7 +-- parser/signal.h | 12 +++-- parser/userns.cc | 8 +--- parser/userns.h | 12 +++-- 18 files changed, 209 insertions(+), 150 deletions(-) diff --git a/parser/af_rule.cc b/parser/af_rule.cc index c974d5ce6..770b56e54 100644 --- a/parser/af_rule.cc +++ b/parser/af_rule.cc @@ -90,15 +90,6 @@ int af_rule::move_base_cond(struct cond_entry *ent, bool peer) return true; } -ostream &af_rule::dump_prefix(ostream &os) -{ - if (audit == AUDIT_FORCE) - os << "audit "; - if (deny) - os << "deny "; - return os; -} - ostream &af_rule::dump_local(ostream &os) { if (perms != AA_VALID_NET_PERMS) { @@ -148,7 +139,7 @@ ostream &af_rule::dump_peer(ostream &os) ostream &af_rule::dump(ostream &os) { - dump_prefix(os); + prefix_rule_t::dump(os); os << af_name; dump_local(os); if (has_peer_conds()) { diff --git a/parser/af_rule.h b/parser/af_rule.h index 99253a834..422bc6b69 100644 --- a/parser/af_rule.h +++ b/parser/af_rule.h @@ -35,7 +35,7 @@ struct supported_cond { enum cond_side side ; }; -class af_rule: public rule_t { +class af_rule: public perms_rule_t { public: std::string af_name; char *sock_type; @@ -44,13 +44,10 @@ public: int proto_n; char *label; char *peer_label; - perms_t perms; - audit_t audit; - bool deny; af_rule(const char *name): af_name(name), sock_type(NULL), sock_type_n(-1), proto(NULL), proto_n(0), label(NULL), - peer_label(NULL), perms(0), audit(AUDIT_UNSPECIFIED), deny(0) + peer_label(NULL) {} virtual ~af_rule() @@ -66,7 +63,6 @@ public: int move_base_cond(struct cond_entry *conds, bool peer); virtual bool has_peer_conds(void) { return peer_label ? true : false; } - virtual ostream &dump_prefix(ostream &os); virtual ostream &dump_local(ostream &os); virtual ostream &dump_peer(ostream &os); virtual ostream &dump(ostream &os); diff --git a/parser/af_unix.h b/parser/af_unix.h index 26615d26c..861b25ecc 100644 --- a/parser/af_unix.h +++ b/parser/af_unix.h @@ -46,6 +46,13 @@ public: free(peer_addr); }; + virtual bool valid_prefix(prefixes &p, const char *&error) { + if (p.owner) { + error = "owner prefix not allowed on unix rules"; + return false; + } + return true; + }; virtual bool has_peer_conds(void) { return af_rule::has_peer_conds() || peer_addr; } diff --git a/parser/dbus.cc b/parser/dbus.cc index e597d0338..bcd4536df 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -68,8 +68,7 @@ void dbus_rule::move_conditionals(struct cond_entry *conds) dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds): - bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL), - perms(0), audit(AUDIT_UNSPECIFIED), deny(0) + bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL) { int name_is_subject_cond = 0, message_rule = 0, service_rule = 0; @@ -122,13 +121,11 @@ dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, ostream &dbus_rule::dump(ostream &os) { - if (audit == AUDIT_FORCE) - os << "audit "; - if (deny) - os << "deny "; + prefix_rule_t::dump(os); os << "dbus ( "; + /* override default perms */ if (perms & AA_DBUS_SEND) os << "send "; if (perms & AA_DBUS_RECEIVE) diff --git a/parser/dbus.h b/parser/dbus.h index cdd1f5cb1..f8da1d07d 100644 --- a/parser/dbus.h +++ b/parser/dbus.h @@ -25,7 +25,7 @@ extern int parse_dbus_perms(const char *str_mode, perms_t *mode, int fail); -class dbus_rule: public rule_t { +class dbus_rule: public perms_rule_t { void move_conditionals(struct cond_entry *conds); public: char *bus; @@ -39,9 +39,6 @@ public: char *path; char *interface; char *member; - perms_t perms; - audit_t audit; - int deny; dbus_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds); @@ -53,6 +50,13 @@ public: free(interface); free(member); }; + virtual bool valid_prefix(prefixes &p, const char *&error) { + if (p.owner) { + error = "owner prefix not allowed on dbus rules"; + return false; + } + return true; + }; virtual ostream &dump(ostream &os); virtual int expand_variables(void); diff --git a/parser/mount.cc b/parser/mount.cc index 3c2db1ecd..66b2bdc0d 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -469,7 +469,7 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, perms_t perms_p): mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL), - flagsv(0), opt_flagsv(0), audit(AUDIT_UNSPECIFIED), deny(0) + flagsv(0), opt_flagsv(0) { /* FIXME: dst_conds are ignored atm */ dev_type = extract_fstype(&src_conds); @@ -551,6 +551,8 @@ mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, ostream &mnt_rule::dump(ostream &os) { + prefix_rule_t::dump(os); + if (perms & AA_MAY_MOUNT) os << "mount"; else if (perms & AA_MAY_UMOUNT) @@ -580,8 +582,8 @@ ostream &mnt_rule::dump(ostream &os) if (trans) os << " -> " << trans; - const char *prefix = deny ? "deny" : ""; - os << " " << prefix << "(0x" << hex << perms << "/0x" << (audit != AUDIT_UNSPECIFIED ? perms : 0) << ")"; + + os << " " << "(0x" << hex << perms << "/0x" << (audit != AUDIT_UNSPECIFIED ? perms : 0) << ")"; os << ",\n"; return os; diff --git a/parser/mount.h b/parser/mount.h index 650628544..4eecee8eb 100644 --- a/parser/mount.h +++ b/parser/mount.h @@ -120,7 +120,7 @@ * remapped to a mount option*/ -class mnt_rule: public rule_t { +class mnt_rule: public perms_rule_t { int gen_policy_remount(Profile &prof, int &count, unsigned int flags, unsigned int opt_flags); int gen_policy_bind_mount(Profile &prof, int &count, unsigned int flags, @@ -143,9 +143,6 @@ public: std::vector flagsv, opt_flagsv; - perms_t perms; - audit_t audit; - int deny; mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, @@ -159,6 +156,13 @@ public: free(trans); } + virtual bool valid_prefix(prefixes &p, const char *&error) { + if (p.owner) { + error = "owner prefix not allowed on mount rules"; + return false; + } + return true; + }; virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); diff --git a/parser/mqueue.cc b/parser/mqueue.cc index 5b9da33d8..47273580f 100644 --- a/parser/mqueue.cc +++ b/parser/mqueue.cc @@ -87,7 +87,7 @@ void mqueue_rule::move_conditionals(struct cond_entry *conds) } mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p): - qtype(mqueue_unspecified), qname(qname_p), label(NULL), audit(AUDIT_UNSPECIFIED), deny(0) + qtype(mqueue_unspecified), qname(qname_p), label(NULL) { move_conditionals(conds); free_cond_list(conds); @@ -115,10 +115,7 @@ mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_ ostream &mqueue_rule::dump(ostream &os) { - if (audit == AUDIT_FORCE) - os << "audit "; - if (deny) - os << "deny "; + prefix_rule_t::dump(os); os << "mqueue "; diff --git a/parser/mqueue.h b/parser/mqueue.h index b7d827687..e9f0a4721 100644 --- a/parser/mqueue.h +++ b/parser/mqueue.h @@ -81,15 +81,12 @@ typedef enum mqueue_type { int parse_mqueue_perms(const char *str_perms, perms_t *perms, int fail); -class mqueue_rule: public rule_t { +class mqueue_rule: public perms_rule_t { void move_conditionals(struct cond_entry *conds); public: mqueue_type qtype; char *qname; char *label; - perms_t perms; - audit_t audit; - int deny; mqueue_rule(perms_t perms, struct cond_entry *conds, char *qname = NULL); virtual ~mqueue_rule() @@ -98,6 +95,14 @@ public: free(label); }; + virtual bool valid_prefix(prefixes &p, const char *&error) { + // not yet, but soon + if (p.owner) { + error = _("owner prefix not allowed on mqueue rules"); + return false; + } + return true; + }; virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); diff --git a/parser/parser.h b/parser/parser.h index 07ed75b73..a638d9a93 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -36,17 +36,14 @@ #include "immunix.h" #include "libapparmor_re/apparmor_re.h" #include "libapparmor_re/aare_rules.h" +#include "rule.h" #include using namespace std; #include -class Profile; -class rule_t; -typedef uint32_t perms_t; -typedef enum { AUDIT_UNSPECIFIED, AUDIT_FORCE, AUDIT_QUIET } audit_t; #define MODULE_NAME "apparmor" @@ -91,11 +88,6 @@ extern dfaflags_t werrflags; typedef enum pattern_t pattern_t; -struct prefixes { - audit_t audit; - int deny; - int owner; -}; struct cod_pattern { char *regex; // posix regex diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index b4101f090..7b71c8845 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -794,97 +794,54 @@ rules: rules opt_prefix network_rule rules: rules opt_prefix mnt_rule { - if ($2.owner) - yyerror(_("owner prefix not allowed on mount rules")); - if ($2.deny && $2.audit == AUDIT_FORCE) { - $3->deny = 1; - } else if ($2.deny) { - $3->deny = 1; - $3->audit = AUDIT_FORCE; - } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit = $2.audit; - } - + const char *error; + if (!$3->add_prefix($2, error)) + yyerror(error); $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix dbus_rule { - if ($2.owner) - yyerror(_("owner prefix not allowed on dbus rules")); - if ($2.deny && $2.audit == AUDIT_FORCE) { - $3->deny = 1; - } else if ($2.deny) { - $3->deny = 1; - $3->audit = AUDIT_FORCE; - } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit = $2.audit; - } + const char *error; + if (!$3->add_prefix($2, error)) + yyerror(error); $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix signal_rule { - if ($2.owner) - yyerror(_("owner prefix not allowed on signal rules")); - if ($2.deny && $2.audit == AUDIT_FORCE) { - $3->deny = 1; - } else if ($2.deny) { - $3->deny = 1; - $3->audit = AUDIT_FORCE; - } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit = $2.audit; - } + const char *error; + if (!$3->add_prefix($2, error)) + yyerror(error); $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix ptrace_rule { - if ($2.owner) - yyerror(_("owner prefix not allowed on ptrace rules")); - if ($2.deny && $2.audit == AUDIT_FORCE) { - $3->deny = 1; - } else if ($2.deny) { - $3->deny = 1; - $3->audit = AUDIT_FORCE; - } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit = $2.audit; - } + const char *error; + if (!$3->add_prefix($2, error)) + yyerror(error); $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix unix_rule { - if ($2.owner) - yyerror(_("owner prefix not allowed on unix rules")); - if ($2.deny && $2.audit == AUDIT_FORCE) { - $3->deny = 1; - } else if ($2.deny) { - $3->deny = 1; - $3->audit = AUDIT_FORCE; - } else if ($2.audit != AUDIT_UNSPECIFIED) { - $3->audit = $2.audit; - } + const char *error; + if (!$3->add_prefix($2, error)) + yyerror(error); $1->rule_ents.push_back($3); $$ = $1; } rules: rules opt_prefix userns_rule { - if ($2.owner) - yyerror(_("owner prefix not allowed on userns rules")); - if ($2.deny && $2.audit) { - $3->deny = 1; - } else if ($2.deny) { - $3->deny = 1; - $3->audit = AUDIT_FORCE; - } else if ($2.audit == AUDIT_FORCE) { - $3->audit = AUDIT_FORCE; - } + const char *error; + if (!$3->add_prefix($2, error)) + yyerror(error); $1->rule_ents.push_back($3); $$ = $1; } @@ -930,16 +887,9 @@ rules: rules opt_prefix capability rules: rules opt_prefix mqueue_rule { - if ($2.owner) - yyerror(_("owner prefix not allowed on mqueue rules")); //is this true? - if ($2.deny && $2.audit) { - $3->deny = 1; - } else if ($2.deny) { - $3->deny = 1; - $3->audit = AUDIT_FORCE; - } else if ($2.audit == AUDIT_FORCE) { - $3->audit = AUDIT_FORCE; - } + const char *error; + if (!$3->add_prefix($2, error)) + yyerror(error); $1->rule_ents.push_back($3); $$ = $1; }; diff --git a/parser/ptrace.cc b/parser/ptrace.cc index fda719705..9459ab3c5 100644 --- a/parser/ptrace.cc +++ b/parser/ptrace.cc @@ -48,7 +48,7 @@ void ptrace_rule::move_conditionals(struct cond_entry *conds) } ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): - peer_label(NULL), audit(AUDIT_UNSPECIFIED), deny(0) + peer_label(NULL) { if (perms_p) { if (perms_p & ~AA_VALID_PTRACE_PERMS) @@ -64,13 +64,11 @@ ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): ostream &ptrace_rule::dump(ostream &os) { - if (audit == AUDIT_FORCE) - os << "audit "; - if (deny) - os << "deny "; + prefix_rule_t::dump(os); os << "ptrace"; + /* override default perm dump */ if (perms != AA_VALID_PTRACE_PERMS) { os << " ("; diff --git a/parser/ptrace.h b/parser/ptrace.h index 2f54b0fd5..dbe1eb308 100644 --- a/parser/ptrace.h +++ b/parser/ptrace.h @@ -29,13 +29,10 @@ int parse_ptrace_perms(const char *str_perms, perms_t *perms, int fail); -class ptrace_rule: public rule_t { +class ptrace_rule: public perms_rule_t { void move_conditionals(struct cond_entry *conds); public: char *peer_label; - perms_t perms; - audit_t audit; - int deny; ptrace_rule(perms_t perms, struct cond_entry *conds); virtual ~ptrace_rule() @@ -48,6 +45,14 @@ public: virtual int gen_policy_re(Profile &prof); virtual void post_process(Profile &prof unused) { }; + virtual bool valid_prefix(prefixes &p, const char *&error) { + if (p.owner) { + error = "owner prefix not allowed on ptrace rules"; + return false; + } + return true; + }; + protected: virtual void warn_once(const char *name) override; }; diff --git a/parser/rule.h b/parser/rule.h index 73e0175af..ad307c66f 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -23,6 +23,8 @@ #include "policydb.h" +using namespace std; + class Profile; #define RULE_NOT_SUPPORTED 0 @@ -51,5 +53,113 @@ std::ostream &operator<<(std::ostream &os, rule_t &rule); typedef std::list RuleList; +/* Not classes so they can be used in the bison front end */ +typedef uint32_t perms_t; +typedef enum { AUDIT_UNSPECIFIED, AUDIT_FORCE, AUDIT_QUIET } audit_t; + +/* NOTE: we can not have a constructor for class prefixes. This is + * because it will break bison, and we would need to transition to + * the C++ bison bindings. Instead get around this by using a + * special rule class that inherits prefixes and handles the + * contruction + */ +class prefixes { +public: + audit_t audit; + int deny; + int owner; + + ostream &dump(ostream &os) + { + bool output = true; + + switch (audit) { + case AUDIT_FORCE: + os << "audit"; + break; + case AUDIT_QUIET: + os << "quiet"; + break; + default: + output = false; + } + + if (deny) { + if (output) + os << " "; + + os << "deny"; + output = true; + } + + if (owner) { + if (output) + os << " "; + os << "owner"; + output = true; + } + + if (output) + os << " "; + + return os; + } +}; + +class prefix_rule_t: public rule_t, public prefixes { +public: + prefix_rule_t() + { + /* Must construct prefix here see note on prefixes */ + audit = AUDIT_UNSPECIFIED; + deny = 0; + owner = 0; + }; + + virtual bool valid_prefix(prefixes &p, const char *&error) = 0; + + virtual bool add_prefix(prefixes &p, const char *&error) { + if (!valid_prefix(p, error)) + return false; + if (p.audit != AUDIT_UNSPECIFIED && audit != p.audit) { + if (audit != AUDIT_UNSPECIFIED) { + error = "conflicting audit prefix"; + return false; + } + } + if (p.deny && p.audit == AUDIT_FORCE) { + deny = 1; + } else if (p.deny) { + deny = 1; + audit = AUDIT_FORCE; + } else if (p.audit != AUDIT_UNSPECIFIED) { + audit = p.audit; + } + owner = p.owner; + return true; + } + + virtual ostream &dump(ostream &os) { + prefixes::dump(os); + + return os; + } + +}; + +class perms_rule_t: public prefix_rule_t { +public: + perms_rule_t(): perms(0) { }; + + /* defaut perms, override/mask off if none default used */ + virtual ostream &dump(ostream &os) { + + return os; + } + + perms_t perms; + +}; + #endif /* __AA_RULE_H */ diff --git a/parser/signal.cc b/parser/signal.cc index 0799ff5d4..461309be5 100644 --- a/parser/signal.cc +++ b/parser/signal.cc @@ -174,7 +174,7 @@ void signal_rule::move_conditionals(struct cond_entry *conds) } signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): - signals(), peer_label(NULL), audit(AUDIT_UNSPECIFIED), deny(0) + signals(), peer_label(NULL) { if (perms_p) { perms = perms_p; @@ -191,10 +191,7 @@ signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): ostream &signal_rule::dump(ostream &os) { - if (audit == AUDIT_FORCE) - os << "audit "; - if (deny) - os << "deny "; + prefix_rule_t::dump(os); os << "signal"; diff --git a/parser/signal.h b/parser/signal.h index 8e3526d89..b6ca7c9ee 100644 --- a/parser/signal.h +++ b/parser/signal.h @@ -33,21 +33,25 @@ typedef set Signals; int parse_signal_perms(const char *str_perms, perms_t *perms, int fail); -class signal_rule: public rule_t { +class signal_rule: public perms_rule_t { void extract_sigs(struct value_list **list); void move_conditionals(struct cond_entry *conds); public: Signals signals; char *peer_label; - perms_t perms; - audit_t audit; - int deny; signal_rule(perms_t perms, struct cond_entry *conds); virtual ~signal_rule() { signals.clear(); free(peer_label); }; + virtual bool valid_prefix(prefixes &p, const char *&error) { + if (p.owner) { + error = "owner prefix not allowed on signal rules"; + return false; + } + return true; + }; virtual ostream &dump(ostream &os); virtual int expand_variables(void); diff --git a/parser/userns.cc b/parser/userns.cc index e8b3b5320..84f0fe31d 100644 --- a/parser/userns.cc +++ b/parser/userns.cc @@ -40,8 +40,7 @@ void userns_rule::move_conditionals(struct cond_entry *conds) } } -userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): - audit(AUDIT_UNSPECIFIED), deny(0) +userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds) { if (perms_p) { if (perms_p & ~AA_VALID_USERNS_PERMS) @@ -59,10 +58,7 @@ userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): ostream &userns_rule::dump(ostream &os) { - if (audit == AUDIT_FORCE) - os << "audit "; - if (deny) - os << "deny "; + prefix_rule_t::dump(os); os << "userns "; diff --git a/parser/userns.h b/parser/userns.h index d7776dc5b..fb60f3d3c 100644 --- a/parser/userns.h +++ b/parser/userns.h @@ -23,18 +23,22 @@ #define AA_USERNS_CREATE 8 #define AA_VALID_USERNS_PERMS (AA_USERNS_CREATE) -class userns_rule: public rule_t { +class userns_rule: public perms_rule_t { void move_conditionals(struct cond_entry *conds); public: - perms_t perms; - audit_t audit; - int deny; userns_rule(perms_t perms, struct cond_entry *conds); virtual ~userns_rule() { }; + virtual bool valid_prefix(prefixes &p, const char *&error) { + if (p.owner) { + error = _("owner prefix not allowed on userns rules"); + return false; + } + return true; + }; virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); From 28ae20983b69728a7a21a8c6d5945dc57faa077e Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 4 Sep 2021 03:46:23 -0700 Subject: [PATCH 10/25] parser: further reduce duplication of prefix rule parsing The previous patch enable the prefix based rules all to use the same code pattern. Group them together Signed-off-by: John Johansen --- parser/parser_yacc.y | 64 +++++++------------------------------------- parser/userns.h | 1 - 2 files changed, 10 insertions(+), 55 deletions(-) diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 7b71c8845..a19868e97 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -200,6 +200,7 @@ void add_local_entry(Profile *prof); unix_rule *unix_entry; userns_rule *userns_entry; mqueue_rule *mqueue_entry; + prefix_rule_t *prefix_entry; flagvals flags; perms_t fperms; @@ -264,6 +265,7 @@ void add_local_entry(Profile *prof); %type dbus_perms %type opt_dbus_perm %type dbus_rule +%type prefix_rule %type signal_perm %type signal_perms %type opt_signal_perm @@ -792,52 +794,15 @@ rules: rules opt_prefix network_rule $$ = $1; } -rules: rules opt_prefix mnt_rule - { - const char *error; - if (!$3->add_prefix($2, error)) - yyerror(error); - $1->rule_ents.push_back($3); - $$ = $1; - } +prefix_rule : mnt_rule { $$ = $1; } + | dbus_rule { $$ = $1; } + | signal_rule { $$ = $1; } + | ptrace_rule { $$ = $1; } + | unix_rule { $$ = $1; } + | userns_rule { $$ = $1; } + | mqueue_rule { $$ = $1; } -rules: rules opt_prefix dbus_rule - { - const char *error; - if (!$3->add_prefix($2, error)) - yyerror(error); - $1->rule_ents.push_back($3); - $$ = $1; - } - -rules: rules opt_prefix signal_rule - { - const char *error; - if (!$3->add_prefix($2, error)) - yyerror(error); - $1->rule_ents.push_back($3); - $$ = $1; - } - -rules: rules opt_prefix ptrace_rule - { - const char *error; - if (!$3->add_prefix($2, error)) - yyerror(error); - $1->rule_ents.push_back($3); - $$ = $1; - } - -rules: rules opt_prefix unix_rule - { - const char *error; - if (!$3->add_prefix($2, error)) - yyerror(error); - $1->rule_ents.push_back($3); - $$ = $1; - } - -rules: rules opt_prefix userns_rule +rules: rules opt_prefix prefix_rule { const char *error; if (!$3->add_prefix($2, error)) @@ -885,15 +850,6 @@ rules: rules opt_prefix capability $$ = $1; }; -rules: rules opt_prefix mqueue_rule - { - const char *error; - if (!$3->add_prefix($2, error)) - yyerror(error); - $1->rule_ents.push_back($3); - $$ = $1; - }; - rules: rules hat { PDEBUG("Matched: hat rule\n"); diff --git a/parser/userns.h b/parser/userns.h index fb60f3d3c..0333e9cac 100644 --- a/parser/userns.h +++ b/parser/userns.h @@ -26,7 +26,6 @@ class userns_rule: public perms_rule_t { void move_conditionals(struct cond_entry *conds); public: - userns_rule(perms_t perms, struct cond_entry *conds); virtual ~userns_rule() { From 10a75c431fd5aa16f493d38ea79ccc58e9254677 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 8 Sep 2021 00:25:28 -0700 Subject: [PATCH 11/25] parser: rename post_process() method and move code around The post_process() method is misnamed, it fires when the profile is finished parsing but fires before variable expansion. Rename it to better reflect what it does and move the trigger code into profile as a start of cleaning this stage up. Also document the order the hooks fire in Signed-off-by: John Johansen --- parser/af_rule.h | 1 - parser/af_unix.h | 1 - parser/dbus.h | 1 - parser/mount.cc | 2 +- parser/mount.h | 2 +- parser/mqueue.h | 1 - parser/parser.h | 2 - parser/parser_policy.c | 189 +------------------------------------- parser/parser_yacc.y | 3 +- parser/profile.cc | 201 +++++++++++++++++++++++++++++++++++++++++ parser/profile.h | 3 + parser/ptrace.h | 1 - parser/rule.h | 16 +++- parser/signal.h | 1 - parser/userns.h | 1 - 15 files changed, 223 insertions(+), 202 deletions(-) diff --git a/parser/af_rule.h b/parser/af_rule.h index 422bc6b69..5e845b2c1 100644 --- a/parser/af_rule.h +++ b/parser/af_rule.h @@ -68,7 +68,6 @@ public: virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof) = 0; - virtual void post_process(Profile &prof unused) { }; }; #endif /* __AA_AF_RULE_H */ diff --git a/parser/af_unix.h b/parser/af_unix.h index 861b25ecc..2ad6e9e84 100644 --- a/parser/af_unix.h +++ b/parser/af_unix.h @@ -61,7 +61,6 @@ public: virtual ostream &dump_peer(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); - virtual void post_process(Profile &prof unused) { }; protected: virtual void warn_once(const char *name) override; diff --git a/parser/dbus.h b/parser/dbus.h index f8da1d07d..a564ef8ae 100644 --- a/parser/dbus.h +++ b/parser/dbus.h @@ -61,7 +61,6 @@ public: virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); - virtual void post_process(Profile &prof unused) { }; protected: virtual void warn_once(const char *name) override; diff --git a/parser/mount.cc b/parser/mount.cc index 66b2bdc0d..7e0b76823 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -1067,7 +1067,7 @@ fail: return RULE_ERROR; } -void mnt_rule::post_process(Profile &prof) +void mnt_rule::post_parse_profile(Profile &prof) { if (trans) { perms_t perms = 0; diff --git a/parser/mount.h b/parser/mount.h index 4eecee8eb..86cd1d99d 100644 --- a/parser/mount.h +++ b/parser/mount.h @@ -166,7 +166,7 @@ public: virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); - virtual void post_process(Profile &prof unused); + virtual void post_parse_profile(Profile &prof unused); protected: virtual void warn_once(const char *name) override; diff --git a/parser/mqueue.h b/parser/mqueue.h index e9f0a4721..b26a988a7 100644 --- a/parser/mqueue.h +++ b/parser/mqueue.h @@ -106,7 +106,6 @@ public: virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); - virtual void post_process(Profile &prof unused) { }; protected: virtual void warn_once(const char *name) override; diff --git a/parser/parser.h b/parser/parser.h index a638d9a93..55ef2e500 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -499,8 +499,6 @@ extern void add_to_list(Profile *profile); extern void add_hat_to_policy(Profile *policy, Profile *hat); extern int add_entry_to_x_table(Profile *prof, char *name); extern void add_entry_to_policy(Profile *policy, struct cod_entry *entry); -extern void post_process_file_entries(Profile *prof); -extern void post_process_rule_entries(Profile *prof); extern int post_process_policy(int debug_only); extern int process_profile_regex(Profile *prof); extern int process_profile_variables(Profile *prof); diff --git a/parser/parser_policy.c b/parser/parser_policy.c index cbf17677c..c57dda8af 100644 --- a/parser/parser_policy.c +++ b/parser/parser_policy.c @@ -70,188 +70,6 @@ void add_hat_to_policy(Profile *prof, Profile *hat) } } -int add_entry_to_x_table(Profile *prof, char *name) -{ - int i; - for (i = (AA_EXEC_LOCAL >> 10) + 1; i < AA_EXEC_COUNT; i++) { - if (!prof->exec_table[i]) { - prof->exec_table[i] = name; - return i; - } else if (strcmp(prof->exec_table[i], name) == 0) { - /* name already in table */ - free(name); - return i; - } - } - free(name); - return 0; -} - -static int add_named_transition(Profile *prof, struct cod_entry *entry) -{ - char *name = NULL; - - /* check to see if it is a local transition */ - if (!label_contains_ns(entry->nt_name)) { - char *sub = strstr(entry->nt_name, "//"); - /* does the subprofile name match the rule */ - - if (sub && strncmp(prof->name, sub, sub - entry->nt_name) && - strcmp(sub + 2, entry->name) == 0) { - free(entry->nt_name); - entry->nt_name = NULL; - return AA_EXEC_LOCAL >> 10; - } else if (((entry->perms & AA_USER_EXEC_MODIFIERS) == - SHIFT_PERMS(AA_EXEC_LOCAL, AA_USER_SHIFT)) || - ((entry->perms & AA_OTHER_EXEC_MODIFIERS) == - SHIFT_PERMS(AA_EXEC_LOCAL, AA_OTHER_SHIFT))) { - if (strcmp(entry->nt_name, entry->name) == 0) { - free(entry->nt_name); - entry->nt_name = NULL; - return AA_EXEC_LOCAL >> 10; - } - /* specified as cix so profile name is implicit */ - name = (char *) malloc(strlen(prof->name) + strlen(entry->nt_name) - + 3); - if (!name) { - PERROR("Memory allocation error\n"); - exit(1); - } - sprintf(name, "%s//%s", prof->name, entry->nt_name); - free(entry->nt_name); - entry->nt_name = NULL; - } else { - /** - * pass control of the memory pointed to by nt_name - * from entry to add_entry_to_x_table() - */ - name = entry->nt_name; - entry->nt_name = NULL; - } - } else { - /** - * pass control of the memory pointed to by nt_name - * from entry to add_entry_to_x_table() - */ - name = entry->nt_name; - entry->nt_name = NULL; - } - - return add_entry_to_x_table(prof, name); -} - -void add_entry_to_policy(Profile *prof, struct cod_entry *entry) -{ - entry->next = prof->entries; - prof->entries = entry; -} - -static bool add_proc_access(Profile *prof, const char *rule) -{ - /* FIXME: should use @{PROC}/@{PID}/attr/{apparmor/,}{current,exec} */ - struct cod_entry *new_ent; - /* allow probe for new interfaces */ - char *buffer = strdup("/proc/*/attr/apparmor/"); - if (!buffer) { - PERROR("Memory allocation error\n"); - return FALSE; - } - new_ent = new_entry(buffer, AA_MAY_READ, NULL); - if (!new_ent) { - free(buffer); - PERROR("Memory allocation error\n"); - return FALSE; - } - add_entry_to_policy(prof, new_ent); - - /* allow probe if apparmor is enabled for the old interface */ - buffer = strdup("/sys/module/apparmor/parameters/enabled"); - if (!buffer) { - PERROR("Memory allocation error\n"); - return FALSE; - } - new_ent = new_entry(buffer, AA_MAY_READ, NULL); - if (!new_ent) { - free(buffer); - PERROR("Memory allocation error\n"); - return FALSE; - } - add_entry_to_policy(prof, new_ent); - - /* allow setting on new and old interfaces */ - buffer = strdup(rule); - if (!buffer) { - PERROR("Memory allocation error\n"); - return FALSE; - } - new_ent = new_entry(buffer, AA_MAY_WRITE, NULL); - if (!new_ent) { - free(buffer); - PERROR("Memory allocation error\n"); - return FALSE; - } - add_entry_to_policy(prof, new_ent); - - return TRUE; -} - -#define CHANGEPROFILE_PATH "/proc/*/attr/{apparmor/,}{current,exec}" -void post_process_file_entries(Profile *prof) -{ - struct cod_entry *entry; - perms_t cp_perms = 0; - - list_for_each(prof->entries, entry) { - if (entry->nt_name) { - perms_t perms = 0; - int n = add_named_transition(prof, entry); - if (!n) { - PERROR("Profile %s has too many specified profile transitions.\n", prof->name); - exit(1); - } - if (entry->perms & AA_USER_EXEC) - perms |= SHIFT_PERMS(n << 10, AA_USER_SHIFT); - if (entry->perms & AA_OTHER_EXEC) - perms |= SHIFT_PERMS(n << 10, AA_OTHER_SHIFT); - entry->perms = ((entry->perms & ~AA_ALL_EXEC_MODIFIERS) | - (perms & AA_ALL_EXEC_MODIFIERS)); - } - /* FIXME: currently change_profile also implies onexec */ - cp_perms |= entry->perms & (AA_CHANGE_PROFILE); - } - - /* if there are change_profile rules, this implies that we need - * access to some /proc/ interfaces - */ - if (cp_perms & AA_CHANGE_PROFILE) { - if (!add_proc_access(prof, CHANGEPROFILE_PATH)) - exit(1); - } -} - -void post_process_rule_entries(Profile *prof) -{ - for (RuleList::iterator i = prof->rule_ents.begin(); i != prof->rule_ents.end(); i++) - (*i)->post_process(*prof); -} - - -#define CHANGEHAT_PATH "/proc/[0-9]*/attr/{apparmor/,}current" - -/* add file rules to access /proc files to call change_hat() - */ -static int profile_add_hat_rules(Profile *prof) -{ - /* don't add hat rules if not hat or profile doesn't have hats */ - if (!(prof->flags.flags & FLAG_HAT) && prof->hat_table.empty()) - return 0; - - if (!add_proc_access(prof, CHANGEHAT_PATH)) - return ENOMEM; - - return 0; -} - int load_policy_list(ProfileList &list, int option, aa_kernel_interface *kernel_interface, int cache_fd) { @@ -392,12 +210,7 @@ int post_process_profile(Profile *profile, int debug_only) { int error = 0; - error = profile_add_hat_rules(profile); - if (error) { - PERROR(_("ERROR adding hat access rule for profile %s\n"), - profile->name); - return error; - } + profile->add_implied_rules(); error = process_profile_variables(profile); if (error) { diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index a19868e97..b9a55bf6e 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -397,8 +397,7 @@ profile_base: TOK_ID opt_id_or_var opt_cond_list flags TOK_OPEN */ prof->flags.mode = MODE_COMPLAIN; - post_process_file_entries(prof); - post_process_rule_entries(prof); + prof->post_parse_profile(); prof->flags.debug(cerr); /* restore previous blocks include cache */ diff --git a/parser/profile.cc b/parser/profile.cc index a3b982aff..79095d1d8 100644 --- a/parser/profile.cc +++ b/parser/profile.cc @@ -14,6 +14,7 @@ #include "profile.h" #include "rule.h" +#include "parser.h" #include #include @@ -118,3 +119,203 @@ Profile::~Profile() free(net.quiet); } +int add_entry_to_x_table(Profile *prof, char *name) +{ + int i; + for (i = (AA_EXEC_LOCAL >> 10) + 1; i < AA_EXEC_COUNT; i++) { + if (!prof->exec_table[i]) { + prof->exec_table[i] = name; + return i; + } else if (strcmp(prof->exec_table[i], name) == 0) { + /* name already in table */ + free(name); + return i; + } + } + free(name); + return 0; +} + +void add_entry_to_policy(Profile *prof, struct cod_entry *entry) +{ + entry->next = prof->entries; + prof->entries = entry; +} + +static int add_named_transition(Profile *prof, struct cod_entry *entry) +{ + char *name = NULL; + + /* check to see if it is a local transition */ + if (!label_contains_ns(entry->nt_name)) { + char *sub = strstr(entry->nt_name, "//"); + /* does the subprofile name match the rule */ + + if (sub && strncmp(prof->name, sub, sub - entry->nt_name) && + strcmp(sub + 2, entry->name) == 0) { + free(entry->nt_name); + entry->nt_name = NULL; + return AA_EXEC_LOCAL >> 10; + } else if (((entry->perms & AA_USER_EXEC_MODIFIERS) == + SHIFT_PERMS(AA_EXEC_LOCAL, AA_USER_SHIFT)) || + ((entry->perms & AA_OTHER_EXEC_MODIFIERS) == + SHIFT_PERMS(AA_EXEC_LOCAL, AA_OTHER_SHIFT))) { + if (strcmp(entry->nt_name, entry->name) == 0) { + free(entry->nt_name); + entry->nt_name = NULL; + return AA_EXEC_LOCAL >> 10; + } + /* specified as cix so profile name is implicit */ + name = (char *) malloc(strlen(prof->name) + strlen(entry->nt_name) + + 3); + if (!name) { + PERROR("Memory allocation error\n"); + exit(1); + } + sprintf(name, "%s//%s", prof->name, entry->nt_name); + free(entry->nt_name); + entry->nt_name = NULL; + } else { + /** + * pass control of the memory pointed to by nt_name + * from entry to add_entry_to_x_table() + */ + name = entry->nt_name; + entry->nt_name = NULL; + } + } else { + /** + * pass control of the memory pointed to by nt_name + * from entry to add_entry_to_x_table() + */ + name = entry->nt_name; + entry->nt_name = NULL; + } + + return add_entry_to_x_table(prof, name); +} + +static bool add_proc_access(Profile *prof, const char *rule) +{ + /* FIXME: should use @{PROC}/@{PID}/attr/{apparmor/,}{current,exec} */ + struct cod_entry *new_ent; + /* allow probe for new interfaces */ + char *buffer = strdup("/proc/*/attr/apparmor/"); + if (!buffer) { + PERROR("Memory allocation error\n"); + return FALSE; + } + new_ent = new_entry(buffer, AA_MAY_READ, NULL); + if (!new_ent) { + free(buffer); + PERROR("Memory allocation error\n"); + return FALSE; + } + add_entry_to_policy(prof, new_ent); + + /* allow probe if apparmor is enabled for the old interface */ + buffer = strdup("/sys/module/apparmor/parameters/enabled"); + if (!buffer) { + PERROR("Memory allocation error\n"); + return FALSE; + } + new_ent = new_entry(buffer, AA_MAY_READ, NULL); + if (!new_ent) { + free(buffer); + PERROR("Memory allocation error\n"); + return FALSE; + } + add_entry_to_policy(prof, new_ent); + + /* allow setting on new and old interfaces */ + buffer = strdup(rule); + if (!buffer) { + PERROR("Memory allocation error\n"); + return FALSE; + } + new_ent = new_entry(buffer, AA_MAY_WRITE, NULL); + if (!new_ent) { + free(buffer); + PERROR("Memory allocation error\n"); + return FALSE; + } + add_entry_to_policy(prof, new_ent); + + return TRUE; +} + +#define CHANGEPROFILE_PATH "/proc/*/attr/{apparmor/,}{current,exec}" +void post_process_file_entries(Profile *prof) +{ + struct cod_entry *entry; + perms_t cp_perms = 0; + + list_for_each(prof->entries, entry) { + if (entry->nt_name) { + perms_t perms = 0; + int n = add_named_transition(prof, entry); + if (!n) { + PERROR("Profile %s has too many specified profile transitions.\n", prof->name); + exit(1); + } + if (entry->perms & AA_USER_EXEC) + perms |= SHIFT_PERMS(n << 10, AA_USER_SHIFT); + if (entry->perms & AA_OTHER_EXEC) + perms |= SHIFT_PERMS(n << 10, AA_OTHER_SHIFT); + entry->perms = ((entry->perms & ~AA_ALL_EXEC_MODIFIERS) | + (perms & AA_ALL_EXEC_MODIFIERS)); + } + /* FIXME: currently change_profile also implies onexec */ + cp_perms |= entry->perms & (AA_CHANGE_PROFILE); + } + + /* if there are change_profile rules, this implies that we need + * access to some /proc/ interfaces + */ + if (cp_perms & AA_CHANGE_PROFILE) { + if (!add_proc_access(prof, CHANGEPROFILE_PATH)) + exit(1); + } +} + +void post_process_rule_entries(Profile *prof) +{ + for (RuleList::iterator i = prof->rule_ents.begin(); i != prof->rule_ents.end(); i++) + (*i)->post_parse_profile(*prof); +} + + +#define CHANGEHAT_PATH "/proc/[0-9]*/attr/{apparmor/,}current" + +/* add file rules to access /proc files to call change_hat() + */ +static int profile_add_hat_rules(Profile *prof) +{ + /* don't add hat rules if not hat or profile doesn't have hats */ + if (!(prof->flags.flags & FLAG_HAT) && prof->hat_table.empty()) + return 0; + + if (!add_proc_access(prof, CHANGEHAT_PATH)) + return ENOMEM; + + return 0; +} + +void Profile::post_parse_profile(void) +{ + post_process_file_entries(this); + post_process_rule_entries(this); +} + +void Profile::add_implied_rules(void) +{ + int error; + + error = profile_add_hat_rules(this); + if (error) { + PERROR(_("ERROR adding hat access rule for profile %s\n"), + name); + //return error; + } + +} diff --git a/parser/profile.h b/parser/profile.h index bf9ca2308..e324d9f1d 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -314,6 +314,9 @@ public: { cout << get_name(fqp);; } + + void post_parse_profile(void); + void add_implied_rules(void); }; diff --git a/parser/ptrace.h b/parser/ptrace.h index dbe1eb308..98454e952 100644 --- a/parser/ptrace.h +++ b/parser/ptrace.h @@ -43,7 +43,6 @@ public: virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); - virtual void post_process(Profile &prof unused) { }; virtual bool valid_prefix(prefixes &p, const char *&error) { if (p.owner) { diff --git a/parser/rule.h b/parser/rule.h index ad307c66f..aa8ff2c72 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -37,9 +37,23 @@ public: //virtual bool operator<(rule_t const &rhs)const = 0; virtual std::ostream &dump(std::ostream &os) = 0; + + // Follow methods in order of being called by the parse + + // called when profile is finished parsing + virtual void post_parse_profile(Profile &prof __attribute__ ((unused))) { }; + + // called before final expansion of variables. So implied rules + // can reference variables + virtual void add_implied_rules(Profile &prof __attribute__ ((unused))) { }; + + // currently only called post parse + // needs to change to being interatively called during parse + // to support expansion in include names and profile names virtual int expand_variables(void) = 0; + + // called late frontend to generate data for regex backend virtual int gen_policy_re(Profile &prof) = 0; - virtual void post_process(Profile &prof) = 0; protected: const char *warned_name = NULL; diff --git a/parser/signal.h b/parser/signal.h index b6ca7c9ee..af8469cc9 100644 --- a/parser/signal.h +++ b/parser/signal.h @@ -56,7 +56,6 @@ public: virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); - virtual void post_process(Profile &prof unused) { }; protected: virtual void warn_once(const char *name) override; diff --git a/parser/userns.h b/parser/userns.h index 0333e9cac..624d53cbb 100644 --- a/parser/userns.h +++ b/parser/userns.h @@ -41,7 +41,6 @@ public: virtual ostream &dump(ostream &os); virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); - virtual void post_process(Profile &prof unused) { }; protected: virtual void warn_once(const char *name) override; From c36d4e9c0388c8fd5a33a51160c128f141c67349 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 8 Sep 2021 02:39:32 -0700 Subject: [PATCH 12/25] parser: make alias_ignore a bool Signed-off-by: John Johansen --- parser/parser.h | 2 +- parser/parser_alias.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/parser/parser.h b/parser/parser.h index 55ef2e500..e71a29c25 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -126,7 +126,7 @@ struct cod_entry { audit_t audit; int deny; /* TRUE or FALSE */ - int alias_ignore; /* ignore for alias processing */ + bool alias_ignore; /* ignore for alias processing */ int subset; diff --git a/parser/parser_alias.c b/parser/parser_alias.c index 6dacb076e..827128e87 100644 --- a/parser/parser_alias.c +++ b/parser/parser_alias.c @@ -141,7 +141,7 @@ static void process_entries(const void *nodep, VISIT value, int level unused) dup->link_name = n; } if (dup) { - dup->alias_ignore = 1; + dup->alias_ignore = true; /* adds to the front of the list, list iteratition * will skip it */ From f76d134b6c091101c6f5ec591927aa9d77eff2d3 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 8 Sep 2021 02:50:31 -0700 Subject: [PATCH 13/25] parser: convert subset flag to a bool Signed-off-by: John Johansen --- parser/parser.h | 2 +- parser/parser_merge.c | 2 +- parser/parser_yacc.y | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/parser/parser.h b/parser/parser.h index e71a29c25..f5a0d5d58 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -128,7 +128,7 @@ struct cod_entry { bool alias_ignore; /* ignore for alias processing */ - int subset; + bool subset; pattern_t pattern_type; struct cod_pattern pat; diff --git a/parser/parser_merge.c b/parser/parser_merge.c index b93103aa1..6c5603e36 100644 --- a/parser/parser_merge.c +++ b/parser/parser_merge.c @@ -44,7 +44,7 @@ static int file_comp(const void *c1, const void *c2) return res; if ((*e1)->link_name) - res = (*e2)->subset - (*e1)->subset; + res = ((int) (*e2)->subset) - ((int) (*e1)->subset); if (res) return res; diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index b9a55bf6e..98dd9901b 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -648,9 +648,9 @@ flagval: TOK_VALUE $$ = fv; }; -opt_subset_flag: { /* nothing */ $$ = 0; } - | TOK_SUBSET { $$ = 1; } - | TOK_LE { $$ = 1; } +opt_subset_flag: { /* nothing */ $$ = false; } + | TOK_SUBSET { $$ = true; } + | TOK_LE { $$ = true; } opt_audit_flag: { /* nothing */ $$ = AUDIT_UNSPECIFIED; } | TOK_AUDIT { $$ = AUDIT_FORCE; }; From 355730d8c70eca4df1d77e97d6f38778ec46170b Mon Sep 17 00:00:00 2001 From: John Johansen Date: Thu, 9 Sep 2021 01:42:51 -0700 Subject: [PATCH 14/25] parser: convert deny flag from bool to rule_mode We need to be able to support more rule types than allow and deny so convert to an enum. Signed-off-by: John Johansen --- parser/af_unix.cc | 18 +++++++-------- parser/af_unix.h | 2 +- parser/dbus.cc | 6 ++--- parser/mount.cc | 18 +++++++-------- parser/mqueue.cc | 8 +++---- parser/parser.h | 2 +- parser/parser_merge.c | 4 ++-- parser/parser_misc.c | 4 ++-- parser/parser_regex.c | 18 ++++++++------- parser/parser_yacc.y | 51 ++++++++++++++++++++++--------------------- parser/ptrace.cc | 2 +- parser/rule.h | 19 ++++++++++------ parser/signal.cc | 2 +- parser/userns.cc | 2 +- 14 files changed, 82 insertions(+), 74 deletions(-) diff --git a/parser/af_unix.cc b/parser/af_unix.cc index 8fbdce9af..a9bbf1ad9 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -95,7 +95,7 @@ void unix_rule::move_peer_conditionals(struct cond_entry *conds) } } -unix_rule::unix_rule(unsigned int type_p, audit_t audit_p, bool denied): +unix_rule::unix_rule(unsigned int type_p, audit_t audit_p, rule_mode_t rule_mode_p): af_rule("unix"), addr(NULL), peer_addr(NULL) { if (type_p != 0xffffffff) { @@ -106,7 +106,7 @@ unix_rule::unix_rule(unsigned int type_p, audit_t audit_p, bool denied): } perms = AA_VALID_NET_PERMS; audit = audit_p; - deny = denied; + rule_mode = rule_mode_p; } unix_rule::unix_rule(perms_t perms_p, struct cond_entry *conds, @@ -193,7 +193,7 @@ void unix_rule::downgrade_rule(Profile &prof) { yyerror(_("Memory allocation error.")); if (sock_type_n != -1) mask = 1 << sock_type_n; - if (!deny) { + if (rule_mode != RULE_DENY) { prof.net.allow[AF_UNIX] |= mask; if (audit == AUDIT_FORCE) prof.net.audit[AF_UNIX] |= mask; @@ -334,7 +334,7 @@ int unix_rule::gen_policy_re(Profile &prof) write_to_prot(buffer); if ((mask & AA_NET_CREATE) && !has_peer_conds()) { buf = buffer.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, + if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(AA_NET_CREATE), map_perms(audit == AUDIT_FORCE ? AA_NET_CREATE : 0), dfaflags)) @@ -359,7 +359,7 @@ int unix_rule::gen_policy_re(Profile &prof) tmp << "\\x00"; buf = tmp.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, + if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(AA_NET_BIND), map_perms(audit == AUDIT_FORCE ? AA_NET_BIND : 0), dfaflags)) @@ -384,7 +384,7 @@ int unix_rule::gen_policy_re(Profile &prof) AA_LOCAL_NET_PERMS & ~AA_LOCAL_NET_CMD; if (mask & local_mask) { buf = buffer.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, + if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(mask & local_mask), map_perms(audit == AUDIT_FORCE ? mask & local_mask : 0), dfaflags)) @@ -398,7 +398,7 @@ int unix_rule::gen_policy_re(Profile &prof) /* TODO: backlog conditional: for now match anything*/ tmp << ".."; buf = tmp.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, + if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(AA_NET_LISTEN), map_perms(audit == AUDIT_FORCE ? AA_NET_LISTEN : 0), dfaflags)) @@ -411,7 +411,7 @@ int unix_rule::gen_policy_re(Profile &prof) /* TODO: sockopt conditional: for now match anything */ tmp << ".."; buf = tmp.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, + if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(AA_NET_OPT), map_perms(audit == AUDIT_FORCE ? AA_NET_OPT : 0), dfaflags)) @@ -432,7 +432,7 @@ int unix_rule::gen_policy_re(Profile &prof) goto fail; buf = buffer.str(); - if (!prof.policy.rules->add_rule(buf.c_str(), deny, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit == AUDIT_FORCE ? perms & AA_PEER_NET_PERMS : 0), dfaflags)) + if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, map_perms(perms & AA_PEER_NET_PERMS), map_perms(audit == AUDIT_FORCE ? perms & AA_PEER_NET_PERMS : 0), dfaflags)) goto fail; } diff --git a/parser/af_unix.h b/parser/af_unix.h index 2ad6e9e84..c7fcf2fcf 100644 --- a/parser/af_unix.h +++ b/parser/af_unix.h @@ -37,7 +37,7 @@ public: char *addr; char *peer_addr; - unix_rule(unsigned int type_p, audit_t audit_p, bool denied); + unix_rule(unsigned int type_p, audit_t audit_p, rule_mode_t rule_mode_p); unix_rule(perms_t perms, struct cond_entry *conds, struct cond_entry *peer_conds); virtual ~unix_rule() diff --git a/parser/dbus.cc b/parser/dbus.cc index bcd4536df..92885b323 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -275,20 +275,20 @@ int dbus_rule::gen_policy_re(Profile &prof) } if (perms & AA_DBUS_BIND) { - if (!prof.policy.rules->add_rule_vec(deny, perms & AA_DBUS_BIND, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms & AA_DBUS_BIND, audit == AUDIT_FORCE ? perms & AA_DBUS_BIND : 0, 2, vec, dfaflags, false)) goto fail; } if (perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE)) { - if (!prof.policy.rules->add_rule_vec(deny, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE), audit == AUDIT_FORCE ? perms & (AA_DBUS_SEND | AA_DBUS_RECEIVE) : 0, 6, vec, dfaflags, false)) goto fail; } if (perms & AA_DBUS_EAVESDROP) { - if (!prof.policy.rules->add_rule_vec(deny, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms & AA_DBUS_EAVESDROP, audit == AUDIT_FORCE ? perms & AA_DBUS_EAVESDROP : 0, 1, vec, dfaflags, false)) diff --git a/parser/mount.cc b/parser/mount.cc index 7e0b76823..c365637b0 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -741,7 +741,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, * if a data match is required this only has AA_MATCH_CONT perms * else it has full perms */ - if (!prof.policy.rules->add_rule_vec(deny, tmpperms, tmpaudit, 4, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4, vec, dfaflags, false)) goto fail; count++; @@ -752,7 +752,7 @@ int mnt_rule::gen_policy_remount(Profile &prof, int &count, if (!build_mnt_opts(optsbuf, opts)) goto fail; vec[4] = optsbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, perms, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, (audit == AUDIT_FORCE ? perms : 0), 5, vec, dfaflags, false)) goto fail; @@ -794,7 +794,7 @@ int mnt_rule::gen_policy_bind_mount(Profile &prof, int &count, opt_flags & MS_BIND_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 4, vec, dfaflags, false)) goto fail; @@ -836,7 +836,7 @@ int mnt_rule::gen_policy_change_mount_type(Profile &prof, int &count, opt_flags & MS_MAKE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 4, vec, dfaflags, false)) goto fail; @@ -879,7 +879,7 @@ int mnt_rule::gen_policy_move_mount(Profile &prof, int &count, opt_flags & MS_MOVE_FLAGS)) goto fail; vec[3] = flagsbuf; - if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 4, vec, dfaflags, false)) goto fail; @@ -931,7 +931,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, tmpaudit = audit == AUDIT_FORCE ? perms : 0; } /* rule for match without required data || data MATCH_CONT */ - if (!prof.policy.rules->add_rule_vec(deny, tmpperms, tmpaudit, 4, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, tmpperms, tmpaudit, 4, vec, dfaflags, false)) goto fail; count++; @@ -942,7 +942,7 @@ int mnt_rule::gen_policy_new_mount(Profile &prof, int &count, if (!build_mnt_opts(optsbuf, opts)) goto fail; vec[4] = optsbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, perms, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 5, vec, dfaflags, false)) goto fail; @@ -1034,7 +1034,7 @@ int mnt_rule::gen_policy_re(Profile &prof) if (!convert_entry(mntbuf, mnt_point)) goto fail; vec[0] = mntbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, perms, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, (audit == AUDIT_FORCE ? perms : 0), 1, vec, dfaflags, false)) goto fail; @@ -1049,7 +1049,7 @@ int mnt_rule::gen_policy_re(Profile &prof) if (!clear_and_convert_entry(devbuf, device)) goto fail; vec[1] = devbuf.c_str(); - if (!prof.policy.rules->add_rule_vec(deny, perms, + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, (audit == AUDIT_FORCE ? perms : 0), 2, vec, dfaflags, false)) goto fail; diff --git a/parser/mqueue.cc b/parser/mqueue.cc index 47273580f..4e1538107 100644 --- a/parser/mqueue.cc +++ b/parser/mqueue.cc @@ -230,10 +230,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) /* store perms at name match so label doesn't need * to be checked */ - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false)) goto fail; } } @@ -265,10 +265,10 @@ int mqueue_rule::gen_policy_re(Profile &prof) } if (perms & AA_VALID_SYSV_MQ_PERMS) { - if (!label && !prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false)) + if (!label && !prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, 1, vec, dfaflags, false)) goto fail; /* also provide label match with perm */ - if (!prof.policy.rules->add_rule_vec(deny, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false)) + if (!prof.policy.rules->add_rule_vec(rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, size, vec, dfaflags, false)) goto fail; } } diff --git a/parser/parser.h b/parser/parser.h index f5a0d5d58..a115ff92a 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -124,7 +124,7 @@ struct cod_entry { * just for this executable */ perms_t perms; /* perms is 'or' of AA_* bits */ audit_t audit; - int deny; /* TRUE or FALSE */ + rule_mode_t rule_mode; bool alias_ignore; /* ignore for alias processing */ diff --git a/parser/parser_merge.c b/parser/parser_merge.c index 6c5603e36..77c295e19 100644 --- a/parser/parser_merge.c +++ b/parser/parser_merge.c @@ -48,8 +48,8 @@ static int file_comp(const void *c1, const void *c2) if (res) return res; - if ((*e1)->deny != (*e2)->deny) - return (*e1)->deny < (*e2)->deny ? -1 : 1; + if ((*e1)->rule_mode != (*e2)->rule_mode) + return (*e1)->rule_mode < (*e2)->rule_mode ? -1 : 1; if ((*e1)->audit != (*e2)->audit) return (*e1)->audit < (*e2)->audit ? -1 : 1; diff --git a/parser/parser_misc.c b/parser/parser_misc.c index ee304d7d6..960d4977c 100644 --- a/parser/parser_misc.c +++ b/parser/parser_misc.c @@ -962,7 +962,7 @@ struct cod_entry *new_entry(char *id, perms_t perms, char *link_id) entry->link_name = link_id; entry->perms = perms; entry->audit = AUDIT_UNSPECIFIED; - entry->deny = FALSE; + entry->rule_mode = RULE_UNSPECIFIED; entry->pattern_type = ePatternInvalid; entry->pat.regex = NULL; @@ -986,7 +986,7 @@ struct cod_entry *copy_cod_entry(struct cod_entry *orig) DUP_STRING(orig, entry, nt_name, err); entry->perms = orig->perms; entry->audit = orig->audit; - entry->deny = orig->deny; + entry->rule_mode = orig->rule_mode; /* XXX - need to create copies of the patterns, too */ entry->pattern_type = orig->pattern_type; diff --git a/parser/parser_regex.c b/parser/parser_regex.c index 9ad25eb41..fa3b42ad7 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -627,17 +627,19 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) * than link in the entry. * TODO: split link and change_profile entries earlier */ - if (entry->deny) { + if (entry->rule_mode == RULE_DENY) { if ((entry->perms & ~AA_LINK_BITS) && !is_change_profile_perms(entry->perms) && - !dfarules->add_rule(tbuf.c_str(), entry->deny, + !dfarules->add_rule(tbuf.c_str(), entry->rule_mode == RULE_DENY, entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE), entry->audit == AUDIT_FORCE ? entry->perms & ~(AA_LINK_BITS | AA_CHANGE_PROFILE) : 0, dfaflags)) return FALSE; } else if (!is_change_profile_perms(entry->perms)) { - if (!dfarules->add_rule(tbuf.c_str(), entry->deny, entry->perms, - entry->audit == AUDIT_FORCE ? entry->perms : 0, dfaflags)) + if (!dfarules->add_rule(tbuf.c_str(), + entry->rule_mode == RULE_DENY, entry->perms, + entry->audit == AUDIT_FORCE ? entry->perms : 0, + dfaflags)) return FALSE; } @@ -660,7 +662,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) perms |= LINK_TO_LINK_SUBSET(perms); vec[1] = "/[^/].*"; } - if (!dfarules->add_rule_vec(entry->deny, perms, entry->audit == AUDIT_FORCE ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false)) + if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, perms, entry->audit == AUDIT_FORCE ? perms & AA_LINK_BITS : 0, 2, vec, dfaflags, false)) return FALSE; } if (is_change_profile_perms(entry->perms)) { @@ -711,13 +713,13 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) } /* regular change_profile rule */ - if (!dfarules->add_rule_vec(entry->deny, + if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, AA_CHANGE_PROFILE | onexec_perms, 0, index - 1, &vec[1], dfaflags, false)) return FALSE; /* onexec rules - both rules are needed for onexec */ - if (!dfarules->add_rule_vec(entry->deny, onexec_perms, + if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, onexec_perms, 0, 1, vec, dfaflags, false)) return FALSE; @@ -726,7 +728,7 @@ static int process_dfa_entry(aare_rules *dfarules, struct cod_entry *entry) * unsafe exec transitions */ onexec_perms |= (entry->perms & (AA_EXEC_BITS | ALL_AA_EXEC_UNSAFE)); - if (!dfarules->add_rule_vec(entry->deny, onexec_perms, + if (!dfarules->add_rule_vec(entry->rule_mode == RULE_DENY, onexec_perms, 0, index, vec, dfaflags, false)) return FALSE; } diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 98dd9901b..476f2e8f6 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -216,6 +216,7 @@ void add_local_entry(Profile *prof); struct prefixes prefix; IncludeCache_t *includecache; audit_t audit; + rule_mode_t rule_mode; } %type TOK_ID @@ -258,7 +259,7 @@ void add_local_entry(Profile *prof); %type opt_owner_flag %type opt_profile_flag %type opt_flags -%type opt_perm_mode +%type opt_rule_mode %type opt_id %type opt_prefix %type dbus_perm @@ -659,14 +660,14 @@ opt_owner_flag: { /* nothing */ $$ = 0; } | TOK_OWNER { $$ = 1; }; | TOK_OTHER { $$ = 2; }; -opt_perm_mode: { /* nothing */ $$ = 0; } - | TOK_ALLOW { $$ = 0; } - | TOK_DENY { $$ = 1; } +opt_rule_mode: { /* nothing */ $$ = RULE_UNSPECIFIED; } + | TOK_ALLOW { $$ = RULE_ALLOW; } + | TOK_DENY { $$ = RULE_DENY; } -opt_prefix: opt_audit_flag opt_perm_mode opt_owner_flag +opt_prefix: opt_audit_flag opt_rule_mode opt_owner_flag { $$.audit = $1; - $$.deny = $2; + $$.rule_mode = $2; $$.owner = $3; } @@ -687,11 +688,11 @@ rules: rules opt_prefix rule PDEBUG("rules rule: (%s)\n", $3->name); if (!$3) yyerror(_("Assert: `rule' returned NULL.")); - $3->deny = $2.deny; - if (($2.deny && ($3->perms & AA_EXEC_BITS) && + $3->rule_mode = $2.rule_mode; + if ((($2.rule_mode == RULE_DENY) && ($3->perms & AA_EXEC_BITS) && ($3->perms & ALL_AA_EXEC_TYPE))) yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); - else if (!$2.deny && ($3->perms & AA_EXEC_BITS) && + else if (($2.rule_mode != RULE_DENY) && ($3->perms & AA_EXEC_BITS) && !($3->perms & ALL_AA_EXEC_TYPE) && !($3->nt_name)) yyerror(_("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'")); @@ -701,7 +702,7 @@ rules: rules opt_prefix rule else if ($2.owner == 2) $3->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); /* only set audit ctl quieting if the rule is not audited */ - if (($2.deny && $2.audit != AUDIT_FORCE) || (!$2.deny && $2.audit == AUDIT_FORCE)) + if ((($2.rule_mode == RULE_DENY) && $2.audit != AUDIT_FORCE) || (($2.rule_mode != RULE_DENY) && $2.audit == AUDIT_FORCE)) $3->audit = AUDIT_FORCE; add_entry_to_policy($1, $3); $$ = $1; @@ -711,18 +712,18 @@ rules: rules opt_prefix rule rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE { struct cod_entry *entry, *tmp; - if ($2.deny) + if ($2.rule_mode == RULE_DENY) yyerror(_("deny prefix not allowed")); PDEBUG("matched: %s%s%sblock\n", $2.audit == AUDIT_FORCE ? "audit " : "", - $2.deny ? "deny " : "", $2.owner ? "owner " : ""); + $2.rule_mode == RULE_DENY ? "deny " : "", $2.owner ? "owner " : ""); list_for_each_safe($4->entries, entry, tmp) { entry->next = NULL; if (entry->perms & AA_EXEC_BITS) { - if (entry->deny && + if ((entry->rule_mode == RULE_DENY) && (entry->perms & ALL_AA_EXEC_TYPE)) yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); - else if (!entry->deny && + else if ((entry->rule_mode != RULE_DENY) && !(entry->perms & ALL_AA_EXEC_TYPE)) yyerror(_("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'")); } @@ -731,9 +732,9 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE else if ($2.owner == 2) entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); - if ($2.audit == AUDIT_FORCE && !entry->deny) + if ($2.audit == AUDIT_FORCE && (entry->rule_mode != RULE_DENY)) entry->audit = AUDIT_FORCE; - else if ($2.audit != AUDIT_FORCE && entry->deny) + else if ($2.audit != AUDIT_FORCE && (entry->rule_mode == RULE_DENY)) entry->audit = AUDIT_FORCE; add_entry_to_policy($1, entry); } @@ -760,14 +761,14 @@ rules: rules opt_prefix network_rule * downgrade if needed */ if (entry->family == AF_UNIX) { - unix_rule *rule = new unix_rule(entry->type, $2.audit, $2.deny); + unix_rule *rule = new unix_rule(entry->type, $2.audit, $2.rule_mode); if (!rule) yyerror(_("Memory allocation error.")); $1->rule_ents.push_back(rule); } if (entry->type > SOCK_PACKET) { /* setting mask instead of a bit */ - if ($2.deny) { + if ($2.rule_mode == RULE_DENY) { $1->net.deny[entry->family] |= entry->type; if ($2.audit != AUDIT_FORCE) $1->net.quiet[entry->family] |= entry->type; @@ -777,7 +778,7 @@ rules: rules opt_prefix network_rule $1->net.audit[entry->family] |= entry->type; } } else { - if ($2.deny) { + if ($2.rule_mode == RULE_DENY) { $1->net.deny[entry->family] |= 1 << entry->type; if ($2.audit != AUDIT_FORCE) $1->net.quiet[entry->family] |= 1 << entry->type; @@ -818,10 +819,10 @@ rules: rules opt_prefix change_profile yyerror(_("Assert: `change_profile' returned NULL.")); if ($2.owner) yyerror(_("owner prefix not allowed on unix rules")); - if ($2.deny && $2.audit == AUDIT_FORCE) { - $3->deny = 1; - } else if ($2.deny) { - $3->deny = 1; + if (($2.rule_mode == RULE_DENY) && $2.audit == AUDIT_FORCE) { + $3->rule_mode = RULE_DENY; + } else if ($2.rule_mode == RULE_DENY) { + $3->rule_mode = RULE_DENY; $3->audit = AUDIT_FORCE; } else if ($2.audit != AUDIT_UNSPECIFIED) { $3->audit = $2.audit; @@ -835,9 +836,9 @@ rules: rules opt_prefix capability if ($2.owner) yyerror(_("owner prefix not allowed on capability rules")); - if ($2.deny && $2.audit == AUDIT_FORCE) { + if ($2.rule_mode == RULE_DENY && $2.audit == AUDIT_FORCE) { $1->caps.deny |= $3; - } else if ($2.deny) { + } else if ($2.rule_mode == RULE_DENY) { $1->caps.deny |= $3; $1->caps.quiet |= $3; } else { diff --git a/parser/ptrace.cc b/parser/ptrace.cc index 9459ab3c5..1570e80cd 100644 --- a/parser/ptrace.cc +++ b/parser/ptrace.cc @@ -135,7 +135,7 @@ int ptrace_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & AA_VALID_PTRACE_PERMS) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/rule.h b/parser/rule.h index aa8ff2c72..000098e5b 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -70,6 +70,7 @@ typedef std::list RuleList; /* Not classes so they can be used in the bison front end */ typedef uint32_t perms_t; typedef enum { AUDIT_UNSPECIFIED, AUDIT_FORCE, AUDIT_QUIET } audit_t; +typedef enum { RULE_UNSPECIFIED, RULE_ALLOW, RULE_DENY } rule_mode_t; /* NOTE: we can not have a constructor for class prefixes. This is * because it will break bison, and we would need to transition to @@ -80,7 +81,7 @@ typedef enum { AUDIT_UNSPECIFIED, AUDIT_FORCE, AUDIT_QUIET } audit_t; class prefixes { public: audit_t audit; - int deny; + rule_mode_t rule_mode; int owner; ostream &dump(ostream &os) @@ -98,12 +99,16 @@ public: output = false; } - if (deny) { + switch (rule_mode) { + case RULE_DENY: if (output) os << " "; os << "deny"; output = true; + break; + default: + break; } if (owner) { @@ -126,7 +131,7 @@ public: { /* Must construct prefix here see note on prefixes */ audit = AUDIT_UNSPECIFIED; - deny = 0; + rule_mode = RULE_UNSPECIFIED; owner = 0; }; @@ -141,10 +146,10 @@ public: return false; } } - if (p.deny && p.audit == AUDIT_FORCE) { - deny = 1; - } else if (p.deny) { - deny = 1; + if (p.rule_mode == RULE_DENY && p.audit == AUDIT_FORCE) { + rule_mode = RULE_DENY; + } else if (p.rule_mode == RULE_DENY) { + rule_mode = RULE_DENY; audit = AUDIT_FORCE; } else if (p.audit != AUDIT_UNSPECIFIED) { audit = p.audit; diff --git a/parser/signal.cc b/parser/signal.cc index 461309be5..a1af31463 100644 --- a/parser/signal.cc +++ b/parser/signal.cc @@ -289,7 +289,7 @@ int signal_rule::gen_policy_re(Profile &prof) buf = buffer.str(); if (perms & (AA_MAY_SEND | AA_MAY_RECEIVE)) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, audit == AUDIT_FORCE ? perms : 0, + if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, dfaflags)) goto fail; } diff --git a/parser/userns.cc b/parser/userns.cc index 84f0fe31d..19bc0f787 100644 --- a/parser/userns.cc +++ b/parser/userns.cc @@ -96,7 +96,7 @@ int userns_rule::gen_policy_re(Profile &prof) buffer << "\\x" << std::setfill('0') << std::setw(2) << std::hex << AA_CLASS_NS; buf = buffer.str(); if (perms & AA_VALID_USERNS_PERMS) { - if (!prof.policy.rules->add_rule(buf.c_str(), deny, perms, + if (!prof.policy.rules->add_rule(buf.c_str(), rule_mode == RULE_DENY, perms, audit == AUDIT_FORCE ? perms : 0, dfaflags)) goto fail; From b3bb74c33c237cdd3b9312cef157ea4cd3c4741e Mon Sep 17 00:00:00 2001 From: John Johansen Date: Thu, 1 Sep 2022 09:56:45 -0700 Subject: [PATCH 15/25] parser: convert valid_prefix and add_prefix to use const The prefix can passed as a parameter can be const so it should be. Signed-off-by: John Johansen --- parser/af_unix.h | 2 +- parser/dbus.h | 2 +- parser/mount.h | 2 +- parser/mqueue.h | 2 +- parser/ptrace.h | 2 +- parser/rule.h | 4 ++-- parser/signal.h | 2 +- parser/userns.h | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/parser/af_unix.h b/parser/af_unix.h index c7fcf2fcf..27cb662bb 100644 --- a/parser/af_unix.h +++ b/parser/af_unix.h @@ -46,7 +46,7 @@ public: free(peer_addr); }; - virtual bool valid_prefix(prefixes &p, const char *&error) { + virtual bool valid_prefix(const prefixes &p, const char *&error) { if (p.owner) { error = "owner prefix not allowed on unix rules"; return false; diff --git a/parser/dbus.h b/parser/dbus.h index a564ef8ae..f35797e9a 100644 --- a/parser/dbus.h +++ b/parser/dbus.h @@ -50,7 +50,7 @@ public: free(interface); free(member); }; - virtual bool valid_prefix(prefixes &p, const char *&error) { + virtual bool valid_prefix(const prefixes &p, const char *&error) { if (p.owner) { error = "owner prefix not allowed on dbus rules"; return false; diff --git a/parser/mount.h b/parser/mount.h index 86cd1d99d..8045ee966 100644 --- a/parser/mount.h +++ b/parser/mount.h @@ -156,7 +156,7 @@ public: free(trans); } - virtual bool valid_prefix(prefixes &p, const char *&error) { + virtual bool valid_prefix(const prefixes &p, const char *&error) { if (p.owner) { error = "owner prefix not allowed on mount rules"; return false; diff --git a/parser/mqueue.h b/parser/mqueue.h index b26a988a7..24265666c 100644 --- a/parser/mqueue.h +++ b/parser/mqueue.h @@ -95,7 +95,7 @@ public: free(label); }; - virtual bool valid_prefix(prefixes &p, const char *&error) { + virtual bool valid_prefix(const prefixes &p, const char *&error) { // not yet, but soon if (p.owner) { error = _("owner prefix not allowed on mqueue rules"); diff --git a/parser/ptrace.h b/parser/ptrace.h index 98454e952..89881de91 100644 --- a/parser/ptrace.h +++ b/parser/ptrace.h @@ -44,7 +44,7 @@ public: virtual int expand_variables(void); virtual int gen_policy_re(Profile &prof); - virtual bool valid_prefix(prefixes &p, const char *&error) { + virtual bool valid_prefix(const prefixes &p, const char *&error) { if (p.owner) { error = "owner prefix not allowed on ptrace rules"; return false; diff --git a/parser/rule.h b/parser/rule.h index 000098e5b..7337adc7f 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -135,9 +135,9 @@ public: owner = 0; }; - virtual bool valid_prefix(prefixes &p, const char *&error) = 0; + virtual bool valid_prefix(const prefixes &p, const char *&error) = 0; - virtual bool add_prefix(prefixes &p, const char *&error) { + virtual bool add_prefix(const prefixes &p, const char *&error) { if (!valid_prefix(p, error)) return false; if (p.audit != AUDIT_UNSPECIFIED && audit != p.audit) { diff --git a/parser/signal.h b/parser/signal.h index af8469cc9..391c8b34d 100644 --- a/parser/signal.h +++ b/parser/signal.h @@ -45,7 +45,7 @@ public: signals.clear(); free(peer_label); }; - virtual bool valid_prefix(prefixes &p, const char *&error) { + virtual bool valid_prefix(const prefixes &p, const char *&error) { if (p.owner) { error = "owner prefix not allowed on signal rules"; return false; diff --git a/parser/userns.h b/parser/userns.h index 624d53cbb..b72577124 100644 --- a/parser/userns.h +++ b/parser/userns.h @@ -31,7 +31,7 @@ public: { }; - virtual bool valid_prefix(prefixes &p, const char *&error) { + virtual bool valid_prefix(const prefixes &p, const char *&error) { if (p.owner) { error = _("owner prefix not allowed on userns rules"); return false; From 30206fc11e2d2e13f8d6800943ca502e89d7ffc7 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Mon, 20 Feb 2023 14:06:15 -0800 Subject: [PATCH 16/25] Fix add prefix to cover more cases and prep for AUDIT_QUIET Signed-off-by: John Johansen --- parser/rule.h | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/parser/rule.h b/parser/rule.h index 7337adc7f..e40d5902a 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -140,12 +140,36 @@ public: virtual bool add_prefix(const prefixes &p, const char *&error) { if (!valid_prefix(p, error)) return false; - if (p.audit != AUDIT_UNSPECIFIED && audit != p.audit) { - if (audit != AUDIT_UNSPECIFIED) { + /* audit conflicts */ + if (p.audit != AUDIT_UNSPECIFIED) { + if (audit != AUDIT_UNSPECIFIED && + audit != p.audit) { error = "conflicting audit prefix"; return false; } +// audit = p.audit; } + + /* allow deny conflicts */ + if (p.rule_mode != RULE_UNSPECIFIED) { + if (rule_mode != RULE_UNSPECIFIED && + rule_mode != p.rule_mode) { + error = "conflicting mode prefix"; + return false; + } + rule_mode = p.rule_mode; + } + + /* owner !owner conflicts */ + if (p.owner) { + if (owner && owner != p.owner) { + error = "conflicting owner prefix"; + return false; + } + owner = p.owner; + } + + /* does the prefix imply a modifier */ if (p.rule_mode == RULE_DENY && p.audit == AUDIT_FORCE) { rule_mode = RULE_DENY; } else if (p.rule_mode == RULE_DENY) { @@ -154,7 +178,7 @@ public: } else if (p.audit != AUDIT_UNSPECIFIED) { audit = p.audit; } - owner = p.owner; + return true; } From a2d56c3c74ce367daa37a94a4f5d499aebc76960 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Fri, 10 Sep 2021 13:37:54 -0700 Subject: [PATCH 17/25] parser: consolidate rule class handling into aa_class Instead of having each rule individually handle the class info introduce a class_rule_t into the hierarchy and consolidate. Signed-off-by: John Johansen --- parser/af_rule.cc | 2 +- parser/af_rule.h | 16 ++++++++++++---- parser/af_unix.cc | 4 ++-- parser/dbus.cc | 7 +++---- parser/mount.cc | 1 + parser/mqueue.cc | 13 +++++++------ parser/policydb.h | 10 +++++++++- parser/ptrace.cc | 6 ++---- parser/rule.cc | 37 +++++++++++++++++++++++++++++++++++++ parser/rule.h | 22 ++++++++++++++++++++-- parser/signal.cc | 6 ++---- parser/userns.cc | 9 ++++----- 12 files changed, 100 insertions(+), 33 deletions(-) diff --git a/parser/af_rule.cc b/parser/af_rule.cc index 770b56e54..e384d95f0 100644 --- a/parser/af_rule.cc +++ b/parser/af_rule.cc @@ -140,7 +140,7 @@ ostream &af_rule::dump_peer(ostream &os) ostream &af_rule::dump(ostream &os) { prefix_rule_t::dump(os); - os << af_name; + os << af_name(); dump_local(os); if (has_peer_conds()) { os << " peer=("; diff --git a/parser/af_rule.h b/parser/af_rule.h index 5e845b2c1..8ff77e738 100644 --- a/parser/af_rule.h +++ b/parser/af_rule.h @@ -25,6 +25,8 @@ #include "rule.h" +#define AF_ANY -1 + enum cond_side { local_cond, peer_cond, either_cond }; struct supported_cond { @@ -37,7 +39,7 @@ struct supported_cond { class af_rule: public perms_rule_t { public: - std::string af_name; + int af; char *sock_type; int sock_type_n; char *proto; @@ -45,10 +47,11 @@ public: char *label; char *peer_label; - af_rule(const char *name): af_name(name), sock_type(NULL), + af_rule(int f): + perms_rule_t(AA_CLASS_NET), + af(f), sock_type(NULL), sock_type_n(-1), proto(NULL), proto_n(0), label(NULL), - peer_label(NULL) - {} + peer_label(NULL) { } virtual ~af_rule() { @@ -58,6 +61,11 @@ public: free(peer_label); }; + const char *af_name(void) { + if (af != AF_ANY) + return net_find_af_name(af); + return "*"; + } bool cond_check(struct supported_cond *cond, struct cond_entry *ent, bool peer, const char *rname); int move_base_cond(struct cond_entry *conds, bool peer); diff --git a/parser/af_unix.cc b/parser/af_unix.cc index a9bbf1ad9..dfd7f427e 100644 --- a/parser/af_unix.cc +++ b/parser/af_unix.cc @@ -96,7 +96,7 @@ void unix_rule::move_peer_conditionals(struct cond_entry *conds) } unix_rule::unix_rule(unsigned int type_p, audit_t audit_p, rule_mode_t rule_mode_p): - af_rule("unix"), addr(NULL), peer_addr(NULL) + af_rule(AF_UNIX), addr(NULL), peer_addr(NULL) { if (type_p != 0xffffffff) { sock_type_n = type_p; @@ -111,7 +111,7 @@ unix_rule::unix_rule(unsigned int type_p, audit_t audit_p, rule_mode_t rule_mode unix_rule::unix_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds): - af_rule("unix"), addr(NULL), peer_addr(NULL) + af_rule(AF_UNIX), addr(NULL), peer_addr(NULL) { move_conditionals(conds); move_peer_conditionals(peer_conds); diff --git a/parser/dbus.cc b/parser/dbus.cc index 92885b323..8c0b8dbee 100644 --- a/parser/dbus.cc +++ b/parser/dbus.cc @@ -68,7 +68,7 @@ void dbus_rule::move_conditionals(struct cond_entry *conds) dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, struct cond_entry *peer_conds): - bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL) + perms_rule_t(AA_CLASS_DBUS), bus(NULL), name(NULL), peer_label(NULL), path(NULL), interface(NULL), member(NULL) { int name_is_subject_cond = 0, message_rule = 0, service_rule = 0; @@ -121,10 +121,9 @@ dbus_rule::dbus_rule(perms_t perms_p, struct cond_entry *conds, ostream &dbus_rule::dump(ostream &os) { - prefix_rule_t::dump(os); - - os << "dbus ( "; + class_rule_t::dump(os); + os << " ( "; /* override default perms */ if (perms & AA_DBUS_SEND) os << "send "; diff --git a/parser/mount.cc b/parser/mount.cc index c365637b0..abcf8e78e 100644 --- a/parser/mount.cc +++ b/parser/mount.cc @@ -468,6 +468,7 @@ static void process_one_option(struct cond_entry *&opts, unsigned int &flags, mnt_rule::mnt_rule(struct cond_entry *src_conds, char *device_p, struct cond_entry *dst_conds unused, char *mnt_point_p, perms_t perms_p): + perms_rule_t(AA_CLASS_MOUNT), mnt_point(mnt_point_p), device(device_p), trans(NULL), opts(NULL), flagsv(0), opt_flagsv(0) { diff --git a/parser/mqueue.cc b/parser/mqueue.cc index 4e1538107..86ab193ae 100644 --- a/parser/mqueue.cc +++ b/parser/mqueue.cc @@ -87,6 +87,9 @@ void mqueue_rule::move_conditionals(struct cond_entry *conds) } mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_p): + // mqueue uses multiple classes, arbitrary choice to represent group + // withing the AST + perms_rule_t(AA_CLASS_POSIX_MQUEUE), qtype(mqueue_unspecified), qname(qname_p), label(NULL) { move_conditionals(conds); @@ -115,19 +118,17 @@ mqueue_rule::mqueue_rule(perms_t perms_p, struct cond_entry *conds, char *qname_ ostream &mqueue_rule::dump(ostream &os) { - prefix_rule_t::dump(os); - - os << "mqueue "; + class_rule_t::dump(os); // do we want to always put type out or leave it implied if there // is a qname if (qtype == mqueue_posix) - os << "type=posix"; + os << " type=posix"; else if (qtype == mqueue_sysv) - os << "type=sysv"; + os << " type=sysv"; if (perms != AA_VALID_MQUEUE_PERMS) { - os << "("; + os << " ( "; if (perms & AA_MQUEUE_WRITE) os << "write "; diff --git a/parser/policydb.h b/parser/policydb.h index 860b4278d..4bb7070e4 100644 --- a/parser/policydb.h +++ b/parser/policydb.h @@ -32,13 +32,21 @@ #define AA_CLASS_NS_DOMAIN 8 #define AA_CLASS_PTRACE 9 #define AA_CLASS_SIGNAL 10 +#define AA_CLASS_XMATCH 11 +#define AA_CLASS_ENV 12 +#define AA_CLASS_ARGV 13 #define AA_CLASS_NETV8 14 #define AA_CLASS_LABEL 16 #define AA_CLASS_POSIX_MQUEUE 17 #define AA_CLASS_SYSV_MQUEUE 18 +#define AA_CLASS_MODULE 19 +#define AA_CLASS_DISPLAY_LSM 20 #define AA_CLASS_NS 21 +#define AA_CLASS_IO_URING 22 +#define AA_CLASS_X 31 /* defined in libapparmor's apparmor.h #define AA_CLASS_DBUS 32 */ -#define AA_CLASS_X 33 + +extern const char *aa_class_table[]; #endif /* __AA_POLICYDB_H */ diff --git a/parser/ptrace.cc b/parser/ptrace.cc index 1570e80cd..8d16f98ca 100644 --- a/parser/ptrace.cc +++ b/parser/ptrace.cc @@ -48,7 +48,7 @@ void ptrace_rule::move_conditionals(struct cond_entry *conds) } ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): - peer_label(NULL) + perms_rule_t(AA_CLASS_PTRACE), peer_label(NULL) { if (perms_p) { if (perms_p & ~AA_VALID_PTRACE_PERMS) @@ -64,9 +64,7 @@ ptrace_rule::ptrace_rule(perms_t perms_p, struct cond_entry *conds): ostream &ptrace_rule::dump(ostream &os) { - prefix_rule_t::dump(os); - - os << "ptrace"; + class_rule_t::dump(os); /* override default perm dump */ if (perms != AA_VALID_PTRACE_PERMS) { diff --git a/parser/rule.cc b/parser/rule.cc index d30fef28d..e4fff0b69 100644 --- a/parser/rule.cc +++ b/parser/rule.cc @@ -19,6 +19,43 @@ #include "parser.h" #include +const char *aa_class_table[] = { + "nullcond", + "unknown", + "file", + "capability", + "network", + "rlimit", + "domain", + "mount", + "unknown8", + "ptrace", + "signal", + "xmatch", + "env", + "argv", + "network", + "unknown15", + "label", + "mqueue", + "mqueue", + "module", + "display_lsm", + "userns", + "io_uring", + "unknown23", + "unknown24", + "unknown25", + "unknown26", + "unknown27", + "unknown28", + "unknown29", + "unknown30", + "X", + "dbus", + NULL +}; + std::ostream &operator<<(std::ostream &os, rule_t &rule) { return rule.dump(os); diff --git a/parser/rule.h b/parser/rule.h index e40d5902a..c57deb3ee 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -190,9 +190,27 @@ public: }; -class perms_rule_t: public prefix_rule_t { +class class_rule_t: public prefix_rule_t { public: - perms_rule_t(): perms(0) { }; + int aa_class; + + class_rule_t(int c) { + aa_class = c; + } + + virtual ostream &dump(ostream &os) { + prefix_rule_t::dump(os); + + os << aa_class_table[aa_class]; + + return os; + } + +}; + +class perms_rule_t: public class_rule_t { +public: + perms_rule_t(int c): class_rule_t(c), perms(0) { }; /* defaut perms, override/mask off if none default used */ virtual ostream &dump(ostream &os) { diff --git a/parser/signal.cc b/parser/signal.cc index a1af31463..5e3eff701 100644 --- a/parser/signal.cc +++ b/parser/signal.cc @@ -174,7 +174,7 @@ void signal_rule::move_conditionals(struct cond_entry *conds) } signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): - signals(), peer_label(NULL) + perms_rule_t(AA_CLASS_SIGNAL), signals(), peer_label(NULL) { if (perms_p) { perms = perms_p; @@ -191,9 +191,7 @@ signal_rule::signal_rule(perms_t perms_p, struct cond_entry *conds): ostream &signal_rule::dump(ostream &os) { - prefix_rule_t::dump(os); - - os << "signal"; + class_rule_t::dump(os); if (perms != AA_VALID_SIGNAL_PERMS) { os << " ("; diff --git a/parser/userns.cc b/parser/userns.cc index 19bc0f787..c868bebb0 100644 --- a/parser/userns.cc +++ b/parser/userns.cc @@ -40,7 +40,8 @@ void userns_rule::move_conditionals(struct cond_entry *conds) } } -userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds) +userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds): + perms_rule_t(AA_CLASS_NS) { if (perms_p) { if (perms_p & ~AA_VALID_USERNS_PERMS) @@ -58,13 +59,11 @@ userns_rule::userns_rule(perms_t perms_p, struct cond_entry *conds) ostream &userns_rule::dump(ostream &os) { - prefix_rule_t::dump(os); - - os << "userns "; + class_rule_t::dump(os); if (perms != AA_VALID_USERNS_PERMS) { if (perms & AA_USERNS_CREATE) - os << "create "; + os << " create"; } os << ",\n"; From e248014171121e6b06572e110ffdd54679472249 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Tue, 21 Sep 2021 03:35:45 -0700 Subject: [PATCH 18/25] parser: carry a rule_t on all rules not just rules that have a class In preparation for rule comparison and elemination have each rule carry a type that can be used as the base of comparison. The rule class is folded into this type. Signed-off-by: John Johansen --- parser/rule.h | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/parser/rule.h b/parser/rule.h index c57deb3ee..2d9832c3e 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -31,10 +31,22 @@ class Profile; #define RULE_ERROR -1 #define RULE_OK 1 +#define RULE_TYPE_RULE 0 +#define RULE_TYPE_PREFIX 1 +#define RULE_TYPE_PERMS 2 +// RULE_TYPE_CLASS needs to be last because various class follow it +#define RULE_TYPE_CLASS 3 + + class rule_t { public: + int rule_type; + + rule_t(int t): rule_type(t) { } virtual ~rule_t() { }; + bool is_type(int type) { return rule_type == type; } + //virtual bool operator<(rule_t const &rhs)const = 0; virtual std::ostream &dump(std::ostream &os) = 0; @@ -127,7 +139,7 @@ public: class prefix_rule_t: public rule_t, public prefixes { public: - prefix_rule_t() + prefix_rule_t(int t = RULE_TYPE_PREFIX) : rule_t(t) { /* Must construct prefix here see note on prefixes */ audit = AUDIT_UNSPECIFIED; @@ -190,18 +202,17 @@ public: }; +/* NOTE: rule_type is RULE_TYPE_CLASS + AA_CLASS */ class class_rule_t: public prefix_rule_t { public: - int aa_class; + class_rule_t(int c): prefix_rule_t(RULE_TYPE_CLASS + c) { } - class_rule_t(int c) { - aa_class = c; - } + int aa_class(void) { return rule_type - RULE_TYPE_CLASS; } virtual ostream &dump(ostream &os) { prefix_rule_t::dump(os); - os << aa_class_table[aa_class]; + os << aa_class_table[aa_class()]; return os; } From 1acc90e06a6b6a9b2b457c6478aa6878b6913ac0 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sun, 19 Sep 2021 00:39:28 -0700 Subject: [PATCH 19/25] parser: add method to test if rules are mergeable/dedupable. in preparation for file rules switching to rule_t add a method to indicate whether a particular rule is mergeable/dedupable. Whether a rule merges or dedups will be up to the rules comparison and merge methods. Signed-off-by: John Johansen --- parser/rule.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/parser/rule.h b/parser/rule.h index 2d9832c3e..053dfeb8e 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -64,6 +64,13 @@ public: // to support expansion in include names and profile names virtual int expand_variables(void) = 0; + // called by duplicate rule merge/elimination after final expand_vars + virtual bool is_mergeable(void) { return false; } + virtual bool operator<(rule_t const &rhs) const { + return rule_type < rhs.rule_type; + } + virtual bool merge(rule_t &rhs __attribute__ ((unused))) { return false; }; + // called late frontend to generate data for regex backend virtual int gen_policy_re(Profile &prof) = 0; @@ -194,6 +201,23 @@ public: return true; } + virtual bool operator<(prefixes const &rhs) const { + if ((uint) audit < (uint) rhs.audit) + return true; + if ((uint) rule_mode < (uint) rhs.rule_mode) + return true; + if (owner < rhs.owner) + return true; + return false; + } + virtual bool operator<(prefix_rule_t const &rhs) const { + if (rule_type < rhs.rule_type) + return true; + if (rhs.rule_type < rule_type) + return false; + return *this < (prefixes const &)rhs; + } + virtual ostream &dump(ostream &os) { prefixes::dump(os); From b061155c9a07e3cd21aa1e9ee950eba3afda595d Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sun, 19 Sep 2021 00:59:45 -0700 Subject: [PATCH 20/25] parser: add flags to rule_t In preparation for file rules and rule duplication removal add flags to rule_t with the first flag indicating if the rule is deleted. We do this instead of actually deleting the rule so we can hold on to the rule for debug and printing output in the future. Signed-off-by: John Johansen --- parser/parser_regex.c | 2 ++ parser/parser_variable.c | 4 +++- parser/profile.cc | 5 ++++- parser/rule.h | 12 +++++++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/parser/parser_regex.c b/parser/parser_regex.c index fa3b42ad7..f5df1635d 100644 --- a/parser/parser_regex.c +++ b/parser/parser_regex.c @@ -843,6 +843,8 @@ int clear_and_convert_entry(std::string& buffer, char *entry) int post_process_policydb_ents(Profile *prof) { for (RuleList::iterator i = prof->rule_ents.begin(); i != prof->rule_ents.end(); i++) { + if ((*i)->flags & RULE_FLAG_DELETED) + continue; if ((*i)->gen_policy_re(*prof) == RULE_ERROR) return FALSE; } diff --git a/parser/parser_variable.c b/parser/parser_variable.c index 3665fe773..15978538b 100644 --- a/parser/parser_variable.c +++ b/parser/parser_variable.c @@ -267,7 +267,9 @@ static int process_variables_in_entries(struct cod_entry *entry_list) static int process_variables_in_rules(Profile &prof) { for (RuleList::iterator i = prof.rule_ents.begin(); i != prof.rule_ents.end(); i++) { - int error = (*i)->expand_variables(); + if ((*i)->flags & RULE_FLAG_DELETED) + continue; + int error = (*i)->expand_variables(); if (error) return error; } diff --git a/parser/profile.cc b/parser/profile.cc index 79095d1d8..54ca6b9b5 100644 --- a/parser/profile.cc +++ b/parser/profile.cc @@ -280,8 +280,11 @@ void post_process_file_entries(Profile *prof) void post_process_rule_entries(Profile *prof) { - for (RuleList::iterator i = prof->rule_ents.begin(); i != prof->rule_ents.end(); i++) + for (RuleList::iterator i = prof->rule_ents.begin(); i != prof->rule_ents.end(); i++) { + if ((*i)->flags & RULE_FLAG_DELETED) + continue; (*i)->post_parse_profile(*prof); + } } diff --git a/parser/rule.h b/parser/rule.h index 053dfeb8e..5a59af9ad 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -38,11 +38,21 @@ class Profile; #define RULE_TYPE_CLASS 3 +typedef enum { RULE_FLAG_NONE = 0, + RULE_FLAG_DELETED = 1, // rule deleted - skip + RULE_FLAG_MERGED = 2, // rule merged with another rule + RULE_FLAG_EXPANDED = 4, // variable expanded + RULE_FLAG_SUB = 8, // rule expanded to subrule(s) + RULE_FLAG_IMPLIED = 16, // rule not specified in policy but + // added because it is implied +} rule_flags_t; + class rule_t { public: int rule_type; + rule_flags_t flags; - rule_t(int t): rule_type(t) { } + rule_t(int t): rule_type(t), flags(RULE_FLAG_NONE) { } virtual ~rule_t() { }; bool is_type(int type) { return rule_type == type; } From 8470760e85645a4077ea653cc9acc917eaab32c8 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 16 Oct 2021 02:18:44 -0700 Subject: [PATCH 21/25] parser: add an integer based rule comparison that can be used by merge Instead of call operator< twice for merge have an integer based comparison fn. Signed-off-by: John Johansen --- parser/rule.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/parser/rule.h b/parser/rule.h index 5a59af9ad..caf8ae904 100644 --- a/parser/rule.h +++ b/parser/rule.h @@ -76,9 +76,12 @@ public: // called by duplicate rule merge/elimination after final expand_vars virtual bool is_mergeable(void) { return false; } - virtual bool operator<(rule_t const &rhs) const { + virtual int cmp(rule_t const &rhs) const { return rule_type < rhs.rule_type; } + virtual bool operator<(rule_t const &rhs) const { + return cmp(rhs) < 0; + } virtual bool merge(rule_t &rhs __attribute__ ((unused))) { return false; }; // called late frontend to generate data for regex backend From dad26e6cd219f2572a30df657b0560d55de68a29 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sat, 16 Oct 2021 03:00:26 -0700 Subject: [PATCH 22/25] parser: add a method for profiles to do rule merging In preparation for file rules converting to use rule_t add a method to do rule merging. Signed-off-by: John Johansen --- parser/profile.cc | 37 +++++++++++++++++++++++++++++++++++++ parser/profile.h | 6 ++++++ 2 files changed, 43 insertions(+) diff --git a/parser/profile.cc b/parser/profile.cc index 54ca6b9b5..27fe570ee 100644 --- a/parser/profile.cc +++ b/parser/profile.cc @@ -18,6 +18,8 @@ #include #include +#include +#include const char *profile_mode_table[] = { "", @@ -119,6 +121,41 @@ Profile::~Profile() free(net.quiet); } +static bool comp (rule_t *lhs, rule_t *rhs) { return (*lhs < *rhs); } + +bool Profile::merge_rules(void) +{ + int count = 0; + + for (RuleList::iterator i = rule_ents.begin(); i != rule_ents.end(); ) { + if ((*i)->is_mergeable()) + count++; + } + if (count < 2) + return 0; + + std::vector table(count); + int n = 0; + for (RuleList::iterator i = rule_ents.begin(); i != rule_ents.end(); ) { + if ((*i)->is_mergeable()) + table[n++] = *i; + } + + std::sort(table.begin(), table.end(), comp); + + for (int i = 0, j = 1; j < count; j++) { + if (table[i]->cmp(*table[j]) == 0) { + if (!table[i]->merge(*table[j])) + return false; + continue; + } + i = j; + } + + return true; +} + + int add_entry_to_x_table(Profile *prof, char *name) { int i; diff --git a/parser/profile.h b/parser/profile.h index e324d9f1d..80ffd20e1 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -251,6 +251,12 @@ public: return strcmp(name, rhs.name) < 0; } + /* + * Requires the merged rules have customized methods + * cmp(), is_mergeable() and merge() + */ + virtual bool merge_rules(void); + void dump(void) { if (ns) From 9eb23475de9e9729c2a7b29fcd5913338e30650c Mon Sep 17 00:00:00 2001 From: John Johansen Date: Sun, 19 Feb 2023 02:41:22 -0800 Subject: [PATCH 23/25] parser: refactor rules parser for a common block Another step towards having a block rule and retaining parsed rule structure. Setup the parse to use a common block pattern, that when we are ready will become an actual rule. Signed-off-by: John Johansen --- parser/parser_yacc.y | 39 ++++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 476f2e8f6..1bfacc9e7 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -227,6 +227,7 @@ void add_local_entry(Profile *prof); %type profile_base %type profile %type rules +%type block %type hat %type local_profile %type cond_rule @@ -708,8 +709,12 @@ rules: rules opt_prefix rule $$ = $1; }; +block: TOK_OPEN rules TOK_CLOSE + { + $$ = $2; + }; -rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE +rules: rules opt_prefix block { struct cod_entry *entry, *tmp; if ($2.rule_mode == RULE_DENY) @@ -717,7 +722,7 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE PDEBUG("matched: %s%s%sblock\n", $2.audit == AUDIT_FORCE ? "audit " : "", $2.rule_mode == RULE_DENY ? "deny " : "", $2.owner ? "owner " : ""); - list_for_each_safe($4->entries, entry, tmp) { + list_for_each_safe($3->entries, entry, tmp) { entry->next = NULL; if (entry->perms & AA_EXEC_BITS) { if ((entry->rule_mode == RULE_DENY) && @@ -738,9 +743,9 @@ rules: rules opt_prefix TOK_OPEN rules TOK_CLOSE entry->audit = AUDIT_FORCE; add_entry_to_policy($1, entry); } - $4->entries = NULL; + $3->entries = NULL; // fix me transfer rules and free sub profile - delete $4; + delete $3; $$ = $1; }; @@ -974,42 +979,42 @@ rules: rules TOK_SET TOK_RLIMIT TOK_ID TOK_LE TOK_VALUE opt_id TOK_END_OF_RULE }; -cond_rule: TOK_IF expr TOK_OPEN rules TOK_CLOSE +cond_rule: TOK_IF expr block { Profile *ret = NULL; PDEBUG("Matched: found conditional rules\n"); if ($2) { - ret = $4; + ret = $3; } else { - delete $4; + delete $3; } $$ = ret; } -cond_rule: TOK_IF expr TOK_OPEN rules TOK_CLOSE TOK_ELSE TOK_OPEN rules TOK_CLOSE +cond_rule: TOK_IF expr block TOK_ELSE block { Profile *ret = NULL; PDEBUG("Matched: found conditional else rules\n"); if ($2) { - ret = $4; - delete $8; + ret = $3; + delete $5; } else { - ret = $8; - delete $4; + ret = $5; + delete $3; } $$ = ret; } -cond_rule: TOK_IF expr TOK_OPEN rules TOK_CLOSE TOK_ELSE cond_rule +cond_rule: TOK_IF expr block TOK_ELSE cond_rule { Profile *ret = NULL; PDEBUG("Matched: found conditional else-if rules\n"); if ($2) { - ret = $4; - delete $7; + ret = $3; + delete $5; } else { - ret = $7; - delete $4; + ret = $5; + delete $3; } $$ = ret; } From 68421547a12fbc98a92f082d1ceec0e8b30a4731 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Tue, 21 Feb 2023 02:02:02 -0800 Subject: [PATCH 24/25] refactor prefix and x check during parser Reduce duplicate code and another step towards converting file rules to rule_t Signed-off-by: John Johansen --- parser/parser_yacc.y | 88 +++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 34 deletions(-) diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 1bfacc9e7..4709fd24a 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -71,6 +71,8 @@ mnt_rule *do_pivot_rule(struct cond_entry *old, char *root, char *transition); static void abi_features(char *filename, bool search); void add_local_entry(Profile *prof); +bool add_prefix(struct cod_entry *entry, const prefixes &p, const char *&error); +bool check_x_qualifier(struct cod_entry *entry, const char *&errror); %} @@ -685,26 +687,14 @@ rules: rules abi_rule { /* nothing */ } rules: rules opt_prefix rule { + const char *error; PDEBUG("matched: rules rule\n"); PDEBUG("rules rule: (%s)\n", $3->name); if (!$3) yyerror(_("Assert: `rule' returned NULL.")); - $3->rule_mode = $2.rule_mode; - if ((($2.rule_mode == RULE_DENY) && ($3->perms & AA_EXEC_BITS) && - ($3->perms & ALL_AA_EXEC_TYPE))) - yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); - else if (($2.rule_mode != RULE_DENY) && ($3->perms & AA_EXEC_BITS) && - !($3->perms & ALL_AA_EXEC_TYPE) && - !($3->nt_name)) - yyerror(_("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', 'c', or 'u'")); - - if ($2.owner == 1) - $3->perms &= (AA_USER_PERMS | AA_SHARED_PERMS); - else if ($2.owner == 2) - $3->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); - /* only set audit ctl quieting if the rule is not audited */ - if ((($2.rule_mode == RULE_DENY) && $2.audit != AUDIT_FORCE) || (($2.rule_mode != RULE_DENY) && $2.audit == AUDIT_FORCE)) - $3->audit = AUDIT_FORCE; + if (!add_prefix($3, $2, error)) { + yyerror(_("%s"), error); + } add_entry_to_policy($1, $3); $$ = $1; }; @@ -717,30 +707,19 @@ block: TOK_OPEN rules TOK_CLOSE rules: rules opt_prefix block { struct cod_entry *entry, *tmp; - if ($2.rule_mode == RULE_DENY) - yyerror(_("deny prefix not allowed")); PDEBUG("matched: %s%s%sblock\n", $2.audit == AUDIT_FORCE ? "audit " : "", $2.rule_mode == RULE_DENY ? "deny " : "", $2.owner ? "owner " : ""); list_for_each_safe($3->entries, entry, tmp) { + const char *error; entry->next = NULL; - if (entry->perms & AA_EXEC_BITS) { - if ((entry->rule_mode == RULE_DENY) && - (entry->perms & ALL_AA_EXEC_TYPE)) - yyerror(_("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); - else if ((entry->rule_mode != RULE_DENY) && - !(entry->perms & ALL_AA_EXEC_TYPE)) - yyerror(_("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'")); + if (!add_prefix(entry, $2, error)) { + yyerror(_("%s"), error); } - if ($2.owner == 1) - entry->perms &= (AA_USER_PERMS | AA_SHARED_PERMS); - else if ($2.owner == 2) - entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); - - if ($2.audit == AUDIT_FORCE && (entry->rule_mode != RULE_DENY)) - entry->audit = AUDIT_FORCE; - else if ($2.audit != AUDIT_FORCE && (entry->rule_mode == RULE_DENY)) - entry->audit = AUDIT_FORCE; + /* transfer rule for now, TODO keep block and just + * apply add_prefix to block rule and have it do + * the work + */ add_entry_to_policy($1, entry); } $3->entries = NULL; @@ -1868,3 +1847,44 @@ static void abi_features(char *filename, bool search) } }; + +bool check_x_qualifier(struct cod_entry *entry, const char *&error) +{ + if (entry->perms & AA_EXEC_BITS) { + if ((entry->rule_mode == RULE_DENY) && + (entry->perms & ALL_AA_EXEC_TYPE)) { + error = _("Invalid perms, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"); + return false; + } else if ((entry->rule_mode != RULE_DENY) && + !(entry->perms & ALL_AA_EXEC_TYPE)) { + error = _("Invalid perms, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"); + return false; + } + } + return true; +} + +// cod_entry version of ->add_prefix here just as file rules aren't converted yet +bool add_prefix(struct cod_entry *entry, const prefixes &p, const char *&error) +{ + /* modifiers aren't correctly stored for cod_entries yet so + * we can't conflict on them easily. Leave that until conversion + * to rule_t + */ + /* apply rule mode */ + entry->rule_mode = p.rule_mode; + + /* apply owner/other */ + if (p.owner == 1) + entry->perms &= (AA_USER_PERMS | AA_SHARED_PERMS); + else if (p.owner == 2) + entry->perms &= (AA_OTHER_PERMS | AA_SHARED_PERMS); + + /* implied audit modifier */ + if (p.audit == AUDIT_FORCE && (entry->rule_mode != RULE_DENY)) + entry->audit = AUDIT_FORCE; + else if (p.audit != AUDIT_FORCE && (entry->rule_mode == RULE_DENY)) + entry->audit = AUDIT_FORCE; + + return check_x_qualifier(entry, error); +} From e6e3f44ff9b45a1995b2e176bebee7379b6ae789 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 22 Feb 2023 17:19:12 -0800 Subject: [PATCH 25/25] parser: cleanup: drop unused add_local_entry and associated vars The code for add_local_entry is actually currently unused and will have to change anyways by the time it is. Some drop it and the associated variables. Signed-off-by: John Johansen --- parser/parser_yacc.y | 28 ---------------------------- parser/profile.h | 18 +++++------------- 2 files changed, 5 insertions(+), 41 deletions(-) diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index 4709fd24a..91a4ffaff 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -70,7 +70,6 @@ mnt_rule *do_mnt_rule(struct cond_entry *src_conds, char *src, mnt_rule *do_pivot_rule(struct cond_entry *old, char *root, char *transition); static void abi_features(char *filename, bool search); -void add_local_entry(Profile *prof); bool add_prefix(struct cod_entry *entry, const prefixes &p, const char *&error); bool check_x_qualifier(struct cod_entry *entry, const char *&errror); @@ -438,7 +437,6 @@ local_profile: TOK_PROFILE profile_base if ($2) PDEBUG("Matched: local profile %s { ... }\n", prof->name); - prof->local = 1; $$ = prof; }; @@ -849,7 +847,6 @@ rules: rules local_profile if (!$2) yyerror(_("Assert: 'local_profile rule' returned NULL.")); add_hat_to_policy($1, $2); - add_local_entry($2); $$ = $1; }; @@ -1695,31 +1692,6 @@ struct cod_entry *do_file_rule(char *id, perms_t perms, char *link_id, char *nt) return entry; } -/* Note: NOT currently in use, used for - * /foo x -> { /bah, } style transitions - */ -void add_local_entry(Profile *prof) -{ - /* ugh this has to be called after the hat is attached to its parent */ - if (prof->local_perms) { - struct cod_entry *entry; - char *trans = (char *) malloc(strlen(prof->parent->name) + - strlen(prof->name) + 3); - char *name = strdup(prof->name); - if (!trans) - yyerror(_("Memory allocation error.")); - sprintf(name, "%s//%s", prof->parent->name, prof->name); - - entry = new_entry(name, prof->local_perms, NULL); - entry->audit = prof->local_audit; - entry->nt_name = trans; - if (!entry) - yyerror(_("Memory allocation error.")); - - add_entry_to_policy(prof, entry); - } -} - static const char *mnt_cond_msg[] = {"", " not allowed as source conditional", " not allowed as target conditional", diff --git a/parser/profile.h b/parser/profile.h index 80ffd20e1..683e97695 100644 --- a/parser/profile.h +++ b/parser/profile.h @@ -189,9 +189,7 @@ public: /* char *sub_name; */ /* subdomain name or NULL */ /* int default_deny; */ /* TRUE or FALSE */ - int local; - perms_t local_perms; - audit_t local_audit; + bool local; Profile *parent; @@ -221,10 +219,6 @@ public: xattrs.list = NULL; xattrs.name = NULL; - local_perms = 0; - local = 0; - local_audit = AUDIT_UNSPECIFIED; - parent = NULL; flags = { 0, MODE_UNSPECIFIED, 0, 0 }; @@ -267,12 +261,10 @@ public: else printf("Name:\t\t\n"); - if (local) { - if (parent) - printf("Local To:\t%s\n", parent->name); - else - printf("Local To:\t\n"); - } + if (parent) + printf("Local To:\t%s\n", parent->name); + else + printf("Local To:\t\n"); flags.dump(cerr); caps.dump();