From 15ee7ac92c2bfbcb121c6f3a16da9ffad1de4d34 Mon Sep 17 00:00:00 2001 From: Georgia Garcia Date: Wed, 14 Aug 2024 17:16:07 -0300 Subject: [PATCH] parser: refactor conditional logic into its own class Remove conditional logic from the parser and move it to its own class, that way any improvements or conditional features will make cleaner changes. Signed-off-by: Georgia Garcia --- .gitignore | 37 ++--------------------------------- parser/Makefile | 7 +++++-- parser/cond_expr.cc | 45 +++++++++++++++++++++++++++++++++++++++++++ parser/cond_expr.h | 35 +++++++++++++++++++++++++++++++++ parser/parser_yacc.y | 46 ++++++++++++++++++++------------------------ 5 files changed, 108 insertions(+), 62 deletions(-) create mode 100644 parser/cond_expr.cc create mode 100644 parser/cond_expr.h 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); }