mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-30 13:58:22 +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_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 | \
|
||||||
|
@ -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) {
|
||||||
|
@ -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}
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user