mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-22 10:07:12 +00:00
fix: the what names can treated as a condlistid
The match {VARIABLE_NAME}/{WS}*={WS}*\( is too broad causing mount and dbus rules to fail for sets of values eg. mount options=(ro bind) Instead of doing a broad match, for now lets lock it down to just peer=(...) being the only cond that can cause entry into CONDLISTID Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
b222731c4f
commit
f19c9f9511
@ -38,16 +38,6 @@ int parse_dbus_mode(const char *str_mode, int *mode, int fail)
|
|||||||
return parse_X_mode("DBus", AA_VALID_DBUS_PERMS, str_mode, mode, fail);
|
return parse_X_mode("DBus", AA_VALID_DBUS_PERMS, str_mode, mode, fail);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void move_conditional_value(char **dst_ptr, struct cond_entry *cond_ent)
|
|
||||||
{
|
|
||||||
if (*dst_ptr)
|
|
||||||
yyerror("dbus conditional \"%s\" can only be specified once\n",
|
|
||||||
cond_ent->name);
|
|
||||||
|
|
||||||
*dst_ptr = cond_ent->vals->value;
|
|
||||||
cond_ent->vals->value = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dbus_rule::move_conditionals(struct cond_entry *conds)
|
void dbus_rule::move_conditionals(struct cond_entry *conds)
|
||||||
{
|
{
|
||||||
struct cond_entry *cond_ent;
|
struct cond_entry *cond_ent;
|
||||||
@ -61,17 +51,17 @@ void dbus_rule::move_conditionals(struct cond_entry *conds)
|
|||||||
cond_ent->name);
|
cond_ent->name);
|
||||||
|
|
||||||
if (strcmp(cond_ent->name, "bus") == 0) {
|
if (strcmp(cond_ent->name, "bus") == 0) {
|
||||||
move_conditional_value(&bus, cond_ent);
|
move_conditional_value("dbus", &bus, cond_ent);
|
||||||
} else if (strcmp(cond_ent->name, "name") == 0) {
|
} else if (strcmp(cond_ent->name, "name") == 0) {
|
||||||
move_conditional_value(&name, cond_ent);
|
move_conditional_value("dbus", &name, cond_ent);
|
||||||
} else if (strcmp(cond_ent->name, "label") == 0) {
|
} else if (strcmp(cond_ent->name, "label") == 0) {
|
||||||
move_conditional_value(&peer_label, cond_ent);
|
move_conditional_value("dbus", &peer_label, cond_ent);
|
||||||
} else if (strcmp(cond_ent->name, "path") == 0) {
|
} else if (strcmp(cond_ent->name, "path") == 0) {
|
||||||
move_conditional_value(&path, cond_ent);
|
move_conditional_value("dbus", &path, cond_ent);
|
||||||
} else if (strcmp(cond_ent->name, "interface") == 0) {
|
} else if (strcmp(cond_ent->name, "interface") == 0) {
|
||||||
move_conditional_value(&interface, cond_ent);
|
move_conditional_value("dbus", &interface, cond_ent);
|
||||||
} else if (strcmp(cond_ent->name, "member") == 0) {
|
} else if (strcmp(cond_ent->name, "member") == 0) {
|
||||||
move_conditional_value(&member, cond_ent);
|
move_conditional_value("dbus", &member, cond_ent);
|
||||||
} else {
|
} else {
|
||||||
yyerror("invalid dbus conditional \"%s\"\n",
|
yyerror("invalid dbus conditional \"%s\"\n",
|
||||||
cond_ent->name);
|
cond_ent->name);
|
||||||
|
@ -78,6 +78,12 @@ struct cond_entry {
|
|||||||
struct cond_entry *next;
|
struct cond_entry *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cond_entry_list {
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
struct cond_entry *list;
|
||||||
|
};
|
||||||
|
|
||||||
struct cod_entry {
|
struct cod_entry {
|
||||||
char *ns;
|
char *ns;
|
||||||
char *name;
|
char *name;
|
||||||
@ -362,6 +368,8 @@ extern struct value_list *dup_value_list(struct value_list *list);
|
|||||||
extern void free_value_list(struct value_list *list);
|
extern void free_value_list(struct value_list *list);
|
||||||
extern void print_value_list(struct value_list *list);
|
extern void print_value_list(struct value_list *list);
|
||||||
extern struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list);
|
extern struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list);
|
||||||
|
extern void move_conditional_value(const char *rulename, char **dst_ptr,
|
||||||
|
struct cond_entry *cond_ent);
|
||||||
extern void free_cond_entry(struct cond_entry *ent);
|
extern void free_cond_entry(struct cond_entry *ent);
|
||||||
extern void free_cond_list(struct cond_entry *ents);
|
extern void free_cond_list(struct cond_entry *ents);
|
||||||
extern void print_cond_entry(struct cond_entry *ent);
|
extern void print_cond_entry(struct cond_entry *ent);
|
||||||
|
@ -301,20 +301,22 @@ LT_EQUAL <=
|
|||||||
}
|
}
|
||||||
|
|
||||||
<INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
|
<INITIAL,MOUNT_MODE,DBUS_MODE,SIGNAL_MODE>{
|
||||||
|
{VARIABLE_NAME}/{WS}*={WS}*\( {
|
||||||
|
/* we match to the = in the lexer so that we can switch scanner
|
||||||
|
* state. By the time the parser see the = it may be too late
|
||||||
|
* as bison may have requested the next token from the scanner
|
||||||
|
*/
|
||||||
|
yylval.id = processid(yytext, yyleng);
|
||||||
|
PUSH_AND_RETURN(EXTCONDLIST_MODE, TOK_CONDLISTID);
|
||||||
|
}
|
||||||
{VARIABLE_NAME}/{WS}*= {
|
{VARIABLE_NAME}/{WS}*= {
|
||||||
/* we match to the = in the lexer so that we can switch scanner
|
/* we match to the = in the lexer so that we can switch scanner
|
||||||
* state. By the time the parser see the = it may be too late
|
* state. By the time the parser see the = it may be too late
|
||||||
* as bison may have requested the next token from the scanner
|
* as bison may have requested the next token from the scanner
|
||||||
*/
|
*/
|
||||||
int token = get_keyword_token(yytext);
|
|
||||||
|
|
||||||
if (token == TOK_PEER) {
|
|
||||||
PUSH_AND_RETURN(EXTCONDLIST_MODE, TOK_CONDLISTID);
|
|
||||||
} else {
|
|
||||||
yylval.id = processid(yytext, yyleng);
|
yylval.id = processid(yytext, yyleng);
|
||||||
PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID);
|
PUSH_AND_RETURN(EXTCOND_MODE, TOK_CONDID);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
{VARIABLE_NAME}/{WS}+in{WS}*\( {
|
{VARIABLE_NAME}/{WS}+in{WS}*\( {
|
||||||
/* we match to 'in' in the lexer so that we can switch scanner
|
/* we match to 'in' in the lexer so that we can switch scanner
|
||||||
* state. By the time the parser see the 'in' it may be to
|
* state. By the time the parser see the 'in' it may be to
|
||||||
|
@ -1150,6 +1150,17 @@ void print_value_list(struct value_list *list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void move_conditional_value(const char *rulename, char **dst_ptr,
|
||||||
|
struct cond_entry *cond_ent)
|
||||||
|
{
|
||||||
|
if (*dst_ptr)
|
||||||
|
yyerror("%s conditional \"%s\" can only be specified once\n",
|
||||||
|
rulename, cond_ent->name);
|
||||||
|
|
||||||
|
*dst_ptr = cond_ent->vals->value;
|
||||||
|
cond_ent->vals->value = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list)
|
struct cond_entry *new_cond_entry(char *name, int eq, struct value_list *list)
|
||||||
{
|
{
|
||||||
struct cond_entry *ent = (struct cond_entry *) calloc(1, sizeof(struct cond_entry));
|
struct cond_entry *ent = (struct cond_entry *) calloc(1, sizeof(struct cond_entry));
|
||||||
|
@ -166,6 +166,7 @@ void add_local_entry(Profile *prof);
|
|||||||
%token TOK_FLAGS
|
%token TOK_FLAGS
|
||||||
|
|
||||||
%code requires {
|
%code requires {
|
||||||
|
#include "parser.h"
|
||||||
#include "profile.h"
|
#include "profile.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
#include "dbus.h"
|
#include "dbus.h"
|
||||||
@ -194,6 +195,7 @@ void add_local_entry(Profile *prof);
|
|||||||
char *var_val;
|
char *var_val;
|
||||||
struct value_list *val_list;
|
struct value_list *val_list;
|
||||||
struct cond_entry *cond_entry;
|
struct cond_entry *cond_entry;
|
||||||
|
struct cond_entry_list cond_entry_list;
|
||||||
int boolean;
|
int boolean;
|
||||||
struct named_transition transition;
|
struct named_transition transition;
|
||||||
struct prefixes prefix;
|
struct prefixes prefix;
|
||||||
@ -219,8 +221,8 @@ void add_local_entry(Profile *prof);
|
|||||||
%type <mnt_entry> mnt_rule
|
%type <mnt_entry> mnt_rule
|
||||||
%type <cond_entry> opt_conds
|
%type <cond_entry> opt_conds
|
||||||
%type <cond_entry> cond
|
%type <cond_entry> cond
|
||||||
%type <cond_entry> cond_list
|
%type <cond_entry_list> cond_list
|
||||||
%type <cond_entry> opt_cond_list
|
%type <cond_entry_list> opt_cond_list
|
||||||
%type <flags> flags
|
%type <flags> flags
|
||||||
%type <flags> flagvals
|
%type <flags> flagvals
|
||||||
%type <flags> flagval
|
%type <flags> flagval
|
||||||
@ -1145,10 +1147,11 @@ opt_conds: { /* nothing */ $$ = NULL; }
|
|||||||
|
|
||||||
cond_list: TOK_CONDLISTID TOK_EQUALS TOK_OPENPAREN opt_conds TOK_CLOSEPAREN
|
cond_list: TOK_CONDLISTID TOK_EQUALS TOK_OPENPAREN opt_conds TOK_CLOSEPAREN
|
||||||
{
|
{
|
||||||
$$ = $4;
|
$$.name = $1;
|
||||||
|
$$.list = $4;
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_cond_list: { /* nothing */ $$ = NULL; }
|
opt_cond_list: { /* nothing */ $$ = { NULL, NULL }; }
|
||||||
| cond_list { $$ = $1; }
|
| cond_list { $$ = $1; }
|
||||||
|
|
||||||
mnt_rule: TOK_MOUNT opt_conds opt_id TOK_END_OF_RULE
|
mnt_rule: TOK_MOUNT opt_conds opt_id TOK_END_OF_RULE
|
||||||
@ -1232,7 +1235,12 @@ dbus_rule: TOK_DBUS opt_dbus_perm opt_conds opt_cond_list TOK_END_OF_RULE
|
|||||||
{
|
{
|
||||||
dbus_rule *ent;
|
dbus_rule *ent;
|
||||||
|
|
||||||
ent = new dbus_rule($2, $3, $4);
|
if ($4.name) {
|
||||||
|
if (strcmp($4.name, "peer") != 0)
|
||||||
|
yyerror(_("dbus rule: invalid conditional group %s=()"), $4.name);
|
||||||
|
free($4.name);
|
||||||
|
}
|
||||||
|
ent = new dbus_rule($2, $3, $4.list);
|
||||||
if (!ent) {
|
if (!ent) {
|
||||||
yyerror(_("Memory allocation error."));
|
yyerror(_("Memory allocation error."));
|
||||||
}
|
}
|
||||||
@ -1273,12 +1281,7 @@ opt_signal_perm: { /* nothing */ $$ = 0; }
|
|||||||
|
|
||||||
signal_rule: TOK_SIGNAL opt_signal_perm opt_conds TOK_END_OF_RULE
|
signal_rule: TOK_SIGNAL opt_signal_perm opt_conds TOK_END_OF_RULE
|
||||||
{
|
{
|
||||||
signal_rule *ent = new signal_rule($2, $3, NULL);
|
signal_rule *ent = new signal_rule($2, $3);
|
||||||
$$ = ent;
|
|
||||||
}
|
|
||||||
| TOK_SIGNAL opt_signal_perm opt_conds TOK_ID TOK_END_OF_RULE
|
|
||||||
{
|
|
||||||
signal_rule *ent = new signal_rule($2, $3, $4);
|
|
||||||
$$ = ent;
|
$$ = ent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +165,8 @@ void signal_rule::move_conditionals(struct cond_entry *conds)
|
|||||||
yyerror("keyword \"in\" is not allowed in signal rules\n");
|
yyerror("keyword \"in\" is not allowed in signal rules\n");
|
||||||
if (strcmp(cond_ent->name, "set") == 0) {
|
if (strcmp(cond_ent->name, "set") == 0) {
|
||||||
extract_sigs(&cond_ent->vals);
|
extract_sigs(&cond_ent->vals);
|
||||||
|
} else if (strcmp(cond_ent->name, "peer") == 0) {
|
||||||
|
move_conditional_value("signal", &peer_label, cond_ent);
|
||||||
} else {
|
} else {
|
||||||
yyerror("invalid signal rule conditional \"%s\"\n",
|
yyerror("invalid signal rule conditional \"%s\"\n",
|
||||||
cond_ent->name);
|
cond_ent->name);
|
||||||
@ -172,9 +174,8 @@ void signal_rule::move_conditionals(struct cond_entry *conds)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
signal_rule::signal_rule(int mode_p, struct cond_entry *conds,
|
signal_rule::signal_rule(int mode_p, struct cond_entry *conds):
|
||||||
char *peer):
|
signals(), peer_label(NULL), audit(0), deny(0)
|
||||||
signals(), peer_label(peer), audit(0), deny(0)
|
|
||||||
{
|
{
|
||||||
if (mode_p) {
|
if (mode_p) {
|
||||||
mode = mode_p;
|
mode = mode_p;
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
int audit;
|
int audit;
|
||||||
int deny;
|
int deny;
|
||||||
|
|
||||||
signal_rule(int mode, struct cond_entry *conds, char *peer);
|
signal_rule(int mode, struct cond_entry *conds);
|
||||||
virtual ~signal_rule() {
|
virtual ~signal_rule() {
|
||||||
signals.clear();
|
signals.clear();
|
||||||
free(peer_label);
|
free(peer_label);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user