2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 01:57:43 +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_AUDIT_FIELD (1 << 28)
#define AA_CHANGE_HAT (1 << 29)
#define AA_CHANGE_PROFILE (1 << 30)
#define AA_ERROR_BIT (1 << 31)
#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE | \
AA_AUDIT_FIELD | AA_ERROR_BIT)
#define AA_USER_PTRACE (1 << 28)
#define AA_OTHER_PTRACE (1 << 29)
#define AA_CHANGE_HAT (1 << 30)
#define AA_CHANGE_PROFILE (1 << 31)
#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE)
#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \
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) {}
};
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
@ -874,10 +874,11 @@ uint32_t accept_perms(State *state, uint32_t *audit_ctl);
*/
State *DFA::verify_perms(void)
{
int error = 0;
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 (accept & AA_ERROR_BIT)
if (error)
return *i;
}
}
@ -889,9 +890,10 @@ State *DFA::verify_perms(void)
*/
void DFA::dump(ostream& os)
{
int error = 0;
for (States::iterator i = states.begin(); i != states.end(); i++) {
uint32_t accept, audit;
accept = accept_perms(*i, &audit);
accept = accept_perms(*i, &audit, &error);
if (*i == start || accept) {
os << **i;
if (*i == start)
@ -930,7 +932,8 @@ void DFA::dump_dot_graph(ostream& os)
if (*i == start) {
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) {
os << "\t\tlabel=\"" << **i << "\\n("
<< perms << ")\"" << endl;
@ -1152,11 +1155,12 @@ TransitionTable::TransitionTable(DFA& dfa, map<uchar, uchar>& eq)
accept.resize(dfa.states.size());
accept2.resize(dfa.states.size());
for (States::iterator i = dfa.states.begin(); i != dfa.states.end(); i++) {
int error = 0;
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)
// 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
* 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,
quiet = 0, deny = 0;
*error = 0;
for (State::iterator i = state->begin(); i != state->end(); i++) {
MatchFlag *match;
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 */
if (!is_merged_x_consistent(exact_match_perms,
match->flag))
exact_match_perms |= AA_ERROR_BIT;
*error = 1;;
exact_match_perms |= match->flag;
exact_audit |= match->audit;
} else if (dynamic_cast<DenyMatchFlag *>(match)) {
@ -1540,7 +1545,7 @@ uint32_t accept_perms(State *state, uint32_t *audit_ctl)
quiet |= match->audit;
} else {
if (!is_merged_x_consistent(perms, match->flag))
perms |= AA_ERROR_BIT;
*error = 1;
perms |= match->flag;
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
* bits are specified */
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;
if (perms & mask) {

View File

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

View File

@ -550,6 +550,19 @@ static int process_dfa_entry(aare_ruleset_t *dfarules, struct cod_entry *entry)
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;
}

View File

@ -103,6 +103,7 @@ struct cod_entry *do_file_rule(char *namespace, char *id, int mode,
%token TOK_PROFILE
%token TOK_SET
%token TOK_ALIAS
%token TOK_PTRACE
/* rlimits */
%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'"));
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)
$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 */
if (!$2)
$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'"));
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)
$4->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS);
$4->mode &= (AA_OTHER_PERMS | AA_SHARED_PERMS | AA_OTHER_PTRACE);
if ($2)
$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;
};
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
{
/* allow change_hat to external hats */