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:
parent
78590d1823
commit
4dd0e8ead8
@ -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 | \
|
||||
|
@ -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) {
|
||||
|
@ -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}
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user