diff --git a/.gitignore b/.gitignore index fbc2bfb70..8f9a1191b 100644 --- a/.gitignore +++ b/.gitignore @@ -28,42 +28,9 @@ parser/parser_version.h parser/parser_yacc.c parser/parser_yacc.h parser/pod2htm*.tmp -parser/af_rule.o -parser/af_unix.o -parser/all_rule.o -parser/common_optarg.o -parser/dbus.o -parser/default_features.o -parser/lib.o -parser/libapparmor_re/aare_rules.o -parser/libapparmor_re/chfa.o -parser/libapparmor_re/expr-tree.o -parser/libapparmor_re/hfa.o +parser/libapparmor_re/*.o parser/libapparmor_re/libapparmor_re.a -parser/libapparmor_re/parse.o -parser/mount.o -parser/mqueue.o -parser/network.o -parser/parser_alias.o -parser/parser_common.o -parser/parser_include.o -parser/parser_interface.o -parser/parser_lex.o -parser/parser_main.o -parser/parser_merge.o -parser/parser_misc.o -parser/parser_policy.o -parser/parser_regex.o -parser/parser_symtab.o -parser/parser_variable.o -parser/parser_yacc.o -parser/policy_cache.o -parser/profile.o -parser/ptrace.o -parser/rule.o -parser/signal.o -parser/userns.o -parser/io_uring.o +parser/*.o parser/*.7 parser/*.5 parser/*.8 diff --git a/parser/Makefile b/parser/Makefile index 7e36a2851..1037f4c7b 100644 --- a/parser/Makefile +++ b/parser/Makefile @@ -105,12 +105,12 @@ SRCS = parser_common.c parser_include.c parser_interface.c parser_lex.c \ parser_alias.c common_optarg.c lib.c network.cc \ 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 io_uring.cc all_rule.cc + mqueue.cc io_uring.cc all_rule.cc cond_expr.cc 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 io_uring.h \ - common_flags.h bignum.h all_rule.h + common_flags.h bignum.h all_rule.h cond_expr.h SPECIAL_HDRS = parser_yacc.h unit_test.h base_cap_names.h GENERATED_HDRS = af_names.h generated_af_names.h \ @@ -328,6 +328,9 @@ io_uring.o: io_uring.cc $(HDRS) all_rule.o: all_rule.cc $(HDRS) $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< +cond_expr.o: cond_expr.cc $(HDRS) + $(CXX) $(EXTRA_CFLAGS) -c -o $@ $< + parser_version.h: Makefile @echo \#define PARSER_VERSION \"$(VERSION)\" > .ver @mv -f .ver $@ diff --git a/parser/cond_expr.cc b/parser/cond_expr.cc new file mode 100644 index 000000000..2a7c6ef94 --- /dev/null +++ b/parser/cond_expr.cc @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024 + * Canonical Ltd. (All rights reserved) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, contact Novell, Inc. or Canonical + * Ltd. + */ + +#include "cond_expr.h" +#include "parser.h" + +cond_expr::cond_expr(bool result): + result(result) +{ +} + +cond_expr::cond_expr(const char *var, bool defined) +{ + char *var_name = process_var(var); + + if (!defined) { + int ret = get_boolean_var(var_name); + if (ret < 0) { + /* FIXME check for set var */ + free(var_name); + yyerror(_("Unset boolean variable %s used in if-expression"), var); + } + result = ret; + } else { + void *set_value = get_set_var(var_name); + PDEBUG("Matched: defined set expr %s value %lx\n", var_name, (long) set_value); + result = !! (long) set_value; + } + free(var_name); +} diff --git a/parser/cond_expr.h b/parser/cond_expr.h new file mode 100644 index 000000000..13bd8d524 --- /dev/null +++ b/parser/cond_expr.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2024 + * Canonical Ltd. (All rights reserved) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, contact Novell, Inc. or Canonical + * Ltd. + */ + +#ifndef __AA_COND_EXPR_H +#define __AA_COND_EXPR_H + +class cond_expr { +private: + bool result; +public: + cond_expr(bool result); + cond_expr(const char *var, bool defined); + virtual ~cond_expr() + { + }; + + bool eval(void) { return result; } +}; + +#endif /* __AA_COND_EXPR_H */ diff --git a/parser/parser_yacc.y b/parser/parser_yacc.y index b225fb5d0..ea0f17686 100644 --- a/parser/parser_yacc.y +++ b/parser/parser_yacc.y @@ -188,6 +188,7 @@ static void abi_features(char *filename, bool search); #include "io_uring.h" #include "network.h" #include "all_rule.h" + #include "cond_expr.h" } %union { @@ -225,6 +226,7 @@ static void abi_features(char *filename, bool search); IncludeCache_t *includecache; audit_t audit; rule_mode_t rule_mode; + cond_expr *cond; } %type TOK_ID @@ -260,7 +262,7 @@ static void abi_features(char *filename, bool search); %type TOK_BOOL_VAR %type TOK_VALUE %type valuelist -%type expr +%type expr %type id_or_var %type opt_id_or_var %type opt_subset_flag @@ -901,11 +903,12 @@ cond_rule: TOK_IF expr block { Profile *ret = NULL; PDEBUG("Matched: found conditional rules\n"); - if ($2) { + if ($2->eval()) { ret = $3; } else { delete $3; } + delete $2; $$ = ret; } @@ -913,13 +916,14 @@ cond_rule: TOK_IF expr block TOK_ELSE block { Profile *ret = NULL; PDEBUG("Matched: found conditional else rules\n"); - if ($2) { + if ($2->eval()) { ret = $3; delete $5; } else { ret = $5; delete $3; } + delete $2; $$ = ret; } @@ -927,53 +931,45 @@ cond_rule: TOK_IF expr block TOK_ELSE cond_rule { Profile *ret = NULL; PDEBUG("Matched: found conditional else-if rules\n"); - if ($2) { + if ($2->eval()) { ret = $3; delete $5; } else { ret = $5; delete $3; } + delete $2; $$ = ret; } expr: TOK_NOT expr { - $$ = !$2; + cond_expr *conds = new cond_expr(!$2->eval()); + delete $2; + $$ = conds; } expr: TOK_BOOL_VAR { - char *var_name = process_var($1); - int boolean = get_boolean_var(var_name); - PDEBUG("Matched: boolean expr %s value: %d\n", $1, boolean); - if (boolean < 0) { - /* FIXME check for set var */ - yyerror(_("Unset boolean variable %s used in if-expression"), - $1); - } - $$ = boolean; - free(var_name); + cond_expr *conds = new cond_expr($1, false); + PDEBUG("Matched: boolean expr %s value: %d\n", $1, conds->eval()); + $$ = conds; free($1); } expr: TOK_DEFINED TOK_SET_VAR { - char *var_name = process_var($2); - void *set_value = get_set_var(var_name); - PDEBUG("Matched: defined set expr %s value %lx\n", $2, (long) set_value); - $$ = !! (long) set_value; - free(var_name); + cond_expr *conds = new cond_expr($2, true); + PDEBUG("Matched: defined set expr %s value %d\n", $2, conds->eval()); + $$ = conds; free($2); } expr: TOK_DEFINED TOK_BOOL_VAR { - char *var_name = process_var($2); - int boolean = get_boolean_var(var_name); - PDEBUG("Matched: defined set expr %s value %d\n", $2, boolean); - $$ = (boolean != -1); - free(var_name); + cond_expr *conds = new cond_expr($2, false); + PDEBUG("Matched: defined set expr %s value %d\n", $2, conds->eval()); + $$ = conds; free($2); }