2
0
mirror of https://gitlab.com/apparmor/apparmor synced 2025-08-22 10:07:12 +00:00

parser: allow backwards mapping of a capability

If a capability is known in policy but not by the kernel, check to see if it has
a backwards mapping to a different capability and use that instead.

Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2020-07-07 07:31:06 -07:00
parent 3880ef5b54
commit c810c755b1
3 changed files with 49 additions and 7 deletions

View File

@ -42,6 +42,7 @@ void capabilities_init(void);
void __debug_capabilities(uint64_t capset, const char *name); void __debug_capabilities(uint64_t capset, const char *name);
bool add_cap_feature_mask(struct aa_features *features, capability_flags flags); bool add_cap_feature_mask(struct aa_features *features, capability_flags flags);
void clear_cap_flag(capability_flags flags); void clear_cap_flag(capability_flags flags);
int capability_backmap(unsigned int cap);
bool capability_in_kernel(unsigned int cap);
#endif /* __AA_CAPABILITY_H */ #endif /* __AA_CAPABILITY_H */

View File

@ -220,6 +220,21 @@ struct capability_table *find_cap_entry_by_name(const char *name)
return NULL; return NULL;
} }
struct capability_table *find_cap_entry_by_num(unsigned int cap)
{
int i;
for (i = 0; cap_table[i].name; i++) {
PDEBUG("Checking %d %d\n", cap, cap_table[i].cap);
if (cap == cap_table[i].cap) {
PDEBUG("Found %d %d\n", cap, cap_table[i].cap);
return &cap_table[i];
}
}
return NULL;
}
/* don't mark up str with \0 */ /* don't mark up str with \0 */
static const char *strn_token(const char *str, size_t &len) static const char *strn_token(const char *str, size_t &len)
{ {
@ -343,16 +358,37 @@ int name_to_capability(const char *cap)
const char *capability_to_name(unsigned int cap) const char *capability_to_name(unsigned int cap)
{ {
int i; struct capability_table *ent;
for (i = 0; cap_table[i].name; i++) { ent = find_cap_entry_by_num(cap);
if (cap_table[i].cap == cap) if (ent)
return cap_table[i].name; return ent->name;
}
return "invalid-capability"; return "invalid-capability";
} }
int capability_backmap(unsigned int cap)
{
struct capability_table *ent;
ent = find_cap_entry_by_num(cap);
if (ent)
return ent->backmap;
return NO_BACKMAP_CAP;
}
bool capability_in_kernel(unsigned int cap)
{
struct capability_table *ent;
ent = find_cap_entry_by_num(cap);
if (ent)
return ent->flags & CAPFLAG_KERNEL_FEATURE;
return false;
}
void __debug_capabilities(uint64_t capset, const char *name) void __debug_capabilities(uint64_t capset, const char *name)
{ {
unsigned int i; unsigned int i;

View File

@ -1605,10 +1605,15 @@ capability: TOK_CAPABILITY caps TOK_END_OF_RULE
caps: { /* nothing */ $$ = 0; } caps: { /* nothing */ $$ = 0; }
| caps TOK_ID | caps TOK_ID
{ {
int cap = name_to_capability($2); int backmap, cap = name_to_capability($2);
if (cap == -1) if (cap == -1)
yyerror(_("Invalid capability %s."), $2); yyerror(_("Invalid capability %s."), $2);
free($2); free($2);
backmap = capability_backmap(cap);
if (backmap != NO_BACKMAP_CAP && !capability_in_kernel(cap)) {
/* TODO: special backmap warning */
cap = backmap;
}
$$ = $1 | CAP_TO_MASK(cap); $$ = $1 | CAP_TO_MASK(cap);
} }