Skip to content

Commit

Permalink
netfilter: ipset: Fix sleeping memory allocation in atomic context
Browse files Browse the repository at this point in the history
Commit 00590fd introduced RCU locking in list type and in
doing so introduced a memory allocation in list_set_add, which
is done in an atomic context, due to the fact that ipset rcu
list modifications are serialised with a spin lock. The reason
why we can't use a mutex is that in addition to modifying the
list with ipset commands, it's also being modified when a
particular ipset rule timeout expires aka garbage collection.
This gc is triggered from set_cleanup_entries, which in turn
is invoked from a timer thus requiring the lock to be bh-safe.

Concretely the following call chain can lead to "sleeping function
called in atomic context" splat:
call_ad -> list_set_uadt -> list_set_uadd -> kzalloc(, GFP_KERNEL).
And since GFP_KERNEL allows initiating direct reclaim thus
potentially sleeping in the allocation path.

To fix the issue change the allocation type to GFP_ATOMIC, to
correctly reflect that it is occuring in an atomic context.

Fixes: 00590fd ("netfilter: ipset: Introduce RCU locking in list type")
Signed-off-by: Nikolay Borisov <[email protected]>
Acked-by: Jozsef Kadlecsik <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
  • Loading branch information
KernelKyupCom authored and nkskjames committed Jan 13, 2016
1 parent e92604f commit ca333f5
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion net/netfilter/ipset/ip_set_list_set.c
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ list_set_uadd(struct ip_set *set, void *value, const struct ip_set_ext *ext,
ip_set_timeout_expired(ext_timeout(n, set))))
n = NULL;

e = kzalloc(set->dsize, GFP_KERNEL);
e = kzalloc(set->dsize, GFP_ATOMIC);
if (!e)
return -ENOMEM;
e->id = d->id;
Expand Down

0 comments on commit ca333f5

Please sign in to comment.