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
@ -100,6 +100,8 @@ struct aa_dfa {
|
|||||||
struct table_header *tables[YYTD_ID_TSIZE];
|
struct table_header *tables[YYTD_ID_TSIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct aa_dfa *nulldfa;
|
||||||
|
|
||||||
#define byte_to_byte(X) (X)
|
#define byte_to_byte(X) (X)
|
||||||
|
|
||||||
#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
|
#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);
|
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);
|
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,
|
unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
|
||||||
const char *str, int len);
|
const char *str, int len);
|
||||||
|
@ -878,6 +878,12 @@ static int __init apparmor_init(void)
|
|||||||
return 0;
|
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();
|
error = aa_alloc_root_ns();
|
||||||
if (error) {
|
if (error) {
|
||||||
AA_ERROR("Unable to allocate default profile namespace\n");
|
AA_ERROR("Unable to allocate default profile namespace\n");
|
||||||
@ -905,6 +911,7 @@ static int __init apparmor_init(void)
|
|||||||
|
|
||||||
alloc_out:
|
alloc_out:
|
||||||
aa_destroy_aafs();
|
aa_destroy_aafs();
|
||||||
|
aa_teardown_dfa_engine();
|
||||||
|
|
||||||
apparmor_enabled = 0;
|
apparmor_enabled = 0;
|
||||||
return error;
|
return error;
|
||||||
|
@ -25,6 +25,33 @@
|
|||||||
|
|
||||||
#define base_idx(X) ((X) & 0xffffff)
|
#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)
|
* unpack_table - unpack a dfa table (one of accept, default, base, next check)
|
||||||
* @blob: data to unpack (NOT NULL)
|
* @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 */
|
/* released on free_profile */
|
||||||
rcu_assign_pointer(profile->parent, aa_get_profile(parent));
|
rcu_assign_pointer(profile->parent, aa_get_profile(parent));
|
||||||
profile->ns = aa_get_ns(parent->ns);
|
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);
|
mutex_lock(&profile->ns->lock);
|
||||||
__list_add_profile(&parent->base.profiles, profile);
|
__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))
|
if (!unpack_nameX(e, AA_STRUCTEND, NULL))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
} else
|
||||||
|
profile->policy.dfa = aa_get_dfa(nulldfa);
|
||||||
|
|
||||||
/* get file rules */
|
/* get file rules */
|
||||||
profile->file.dfa = unpack_dfa(e);
|
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->policy.start[AA_CLASS_FILE]) {
|
||||||
profile->file.dfa = aa_get_dfa(profile->policy.dfa);
|
profile->file.dfa = aa_get_dfa(profile->policy.dfa);
|
||||||
profile->file.start = profile->policy.start[AA_CLASS_FILE];
|
profile->file.start = profile->policy.start[AA_CLASS_FILE];
|
||||||
}
|
} else
|
||||||
|
profile->file.dfa = aa_get_dfa(nulldfa);
|
||||||
|
|
||||||
if (!unpack_trans_table(e, profile))
|
if (!unpack_trans_table(e, profile))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
Loading…
Reference in New Issue
Block a user