diff mbox

[net-next] rhashtable: Make sure max_size is non zero

Message ID 20170427222824.31936-1-florian.fainelli@broadcom.com
State Superseded, archived
Headers show

Commit Message

Florian Fainelli April 27, 2017, 10:28 p.m. UTC
After commit 6d684e54690c ("rhashtable: Cap total number of
entries to 2^31"), we would be hitting a panic() in net/core/rtnetlink.c
during initialization. The call stack would look like this:

register_pernet_subsys()
    ...
    ops->init()
	rtnetlink_net_init()
	  netlink_kernel_create()
	     netlink_insert()
		__netlink_insert()
		   rhashtable_lookup_insert_key()
		      __rhashtable_insert_fast()
			rht_grow_above_max()

And here, we have rht_grow_above_max() return true, because ht->nelemts = 0 (legit)
&& ht->max_elems = 0 (looks bogus).

Eventually, we would be return -E2BIG from __rhashtable_insert_fast()
and propagate this all the way back to the caller.

After commit 6d684e54690c what changed is that we would take the
following condition:

if (ht->p.max_size < ht->max_elems / 2)
	ht->max_elems = ht->p.max_size * 2;

and since ht->p.max_size = 0, we would set ht->max_elems to 0 as well.

Fix this by taking this branch only when ht->p.max_size is non-zero

Fixes: Fixes: 6d684e54690c ("rhashtable: Cap total number of entries to 2^31")
Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>
---
 lib/rhashtable.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Florian Fainelli April 27, 2017, 10:32 p.m. UTC | #1
On 04/27/2017 03:28 PM, Florian Fainelli wrote:
> After commit 6d684e54690c ("rhashtable: Cap total number of
> entries to 2^31"), we would be hitting a panic() in net/core/rtnetlink.c
> during initialization. The call stack would look like this:
> 
> register_pernet_subsys()
>     ...
>     ops->init()
> 	rtnetlink_net_init()
> 	  netlink_kernel_create()
> 	     netlink_insert()
> 		__netlink_insert()
> 		   rhashtable_lookup_insert_key()
> 		      __rhashtable_insert_fast()
> 			rht_grow_above_max()
> 
> And here, we have rht_grow_above_max() return true, because ht->nelemts = 0 (legit)
> && ht->max_elems = 0 (looks bogus).
> 
> Eventually, we would be return -E2BIG from __rhashtable_insert_fast()
> and propagate this all the way back to the caller.
> 
> After commit 6d684e54690c what changed is that we would take the
> following condition:
> 
> if (ht->p.max_size < ht->max_elems / 2)
> 	ht->max_elems = ht->p.max_size * 2;
> 
> and since ht->p.max_size = 0, we would set ht->max_elems to 0 as well.
> 
> Fix this by taking this branch only when ht->p.max_size is non-zero
> 
> Fixes: Fixes: 6d684e54690c ("rhashtable: Cap total number of entries to 2^31")
> Signed-off-by: Florian Fainelli <florian.fainelli@broadcom.com>

Sent another version with the correct email address and marked this one
as superseded in patchwork, not that this email is not valid, but it's
all about consistency.

David pleas apply this one instead:
http://patchwork.ozlabs.org/patch/756172/

/me remembers to stop switching between machines.
diff mbox

Patch

diff --git a/lib/rhashtable.c b/lib/rhashtable.c
index 751630bbe409..6b4f07760fec 100644
--- a/lib/rhashtable.c
+++ b/lib/rhashtable.c
@@ -963,7 +963,7 @@  int rhashtable_init(struct rhashtable *ht,
 
 	/* Cap total entries at 2^31 to avoid nelems overflow. */
 	ht->max_elems = 1u << 31;
-	if (ht->p.max_size < ht->max_elems / 2)
+	if (ht->p.max_size && (ht->p.max_size < ht->max_elems / 2))
 		ht->max_elems = ht->p.max_size * 2;
 
 	ht->p.min_size = max(ht->p.min_size, HASH_MIN_SIZE);