![]() This fix adds a new reference counter (ref_netlink) for the struct ip_set. The other reference counter (ref) can be swapped out by ip_set_swap and we need a separate counter to keep track of references for netlink events like dump. Using the same ref counter for dump causes a race condition which can be demonstrated by the following script: ipset create hash_ip1 hash:ip family inet hashsize 1024 maxelem 500000 \ counters ipset create hash_ip2 hash:ip family inet hashsize 300000 maxelem 500000 \ counters ipset create hash_ip3 hash:ip family inet hashsize 1024 maxelem 500000 \ counters ipset save & ipset swap hash_ip3 hash_ip2 ipset destroy hash_ip3 /* will crash the machine */ Swap will exchange the values of ref so destroy will see ref = 0 instead of ref = 1. With this fix in place swap will not succeed because ipset save still has ref_netlink on the set (ip_set_swap doesn't swap ref_netlink). Both delete and swap will error out if ref_netlink != 0 on the set. Note: The changes to *_head functions is because previously we would increment ref whenever we called these functions, we don't do that anymore. Reviewed-by: Joshua Hunt <johunt@akamai.com> Signed-off-by: Vishwanath Pai <vpai@akamai.com> Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> |
||
---|---|---|
.. | ||
ip_set_bitmap_gen.h | ||
ip_set_bitmap_ip.c | ||
ip_set_bitmap_ipmac.c | ||
ip_set_bitmap_port.c | ||
ip_set_core.c | ||
ip_set_getport.c | ||
ip_set_hash_gen.h | ||
ip_set_hash_ip.c | ||
ip_set_hash_ipmark.c | ||
ip_set_hash_ipport.c | ||
ip_set_hash_ipportip.c | ||
ip_set_hash_ipportnet.c | ||
ip_set_hash_mac.c | ||
ip_set_hash_net.c | ||
ip_set_hash_netiface.c | ||
ip_set_hash_netnet.c | ||
ip_set_hash_netport.c | ||
ip_set_hash_netportnet.c | ||
ip_set_list_set.c | ||
Kconfig | ||
Makefile | ||
pfxlen.c |