diff options
author | Ondrej Mosnacek <omosnace@redhat.com> | 2021-11-19 14:45:20 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-11-26 10:39:21 +0100 |
commit | b17dd53cac769dd13031b0ca34f90cc65e523fab (patch) | |
tree | c1c15662cf84b3a8029e58b561d174a32798e5f4 /security | |
parent | 1ae0d59c4f5ed1555d99e139cb68b8e87a5e13eb (diff) |
selinux: fix NULL-pointer dereference when hashtab allocation fails
commit dc27f3c5d10c58069672215787a96b4fae01818b upstream.
When the hash table slot array allocation fails in hashtab_init(),
h->size is left initialized with a non-zero value, but the h->htable
pointer is NULL. This may then cause a NULL pointer dereference, since
the policydb code relies on the assumption that even after a failed
hashtab_init(), hashtab_map() and hashtab_destroy() can be safely called
on it. Yet, these detect an empty hashtab only by looking at the size.
Fix this by making sure that hashtab_init() always leaves behind a valid
empty hashtab when the allocation fails.
Cc: stable@vger.kernel.org
Fixes: 03414a49ad5f ("selinux: do not allocate hashtabs dynamically")
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/ss/hashtab.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c index dab8c25c739b..7335f67ce54e 100644 --- a/security/selinux/ss/hashtab.c +++ b/security/selinux/ss/hashtab.c @@ -30,13 +30,20 @@ static u32 hashtab_compute_size(u32 nel) int hashtab_init(struct hashtab *h, u32 nel_hint) { - h->size = hashtab_compute_size(nel_hint); + u32 size = hashtab_compute_size(nel_hint); + + /* should already be zeroed, but better be safe */ h->nel = 0; - if (!h->size) - return 0; + h->size = 0; + h->htable = NULL; - h->htable = kcalloc(h->size, sizeof(*h->htable), GFP_KERNEL); - return h->htable ? 0 : -ENOMEM; + if (size) { + h->htable = kcalloc(size, sizeof(*h->htable), GFP_KERNEL); + if (!h->htable) + return -ENOMEM; + h->size = size; + } + return 0; } int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst, |