apparmor: add a default null dfa
Instead of testing whether a given dfa exists in every code path, have a default null dfa that is used when loaded policy doesn't provide a dfa. This will let us get rid of special casing and avoid dereference bugs when special casing is missed. Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
parent
6604d4c1c1
commit
11c236b89d
6 changed files with 46 additions and 2 deletions
|
@ -100,6 +100,8 @@ struct aa_dfa {
|
|||
struct table_header *tables[YYTD_ID_TSIZE];
|
||||
};
|
||||
|
||||
extern struct aa_dfa *nulldfa;
|
||||
|
||||
#define byte_to_byte(X) (X)
|
||||
|
||||
#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
|
||||
|
@ -117,6 +119,9 @@ static inline size_t table_size(size_t len, size_t el_size)
|
|||
return ALIGN(sizeof(struct table_header) + len * el_size, 8);
|
||||
}
|
||||
|
||||
int aa_setup_dfa_engine(void);
|
||||
void aa_teardown_dfa_engine(void);
|
||||
|
||||
struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags);
|
||||
unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
|
||||
const char *str, int len);
|
||||
|
|
|
@ -878,6 +878,12 @@ static int __init apparmor_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
error = aa_setup_dfa_engine();
|
||||
if (error) {
|
||||
AA_ERROR("Unable to setup dfa engine\n");
|
||||
goto alloc_out;
|
||||
}
|
||||
|
||||
error = aa_alloc_root_ns();
|
||||
if (error) {
|
||||
AA_ERROR("Unable to allocate default profile namespace\n");
|
||||
|
@ -905,6 +911,7 @@ static int __init apparmor_init(void)
|
|||
|
||||
alloc_out:
|
||||
aa_destroy_aafs();
|
||||
aa_teardown_dfa_engine();
|
||||
|
||||
apparmor_enabled = 0;
|
||||
return error;
|
||||
|
|
|
@ -25,6 +25,33 @@
|
|||
|
||||
#define base_idx(X) ((X) & 0xffffff)
|
||||
|
||||
static char nulldfa_src[] = {
|
||||
#include "nulldfa.in"
|
||||
};
|
||||
struct aa_dfa *nulldfa;
|
||||
|
||||
int aa_setup_dfa_engine(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
nulldfa = aa_dfa_unpack(nulldfa_src, sizeof(nulldfa_src),
|
||||
TO_ACCEPT1_FLAG(YYTD_DATA32) |
|
||||
TO_ACCEPT2_FLAG(YYTD_DATA32));
|
||||
if (!IS_ERR(nulldfa))
|
||||
return 0;
|
||||
|
||||
error = PTR_ERR(nulldfa);
|
||||
nulldfa = NULL;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void aa_teardown_dfa_engine(void)
|
||||
{
|
||||
aa_put_dfa(nulldfa);
|
||||
nulldfa = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* unpack_table - unpack a dfa table (one of accept, default, base, next check)
|
||||
* @blob: data to unpack (NOT NULL)
|
||||
|
|
1
security/apparmor/nulldfa.in
Normal file
1
security/apparmor/nulldfa.in
Normal file
File diff suppressed because one or more lines are too long
|
@ -348,6 +348,8 @@ name:
|
|||
/* released on free_profile */
|
||||
rcu_assign_pointer(profile->parent, aa_get_profile(parent));
|
||||
profile->ns = aa_get_ns(parent->ns);
|
||||
profile->file.dfa = aa_get_dfa(nulldfa);
|
||||
profile->policy.dfa = aa_get_dfa(nulldfa);
|
||||
|
||||
mutex_lock(&profile->ns->lock);
|
||||
__list_add_profile(&parent->base.profiles, profile);
|
||||
|
|
|
@ -603,7 +603,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
|||
}
|
||||
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
||||
goto fail;
|
||||
}
|
||||
} else
|
||||
profile->policy.dfa = aa_get_dfa(nulldfa);
|
||||
|
||||
/* get file rules */
|
||||
profile->file.dfa = unpack_dfa(e);
|
||||
|
@ -619,7 +620,8 @@ static struct aa_profile *unpack_profile(struct aa_ext *e)
|
|||
profile->policy.start[AA_CLASS_FILE]) {
|
||||
profile->file.dfa = aa_get_dfa(profile->policy.dfa);
|
||||
profile->file.start = profile->policy.start[AA_CLASS_FILE];
|
||||
}
|
||||
} else
|
||||
profile->file.dfa = aa_get_dfa(nulldfa);
|
||||
|
||||
if (!unpack_trans_table(e, profile))
|
||||
goto fail;
|
||||
|
|
Loading…
Reference in a new issue