convert owner to an enum

provide better type checking and semantics to the owner conditional

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2023-08-03 23:21:05 -07:00
parent 07155e8e83
commit 4264338bed
6 changed files with 35 additions and 21 deletions

View file

@ -51,7 +51,7 @@ public:
free(member); free(member);
}; };
virtual bool valid_prefix(const prefixes &p, const char *&error) { virtual bool valid_prefix(const prefixes &p, const char *&error) {
if (p.owner) { if (p.owner != OWNER_UNSPECIFIED) {
error = "owner prefix not allowed on dbus rules"; error = "owner prefix not allowed on dbus rules";
return false; return false;
} }

View file

@ -163,7 +163,7 @@ public:
} }
virtual bool valid_prefix(const prefixes &p, const char *&error) { virtual bool valid_prefix(const prefixes &p, const char *&error) {
if (p.owner) { if (p.owner != OWNER_UNSPECIFIED) {
error = "owner prefix not allowed on mount rules"; error = "owner prefix not allowed on mount rules";
return false; return false;
} }

View file

@ -222,6 +222,7 @@ static void abi_features(char *filename, bool search);
struct cond_entry *cond_entry; struct cond_entry *cond_entry;
struct cond_entry_list cond_entry_list; struct cond_entry_list cond_entry_list;
int boolean; int boolean;
owner_t owner;
struct prefixes prefix; struct prefixes prefix;
IncludeCache_t *includecache; IncludeCache_t *includecache;
audit_t audit; audit_t audit;
@ -266,7 +267,7 @@ static void abi_features(char *filename, bool search);
%type <id> opt_id_or_var %type <id> opt_id_or_var
%type <boolean> opt_subset_flag %type <boolean> opt_subset_flag
%type <audit> opt_audit_flag %type <audit> opt_audit_flag
%type <boolean> opt_owner_flag %type <owner> opt_owner_flag
%type <boolean> opt_profile_flag %type <boolean> opt_profile_flag
%type <boolean> opt_flags %type <boolean> opt_flags
%type <rule_mode> opt_rule_mode %type <rule_mode> opt_rule_mode
@ -626,9 +627,9 @@ opt_subset_flag: { /* nothing */ $$ = false; }
opt_audit_flag: { /* nothing */ $$ = AUDIT_UNSPECIFIED; } opt_audit_flag: { /* nothing */ $$ = AUDIT_UNSPECIFIED; }
| TOK_AUDIT { $$ = AUDIT_FORCE; }; | TOK_AUDIT { $$ = AUDIT_FORCE; };
opt_owner_flag: { /* nothing */ $$ = 0; } opt_owner_flag: { /* nothing */ $$ = OWNER_UNSPECIFIED; }
| TOK_OWNER { $$ = 1; }; | TOK_OWNER { $$ = OWNER_SPECIFIED; };
| TOK_OTHER { $$ = 2; }; | TOK_OTHER { $$ = OWNER_NOT; };
opt_rule_mode: { /* nothing */ $$ = RULE_UNSPECIFIED; } opt_rule_mode: { /* nothing */ $$ = RULE_UNSPECIFIED; }
| TOK_ALLOW { $$ = RULE_ALLOW; } | TOK_ALLOW { $$ = RULE_ALLOW; }
@ -680,7 +681,7 @@ rules: rules opt_prefix block
$2.audit == AUDIT_FORCE ? "audit " : "", $2.audit == AUDIT_FORCE ? "audit " : "",
$2.rule_mode == RULE_DENY ? "deny " : "", $2.rule_mode == RULE_DENY ? "deny " : "",
$2.rule_mode == RULE_PROMPT ? "prompt " : "", $2.rule_mode == RULE_PROMPT ? "prompt " : "",
$2.owner ? "owner " : ""); $2.owner == OWNER_SPECIFIED ? "owner " : "");
list_for_each_safe($3->entries, entry, tmp) { list_for_each_safe($3->entries, entry, tmp) {
const char *error; const char *error;
entry->next = NULL; entry->next = NULL;
@ -746,8 +747,8 @@ rules: rules opt_prefix change_profile
PDEBUG("rules change_profile: (%s)\n", $3->name); PDEBUG("rules change_profile: (%s)\n", $3->name);
if (!$3) if (!$3)
yyerror(_("Assert: `change_profile' returned NULL.")); yyerror(_("Assert: `change_profile' returned NULL."));
if ($2.owner) if ($2.owner != OWNER_UNSPECIFIED)
yyerror(_("owner prefix not allowed on unix rules")); yyerror(_("owner conditional not allowed on unix rules"));
if (($2.rule_mode == RULE_DENY) && $2.audit == AUDIT_FORCE) { if (($2.rule_mode == RULE_DENY) && $2.audit == AUDIT_FORCE) {
$3->rule_mode = RULE_DENY; $3->rule_mode = RULE_DENY;
} else if ($2.rule_mode == RULE_DENY) { } else if ($2.rule_mode == RULE_DENY) {
@ -762,8 +763,8 @@ rules: rules opt_prefix change_profile
rules: rules opt_prefix capability rules: rules opt_prefix capability
{ {
if ($2.owner) if ($2.owner != OWNER_UNSPECIFIED)
yyerror(_("owner prefix not allowed on capability rules")); yyerror(_("owner conditional not allowed on capability rules"));
if ($2.rule_mode == RULE_DENY && $2.audit == AUDIT_FORCE) { if ($2.rule_mode == RULE_DENY && $2.audit == AUDIT_FORCE) {
$1->caps.deny |= $3; $1->caps.deny |= $3;
@ -1809,4 +1810,3 @@ static void abi_features(char *filename, bool search)
} }
}; };

View file

@ -45,7 +45,7 @@ public:
virtual int gen_policy_re(Profile &prof); virtual int gen_policy_re(Profile &prof);
virtual bool valid_prefix(const prefixes &p, const char *&error) { virtual bool valid_prefix(const prefixes &p, const char *&error) {
if (p.owner) { if (p.owner != OWNER_UNSPECIFIED) {
error = "owner prefix not allowed on ptrace rules"; error = "owner prefix not allowed on ptrace rules";
return false; return false;
} }

View file

@ -162,6 +162,8 @@ typedef std::list<rule_t *> RuleList;
/* Not classes so they can be used in the bison front end */ /* Not classes so they can be used in the bison front end */
typedef enum { AUDIT_UNSPECIFIED, AUDIT_FORCE, AUDIT_QUIET } audit_t; typedef enum { AUDIT_UNSPECIFIED, AUDIT_FORCE, AUDIT_QUIET } audit_t;
typedef enum { RULE_UNSPECIFIED, RULE_ALLOW, RULE_DENY, RULE_PROMPT } rule_mode_t; typedef enum { RULE_UNSPECIFIED, RULE_ALLOW, RULE_DENY, RULE_PROMPT } rule_mode_t;
typedef enum { OWNER_UNSPECIFIED, OWNER_SPECIFIED, OWNER_NOT } owner_t;
/* NOTE: we can not have a constructor for class prefixes. This is /* NOTE: we can not have a constructor for class prefixes. This is
* because it will break bison, and we would need to transition to * because it will break bison, and we would need to transition to
@ -173,7 +175,7 @@ class prefixes {
public: public:
audit_t audit; audit_t audit;
rule_mode_t rule_mode; rule_mode_t rule_mode;
int owner; owner_t owner;
ostream &dump(ostream &os) ostream &dump(ostream &os)
{ {
@ -216,11 +218,21 @@ public:
break; break;
} }
if (owner) { switch (owner) {
case OWNER_SPECIFIED:
if (output) if (output)
os << " "; os << " ";
os << "owner"; os << "owner";
output = true; output = true;
break;
case OWNER_NOT:
if (output)
os << " ";
os << "!owner";
output = true;
break;
default:
break;
} }
if (output) if (output)
@ -238,9 +250,9 @@ public:
return -1; return -1;
if ((uint) rule_mode > (uint) rhs.rule_mode) if ((uint) rule_mode > (uint) rhs.rule_mode)
return 1; return 1;
if (owner < rhs.owner) if ((uint) owner < (uint) rhs.owner)
return -1; return -1;
if (owner > rhs.owner) if ((uint) owner > (uint) rhs.owner)
return 1; return 1;
return 0; return 0;
} }
@ -250,7 +262,7 @@ public:
return true; return true;
if ((uint) rule_mode < (uint) rhs.rule_mode) if ((uint) rule_mode < (uint) rhs.rule_mode)
return true; return true;
if (owner < rhs.owner) if ((uint) owner < (uint) rhs.owner)
return true; return true;
return false; return false;
} }
@ -263,7 +275,7 @@ public:
/* Must construct prefix here see note on prefixes */ /* Must construct prefix here see note on prefixes */
audit = AUDIT_UNSPECIFIED; audit = AUDIT_UNSPECIFIED;
rule_mode = RULE_UNSPECIFIED; rule_mode = RULE_UNSPECIFIED;
owner = 0; owner = OWNER_UNSPECIFIED;
}; };
virtual bool valid_prefix(const prefixes &p, const char *&error) = 0; virtual bool valid_prefix(const prefixes &p, const char *&error) = 0;
@ -293,13 +305,15 @@ public:
/* owner !owner conflicts */ /* owner !owner conflicts */
if (p.owner) { if (p.owner) {
if (owner && owner != p.owner) { if (owner != OWNER_UNSPECIFIED &&
owner != p.owner) {
error = "conflicting owner prefix"; error = "conflicting owner prefix";
return false; return false;
} }
owner = p.owner; owner = p.owner;
} }
/* TODO: MOVE this ! */
/* does the prefix imply a modifier */ /* does the prefix imply a modifier */
if (p.rule_mode == RULE_DENY && p.audit == AUDIT_FORCE) { if (p.rule_mode == RULE_DENY && p.audit == AUDIT_FORCE) {
rule_mode = RULE_DENY; rule_mode = RULE_DENY;

View file

@ -47,7 +47,7 @@ public:
free(peer_label); free(peer_label);
}; };
virtual bool valid_prefix(const prefixes &p, const char *&error) { virtual bool valid_prefix(const prefixes &p, const char *&error) {
if (p.owner) { if (p.owner != OWNER_UNSPECIFIED) {
error = "owner prefix not allowed on signal rules"; error = "owner prefix not allowed on signal rules";
return false; return false;
} }