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 <georgia.garcia@canonical.com>
This commit is contained in:
Georgia Garcia 2024-08-14 17:16:07 -03:00
parent a50283bad0
commit 15ee7ac92c
5 changed files with 108 additions and 62 deletions

37
.gitignore vendored
View file

@ -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

View file

@ -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 $@

45
parser/cond_expr.cc Normal file
View file

@ -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);
}

35
parser/cond_expr.h Normal file
View file

@ -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 */

View file

@ -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 <id> TOK_ID
@ -260,7 +262,7 @@ static void abi_features(char *filename, bool search);
%type <bool_var> TOK_BOOL_VAR
%type <var_val> TOK_VALUE
%type <val_list> valuelist
%type <boolean> expr
%type <cond> expr
%type <id> id_or_var
%type <id> opt_id_or_var
%type <boolean> 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);
}