diff options
author | Ondrej Mosnacek <omosnace@redhat.com> | 2019-03-17 09:46:53 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2019-03-18 12:19:48 -0400 |
commit | 6a1afffb08ce5f9fb9ccc20f7ab24846c0142984 (patch) | |
tree | 960c8d62d8a57248005a8f626b79b4eb37d53dea | |
parent | 9e98c678c2d6ae3a17cb2de55d17f69dddaa231b (diff) |
selinux: fix NULL dereference in policydb_destroy()
The conversion to kvmalloc() forgot to account for the possibility that
p->type_attr_map_array might be null in policydb_destroy().
Fix this by destroying its contents only if it is not NULL.
Also make sure ebitmap_init() is called on all entries before
policydb_destroy() can be called. Right now this is a no-op, because
both kvcalloc() and ebitmap_init() just zero out the whole struct, but
let's rather not rely on a specific implementation.
Reported-by: syzbot+a57b2aff60832666fc28@syzkaller.appspotmail.com
Fixes: acdf52d97f82 ("selinux: convert to kvmalloc")
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r-- | security/selinux/ss/policydb.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 6b576e588725..daecdfb15a9c 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -828,9 +828,11 @@ void policydb_destroy(struct policydb *p) | |||
828 | hashtab_map(p->range_tr, range_tr_destroy, NULL); | 828 | hashtab_map(p->range_tr, range_tr_destroy, NULL); |
829 | hashtab_destroy(p->range_tr); | 829 | hashtab_destroy(p->range_tr); |
830 | 830 | ||
831 | for (i = 0; i < p->p_types.nprim; i++) | 831 | if (p->type_attr_map_array) { |
832 | ebitmap_destroy(&p->type_attr_map_array[i]); | 832 | for (i = 0; i < p->p_types.nprim; i++) |
833 | kvfree(p->type_attr_map_array); | 833 | ebitmap_destroy(&p->type_attr_map_array[i]); |
834 | kvfree(p->type_attr_map_array); | ||
835 | } | ||
834 | 836 | ||
835 | ebitmap_destroy(&p->filename_trans_ttypes); | 837 | ebitmap_destroy(&p->filename_trans_ttypes); |
836 | ebitmap_destroy(&p->policycaps); | 838 | ebitmap_destroy(&p->policycaps); |
@@ -2496,10 +2498,13 @@ int policydb_read(struct policydb *p, void *fp) | |||
2496 | if (!p->type_attr_map_array) | 2498 | if (!p->type_attr_map_array) |
2497 | goto bad; | 2499 | goto bad; |
2498 | 2500 | ||
2501 | /* just in case ebitmap_init() becomes more than just a memset(0): */ | ||
2502 | for (i = 0; i < p->p_types.nprim; i++) | ||
2503 | ebitmap_init(&p->type_attr_map_array[i]); | ||
2504 | |||
2499 | for (i = 0; i < p->p_types.nprim; i++) { | 2505 | for (i = 0; i < p->p_types.nprim; i++) { |
2500 | struct ebitmap *e = &p->type_attr_map_array[i]; | 2506 | struct ebitmap *e = &p->type_attr_map_array[i]; |
2501 | 2507 | ||
2502 | ebitmap_init(e); | ||
2503 | if (p->policyvers >= POLICYDB_VERSION_AVTAB) { | 2508 | if (p->policyvers >= POLICYDB_VERSION_AVTAB) { |
2504 | rc = ebitmap_read(e, fp); | 2509 | rc = ebitmap_read(e, fp); |
2505 | if (rc) | 2510 | if (rc) |