mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 10:44:14 +08:00
netfilter: ipset: use bitmap infrastructure completely
The bitmap allocation did not use full unsigned long sizes when calculating the required size and that was triggered by KASAN as slab-out-of-bounds read in several places. The patch fixes all of them. Reported-by: syzbot+fabca5cbf5e54f3fe2de@syzkaller.appspotmail.com Reported-by: syzbot+827ced406c9a1d9570ed@syzkaller.appspotmail.com Reported-by: syzbot+190d63957b22ef673ea5@syzkaller.appspotmail.com Reported-by: syzbot+dfccdb2bdb4a12ad425e@syzkaller.appspotmail.com Reported-by: syzbot+df0d0f5895ef1f41a65b@syzkaller.appspotmail.com Reported-by: syzbot+b08bd19bb37513357fd4@syzkaller.appspotmail.com Reported-by: syzbot+53cdd0ec0bbabd53370a@syzkaller.appspotmail.com Signed-off-by: Jozsef Kadlecsik <kadlec@netfilter.org> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
7eaecf7963
commit
32c72165db
@ -426,13 +426,6 @@ ip6addrptr(const struct sk_buff *skb, bool src, struct in6_addr *addr)
|
|||||||
sizeof(*addr));
|
sizeof(*addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calculate the bytes required to store the inclusive range of a-b */
|
|
||||||
static inline int
|
|
||||||
bitmap_bytes(u32 a, u32 b)
|
|
||||||
{
|
|
||||||
return 4 * ((((b - a + 8) / 8) + 3) / 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* How often should the gc be run by default */
|
/* How often should the gc be run by default */
|
||||||
#define IPSET_GC_TIME (3 * 60)
|
#define IPSET_GC_TIME (3 * 60)
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ mtype_flush(struct ip_set *set)
|
|||||||
|
|
||||||
if (set->extensions & IPSET_EXT_DESTROY)
|
if (set->extensions & IPSET_EXT_DESTROY)
|
||||||
mtype_ext_cleanup(set);
|
mtype_ext_cleanup(set);
|
||||||
memset(map->members, 0, map->memsize);
|
bitmap_zero(map->members, map->elements);
|
||||||
set->elements = 0;
|
set->elements = 0;
|
||||||
set->ext_size = 0;
|
set->ext_size = 0;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ MODULE_ALIAS("ip_set_bitmap:ip");
|
|||||||
|
|
||||||
/* Type structure */
|
/* Type structure */
|
||||||
struct bitmap_ip {
|
struct bitmap_ip {
|
||||||
void *members; /* the set members */
|
unsigned long *members; /* the set members */
|
||||||
u32 first_ip; /* host byte order, included in range */
|
u32 first_ip; /* host byte order, included in range */
|
||||||
u32 last_ip; /* host byte order, included in range */
|
u32 last_ip; /* host byte order, included in range */
|
||||||
u32 elements; /* number of max elements in the set */
|
u32 elements; /* number of max elements in the set */
|
||||||
@ -220,7 +220,7 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
|
|||||||
u32 first_ip, u32 last_ip,
|
u32 first_ip, u32 last_ip,
|
||||||
u32 elements, u32 hosts, u8 netmask)
|
u32 elements, u32 hosts, u8 netmask)
|
||||||
{
|
{
|
||||||
map->members = ip_set_alloc(map->memsize);
|
map->members = bitmap_zalloc(elements, GFP_KERNEL | __GFP_NOWARN);
|
||||||
if (!map->members)
|
if (!map->members)
|
||||||
return false;
|
return false;
|
||||||
map->first_ip = first_ip;
|
map->first_ip = first_ip;
|
||||||
@ -322,7 +322,7 @@ bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
|
|||||||
if (!map)
|
if (!map)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
map->memsize = bitmap_bytes(0, elements - 1);
|
map->memsize = BITS_TO_LONGS(elements) * sizeof(unsigned long);
|
||||||
set->variant = &bitmap_ip;
|
set->variant = &bitmap_ip;
|
||||||
if (!init_map_ip(set, map, first_ip, last_ip,
|
if (!init_map_ip(set, map, first_ip, last_ip,
|
||||||
elements, hosts, netmask)) {
|
elements, hosts, netmask)) {
|
||||||
|
@ -42,7 +42,7 @@ enum {
|
|||||||
|
|
||||||
/* Type structure */
|
/* Type structure */
|
||||||
struct bitmap_ipmac {
|
struct bitmap_ipmac {
|
||||||
void *members; /* the set members */
|
unsigned long *members; /* the set members */
|
||||||
u32 first_ip; /* host byte order, included in range */
|
u32 first_ip; /* host byte order, included in range */
|
||||||
u32 last_ip; /* host byte order, included in range */
|
u32 last_ip; /* host byte order, included in range */
|
||||||
u32 elements; /* number of max elements in the set */
|
u32 elements; /* number of max elements in the set */
|
||||||
@ -299,7 +299,7 @@ static bool
|
|||||||
init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
|
init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
|
||||||
u32 first_ip, u32 last_ip, u32 elements)
|
u32 first_ip, u32 last_ip, u32 elements)
|
||||||
{
|
{
|
||||||
map->members = ip_set_alloc(map->memsize);
|
map->members = bitmap_zalloc(elements, GFP_KERNEL | __GFP_NOWARN);
|
||||||
if (!map->members)
|
if (!map->members)
|
||||||
return false;
|
return false;
|
||||||
map->first_ip = first_ip;
|
map->first_ip = first_ip;
|
||||||
@ -360,7 +360,7 @@ bitmap_ipmac_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
|
|||||||
if (!map)
|
if (!map)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
map->memsize = bitmap_bytes(0, elements - 1);
|
map->memsize = BITS_TO_LONGS(elements) * sizeof(unsigned long);
|
||||||
set->variant = &bitmap_ipmac;
|
set->variant = &bitmap_ipmac;
|
||||||
if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
|
if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
|
||||||
kfree(map);
|
kfree(map);
|
||||||
|
@ -30,7 +30,7 @@ MODULE_ALIAS("ip_set_bitmap:port");
|
|||||||
|
|
||||||
/* Type structure */
|
/* Type structure */
|
||||||
struct bitmap_port {
|
struct bitmap_port {
|
||||||
void *members; /* the set members */
|
unsigned long *members; /* the set members */
|
||||||
u16 first_port; /* host byte order, included in range */
|
u16 first_port; /* host byte order, included in range */
|
||||||
u16 last_port; /* host byte order, included in range */
|
u16 last_port; /* host byte order, included in range */
|
||||||
u32 elements; /* number of max elements in the set */
|
u32 elements; /* number of max elements in the set */
|
||||||
@ -231,7 +231,7 @@ static bool
|
|||||||
init_map_port(struct ip_set *set, struct bitmap_port *map,
|
init_map_port(struct ip_set *set, struct bitmap_port *map,
|
||||||
u16 first_port, u16 last_port)
|
u16 first_port, u16 last_port)
|
||||||
{
|
{
|
||||||
map->members = ip_set_alloc(map->memsize);
|
map->members = bitmap_zalloc(map->elements, GFP_KERNEL | __GFP_NOWARN);
|
||||||
if (!map->members)
|
if (!map->members)
|
||||||
return false;
|
return false;
|
||||||
map->first_port = first_port;
|
map->first_port = first_port;
|
||||||
@ -271,7 +271,7 @@ bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
map->elements = elements;
|
map->elements = elements;
|
||||||
map->memsize = bitmap_bytes(0, map->elements);
|
map->memsize = BITS_TO_LONGS(elements) * sizeof(unsigned long);
|
||||||
set->variant = &bitmap_port;
|
set->variant = &bitmap_port;
|
||||||
if (!init_map_port(set, map, first_port, last_port)) {
|
if (!init_map_port(set, map, first_port, last_port)) {
|
||||||
kfree(map);
|
kfree(map);
|
||||||
|
Loading…
Reference in New Issue
Block a user