2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-30 05:47:59 +00:00

allow for ptrace rules

This commit is contained in:
John Johansen 2008-04-09 09:04:08 +00:00
parent 78590d1823
commit 4dd0e8ead8
5 changed files with 58 additions and 22 deletions

View File

@ -57,13 +57,11 @@
#define AA_FILE_PERMS (AA_USER_PERMS | AA_OTHER_PERMS ) #define AA_FILE_PERMS (AA_USER_PERMS | AA_OTHER_PERMS )
#define AA_AUDIT_FIELD (1 << 28) #define AA_USER_PTRACE (1 << 28)
#define AA_CHANGE_HAT (1 << 29) #define AA_OTHER_PTRACE (1 << 29)
#define AA_CHANGE_PROFILE (1 << 30) #define AA_CHANGE_HAT (1 << 30)
#define AA_ERROR_BIT (1 << 31) #define AA_CHANGE_PROFILE (1 << 31)
#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE | \ #define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE)
AA_AUDIT_FIELD | AA_ERROR_BIT)
#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \ #define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \
AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \ AA_EXEC_MOD_2 | AA_EXEC_MOD_3 | \

View File

@ -865,7 +865,7 @@ public:
DenyMatchFlag(uint32_t flag, uint32_t quiet) : MatchFlag(flag, quiet) {} DenyMatchFlag(uint32_t flag, uint32_t quiet) : MatchFlag(flag, quiet) {}
}; };
uint32_t accept_perms(State *state, uint32_t *audit_ctl); uint32_t accept_perms(State *state, uint32_t *audit_ctl, int *error);
/** /**
* verify that there are no conflicting X permissions on the dfa * verify that there are no conflicting X permissions on the dfa
@ -874,10 +874,11 @@ uint32_t accept_perms(State *state, uint32_t *audit_ctl);
*/ */
State *DFA::verify_perms(void) State *DFA::verify_perms(void)
{ {
int error = 0;
for (States::iterator i = states.begin(); i != states.end(); i++) { for (States::iterator i = states.begin(); i != states.end(); i++) {
uint32_t accept = accept_perms(*i, NULL); uint32_t accept = accept_perms(*i, NULL, &error);
if (*i == start || accept) { if (*i == start || accept) {
if (accept & AA_ERROR_BIT) if (error)
return *i; return *i;
} }
} }
@ -889,9 +890,10 @@ State *DFA::verify_perms(void)
*/ */
void DFA::dump(ostream& os) void DFA::dump(ostream& os)
{ {
int error = 0;
for (States::iterator i = states.begin(); i != states.end(); i++) { for (States::iterator i = states.begin(); i != states.end(); i++) {
uint32_t accept, audit; uint32_t accept, audit;
accept = accept_perms(*i, &audit); accept = accept_perms(*i, &audit, &error);
if (*i == start || accept) { if (*i == start || accept) {
os << **i; os << **i;
if (*i == start) if (*i == start)
@ -930,7 +932,8 @@ void DFA::dump_dot_graph(ostream& os)
if (*i == start) { if (*i == start) {
os << "\t\tstyle=bold" << endl; os << "\t\tstyle=bold" << endl;
} }
uint32_t perms = accept_perms(*i, NULL); int error = 0;
uint32_t perms = accept_perms(*i, NULL, &error);
if (perms) { if (perms) {
os << "\t\tlabel=\"" << **i << "\\n(" os << "\t\tlabel=\"" << **i << "\\n("
<< perms << ")\"" << endl; << perms << ")\"" << endl;
@ -1152,11 +1155,12 @@ TransitionTable::TransitionTable(DFA& dfa, map<uchar, uchar>& eq)
accept.resize(dfa.states.size()); accept.resize(dfa.states.size());
accept2.resize(dfa.states.size()); accept2.resize(dfa.states.size());
for (States::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) { for (States::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) {
int error = 0;
uint32_t audit_ctl; uint32_t audit_ctl;
accept[num[*i]] = accept_perms(*i, &audit_ctl); accept[num[*i]] = accept_perms(*i, &audit_ctl, &error);
accept2[num[*i]] = audit_ctl;
//if (accept[num[*i]] & AA_CHANGE_HAT) //if (accept[num[*i]] & AA_CHANGE_HAT)
// fprintf(stderr, "change_hat state %d - 0x%x\n", num[*i], accept[num[*i]]); // fprintf(stderr, "change_hat state %d - 0x%x\n", num[*i], accept[num[*i]]);
// accept2[num[*i]] = audit_ctl;
} }
} }
@ -1519,11 +1523,12 @@ static inline int diff_qualifiers(uint32_t perm1, uint32_t perm2)
* have any exact matches, then they override the execute and safe * have any exact matches, then they override the execute and safe
* execute flags. * execute flags.
*/ */
uint32_t accept_perms(State *state, uint32_t *audit_ctl) uint32_t accept_perms(State *state, uint32_t *audit_ctl, int *error)
{ {
uint32_t perms = 0, exact_match_perms = 0, audit = 0, exact_audit = 0, uint32_t perms = 0, exact_match_perms = 0, audit = 0, exact_audit = 0,
quiet = 0, deny = 0; quiet = 0, deny = 0;
*error = 0;
for (State::iterator i = state->begin(); i != state->end(); i++) { for (State::iterator i = state->begin(); i != state->end(); i++) {
MatchFlag *match; MatchFlag *match;
if (!(match= dynamic_cast<MatchFlag *>(*i))) if (!(match= dynamic_cast<MatchFlag *>(*i)))
@ -1532,7 +1537,7 @@ uint32_t accept_perms(State *state, uint32_t *audit_ctl)
/* exact match only ever happens with x */ /* exact match only ever happens with x */
if (!is_merged_x_consistent(exact_match_perms, if (!is_merged_x_consistent(exact_match_perms,
match->flag)) match->flag))
exact_match_perms |= AA_ERROR_BIT; *error = 1;;
exact_match_perms |= match->flag; exact_match_perms |= match->flag;
exact_audit |= match->audit; exact_audit |= match->audit;
} else if (dynamic_cast<DenyMatchFlag *>(match)) { } else if (dynamic_cast<DenyMatchFlag *>(match)) {
@ -1540,7 +1545,7 @@ uint32_t accept_perms(State *state, uint32_t *audit_ctl)
quiet |= match->audit; quiet |= match->audit;
} else { } else {
if (!is_merged_x_consistent(perms, match->flag)) if (!is_merged_x_consistent(perms, match->flag))
perms |= AA_ERROR_BIT; *error = 1;
perms |= match->flag; perms |= match->flag;
audit |= match->audit; audit |= match->audit;
} }
@ -1662,7 +1667,7 @@ extern "C" int aare_add_rule_vec(aare_ruleset_t *rules, int deny,
/* the permissions set is assumed to be non-empty if any audit /* the permissions set is assumed to be non-empty if any audit
* bits are specified */ * bits are specified */
accept = NULL; accept = NULL;
for (unsigned int n = 0; perms && n < (sizeof(perms) * 8) - 1; n++) { for (unsigned int n = 0; perms && n < (sizeof(perms) * 8) ; n++) {
uint32_t mask = 1 << n; uint32_t mask = 1 << n;
if (perms & mask) { if (perms & mask) {

View File

@ -71,6 +71,7 @@ static struct keyword_table keyword_table[] = {
{"set", TOK_SET}, {"set", TOK_SET},
{"rlimit", TOK_RLIMIT}, {"rlimit", TOK_RLIMIT},
{"alias", TOK_ALIAS}, {"alias", TOK_ALIAS},
{"ptrace", TOK_PTRACE},
/* terminate */ /* terminate */
{NULL, 0} {NULL, 0}
}; };

View File

@ -550,6 +550,19 @@ static int process_dfa_entry(aare_ruleset_t *dfarules, struct cod_entry *entry)
return FALSE; return FALSE;
} }
} }
if (entry->mode & (AA_USER_PTRACE | AA_OTHER_PTRACE)) {
int mode = entry->mode & (AA_USER_PTRACE | AA_OTHER_PTRACE);
if (entry->namespace) {
char *vec[2];
vec[0] = entry->namespace;
vec[1] = entry->name;
if (!aare_add_rule_vec(dfarules, 0, mode, 0, 2, vec))
return FALSE;
} else {
if (!aare_add_rule(dfarules, entry->name, 0, mode, 0))
return FALSE;
}
}
return TRUE; return TRUE;
} }

View File

@ -103,6 +103,7 @@ struct cod_entry *do_file_rule(char *namespace, char *id, int mode,
%token TOK_PROFILE %token TOK_PROFILE
%token TOK_SET %token TOK_SET
%token TOK_ALIAS %token TOK_ALIAS
%token TOK_PTRACE
/* rlimits */ /* rlimits */
%token TOK_RLIMIT %token TOK_RLIMIT
@ -434,9 +435,9 @@ rules: rules opt_audit_flag TOK_DENY opt_owner_flag rule
yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'")); yyerror(_("Invalid mode, in deny rules 'x' must not be preceded by exec qualifier 'i', 'p', or 'u'"));
if ($4 == 1) if ($4 == 1)
$5->mode &= (AA_USER_PERMS | AA_SHARED_PERMS); $5->mode &= (AA_USER_PERMS | AA_SHARED_PERMS | AA_USER_PTRACE);
else if ($4 == 2) else if ($4 == 2)
$5->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS); $5->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS | AA_OTHER_PTRACE);
/* only set audit ctl quieting if the rule is not audited */ /* only set audit ctl quieting if the rule is not audited */
if (!$2) if (!$2)
$5->audit = $5->mode & ~ALL_AA_EXEC_TYPE; $5->audit = $5->mode & ~ALL_AA_EXEC_TYPE;
@ -455,9 +456,9 @@ rules: rules opt_audit_flag opt_owner_flag rule
yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'")); yyerror(_("Invalid mode, 'x' must be preceded by exec qualifier 'i', 'p', or 'u'"));
if ($3 == 1) if ($3 == 1)
$4->mode &= (AA_USER_PERMS | AA_SHARED_PERMS); $4->mode &= (AA_USER_PERMS | AA_SHARED_PERMS | AA_USER_PTRACE);
else if ($3 == 2) else if ($3 == 2)
$4->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS); $4->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS | AA_OTHER_PTRACE);
if ($2) if ($2)
$4->audit = $4->mode & ~ALL_AA_EXEC_TYPE; $4->audit = $4->mode & ~ALL_AA_EXEC_TYPE;
@ -834,6 +835,24 @@ rule: file_mode opt_subset_flag TOK_ID TOK_ARROW TOK_ID TOK_END_OF_RULE
$$ = entry; $$ = entry;
}; };
rule: TOK_PTRACE TOK_ID TOK_END_OF_RULE
{
struct cod_entry *entry;
entry = new_entry(NULL, $2, AA_USER_PTRACE | AA_OTHER_PTRACE, NULL);
if (!entry)
yyerror(_("Memory allocation error."));
$$ = entry;
};
rule: TOK_PTRACE TOK_COLON TOK_ID TOK_COLON TOK_ID TOK_END_OF_RULE
{
struct cod_entry *entry;
entry = new_entry($3, $5, AA_USER_PTRACE | AA_OTHER_PTRACE, NULL);
if (!entry)
yyerror(_("Memory allocation error."));
$$ = entry;
};
change_hat: hat_start TOK_ID TOK_END_OF_RULE change_hat: hat_start TOK_ID TOK_END_OF_RULE
{ {
/* allow change_hat to external hats */ /* allow change_hat to external hats */