summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authorOndrej Mosnacek <omosnace@redhat.com>2021-11-19 16:45:20 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-11-25 11:49:07 +0300
commit83c8ab8503adf56bf68dafc7a382f4946c87da79 (patch)
tree60e7f4edcdcacf756393fbc96ea288d6b709cd47 /security
parent439b99314b635b40f2e0622eabe62d7055bb409b (diff)
downloadlinux-83c8ab8503adf56bf68dafc7a382f4946c87da79.tar.xz
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.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/security/selinux/ss/hashtab.c b/security/selinux/ss/hashtab.c
index b8f6b3e0a921..a91fb0ed00de 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,