Skip to content

Commit 6badad1

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Missing netlink attribute sanity check for NFTA_OSF_DREG, from Florian Westphal. 2) Use bitmap infrastructure in ipset to fix KASAN slab-out-of-bounds reads, from Jozsef Kadlecsik. 3) Missing initial CLOSED state in new sctp connection through ctnetlink events, from Jiri Wiesner. 4) Missing check for NFT_CHAIN_HW_OFFLOAD in nf_tables offload indirect block infrastructure, from wenxu. 5) Add __nft_chain_type_get() to sanity check family and chain type. 6) Autoload modules from the nf_tables abort path to fix races reported by syzbot. 7) Remove unnecessary skb->csum update on inet_proto_csum_replace16(), from Praveen Chaudhary. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 722943a + 189c9b1 commit 6badad1

File tree

13 files changed

+146
-76
lines changed

13 files changed

+146
-76
lines changed

include/linux/netfilter/ipset/ip_set.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -426,13 +426,6 @@ ip6addrptr(const struct sk_buff *skb, bool src, struct in6_addr *addr)
426426
sizeof(*addr));
427427
}
428428

429-
/* Calculate the bytes required to store the inclusive range of a-b */
430-
static inline int
431-
bitmap_bytes(u32 a, u32 b)
432-
{
433-
return 4 * ((((b - a + 8) / 8) + 3) / 4);
434-
}
435-
436429
/* How often should the gc be run by default */
437430
#define IPSET_GC_TIME (3 * 60)
438431

include/linux/netfilter/nfnetlink.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct nfnetlink_subsystem {
3131
const struct nfnl_callback *cb; /* callback for individual types */
3232
struct module *owner;
3333
int (*commit)(struct net *net, struct sk_buff *skb);
34-
int (*abort)(struct net *net, struct sk_buff *skb);
34+
int (*abort)(struct net *net, struct sk_buff *skb, bool autoload);
3535
void (*cleanup)(struct net *net);
3636
bool (*valid_genid)(struct net *net, u32 genid);
3737
};

include/net/netns/nftables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
struct netns_nftables {
88
struct list_head tables;
99
struct list_head commit_list;
10+
struct list_head module_list;
1011
struct mutex commit_mutex;
1112
unsigned int base_seq;
1213
u8 gencursor;

net/core/utils.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,23 @@ void inet_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
438438
}
439439
EXPORT_SYMBOL(inet_proto_csum_replace4);
440440

441+
/**
442+
* inet_proto_csum_replace16 - update layer 4 header checksum field
443+
* @sum: Layer 4 header checksum field
444+
* @skb: sk_buff for the packet
445+
* @from: old IPv6 address
446+
* @to: new IPv6 address
447+
* @pseudohdr: True if layer 4 header checksum includes pseudoheader
448+
*
449+
* Update layer 4 header as per the update in IPv6 src/dst address.
450+
*
451+
* There is no need to update skb->csum in this function, because update in two
452+
* fields a.) IPv6 src/dst address and b.) L4 header checksum cancels each other
453+
* for skb->csum calculation. Whereas inet_proto_csum_replace4 function needs to
454+
* update skb->csum, because update in 3 fields a.) IPv4 src/dst address,
455+
* b.) IPv4 Header checksum and c.) L4 header checksum results in same diff as
456+
* L4 Header checksum for skb->csum calculation.
457+
*/
441458
void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
442459
const __be32 *from, const __be32 *to,
443460
bool pseudohdr)
@@ -449,9 +466,6 @@ void inet_proto_csum_replace16(__sum16 *sum, struct sk_buff *skb,
449466
if (skb->ip_summed != CHECKSUM_PARTIAL) {
450467
*sum = csum_fold(csum_partial(diff, sizeof(diff),
451468
~csum_unfold(*sum)));
452-
if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
453-
skb->csum = ~csum_partial(diff, sizeof(diff),
454-
~skb->csum);
455469
} else if (pseudohdr)
456470
*sum = ~csum_fold(csum_partial(diff, sizeof(diff),
457471
csum_unfold(*sum)));

net/netfilter/ipset/ip_set_bitmap_gen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ mtype_flush(struct ip_set *set)
7575

7676
if (set->extensions & IPSET_EXT_DESTROY)
7777
mtype_ext_cleanup(set);
78-
memset(map->members, 0, map->memsize);
78+
bitmap_zero(map->members, map->elements);
7979
set->elements = 0;
8080
set->ext_size = 0;
8181
}

net/netfilter/ipset/ip_set_bitmap_ip.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ MODULE_ALIAS("ip_set_bitmap:ip");
3737

3838
/* Type structure */
3939
struct bitmap_ip {
40-
void *members; /* the set members */
40+
unsigned long *members; /* the set members */
4141
u32 first_ip; /* host byte order, included in range */
4242
u32 last_ip; /* host byte order, included in range */
4343
u32 elements; /* number of max elements in the set */
@@ -220,7 +220,7 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
220220
u32 first_ip, u32 last_ip,
221221
u32 elements, u32 hosts, u8 netmask)
222222
{
223-
map->members = ip_set_alloc(map->memsize);
223+
map->members = bitmap_zalloc(elements, GFP_KERNEL | __GFP_NOWARN);
224224
if (!map->members)
225225
return false;
226226
map->first_ip = first_ip;
@@ -322,7 +322,7 @@ bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
322322
if (!map)
323323
return -ENOMEM;
324324

325-
map->memsize = bitmap_bytes(0, elements - 1);
325+
map->memsize = BITS_TO_LONGS(elements) * sizeof(unsigned long);
326326
set->variant = &bitmap_ip;
327327
if (!init_map_ip(set, map, first_ip, last_ip,
328328
elements, hosts, netmask)) {

net/netfilter/ipset/ip_set_bitmap_ipmac.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ enum {
4242

4343
/* Type structure */
4444
struct bitmap_ipmac {
45-
void *members; /* the set members */
45+
unsigned long *members; /* the set members */
4646
u32 first_ip; /* host byte order, included in range */
4747
u32 last_ip; /* host byte order, included in range */
4848
u32 elements; /* number of max elements in the set */
@@ -299,7 +299,7 @@ static bool
299299
init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
300300
u32 first_ip, u32 last_ip, u32 elements)
301301
{
302-
map->members = ip_set_alloc(map->memsize);
302+
map->members = bitmap_zalloc(elements, GFP_KERNEL | __GFP_NOWARN);
303303
if (!map->members)
304304
return false;
305305
map->first_ip = first_ip;
@@ -360,7 +360,7 @@ bitmap_ipmac_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
360360
if (!map)
361361
return -ENOMEM;
362362

363-
map->memsize = bitmap_bytes(0, elements - 1);
363+
map->memsize = BITS_TO_LONGS(elements) * sizeof(unsigned long);
364364
set->variant = &bitmap_ipmac;
365365
if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
366366
kfree(map);

net/netfilter/ipset/ip_set_bitmap_port.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ MODULE_ALIAS("ip_set_bitmap:port");
3030

3131
/* Type structure */
3232
struct bitmap_port {
33-
void *members; /* the set members */
33+
unsigned long *members; /* the set members */
3434
u16 first_port; /* host byte order, included in range */
3535
u16 last_port; /* host byte order, included in range */
3636
u32 elements; /* number of max elements in the set */
@@ -231,7 +231,7 @@ static bool
231231
init_map_port(struct ip_set *set, struct bitmap_port *map,
232232
u16 first_port, u16 last_port)
233233
{
234-
map->members = ip_set_alloc(map->memsize);
234+
map->members = bitmap_zalloc(map->elements, GFP_KERNEL | __GFP_NOWARN);
235235
if (!map->members)
236236
return false;
237237
map->first_port = first_port;
@@ -271,7 +271,7 @@ bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
271271
return -ENOMEM;
272272

273273
map->elements = elements;
274-
map->memsize = bitmap_bytes(0, map->elements);
274+
map->memsize = BITS_TO_LONGS(elements) * sizeof(unsigned long);
275275
set->variant = &bitmap_port;
276276
if (!init_map_port(set, map, first_port, last_port)) {
277277
kfree(map);

net/netfilter/nf_conntrack_proto_sctp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
114114
{
115115
/* ORIGINAL */
116116
/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
117-
/* init */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA, sCW, sHA},
117+
/* init */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCW, sHA},
118118
/* init_ack */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},
119119
/* abort */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
120120
/* shutdown */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL, sSS},
@@ -130,7 +130,7 @@ static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
130130
/* REPLY */
131131
/* sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
132132
/* init */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},/* INIT in sCL Big TODO */
133-
/* init_ack */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},
133+
/* init_ack */ {sIV, sCW, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},
134134
/* abort */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV, sCL},
135135
/* shutdown */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV, sSR},
136136
/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV, sHA},
@@ -316,7 +316,7 @@ sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
316316
ct->proto.sctp.vtag[IP_CT_DIR_REPLY] = sh->vtag;
317317
}
318318

319-
ct->proto.sctp.state = new_state;
319+
ct->proto.sctp.state = SCTP_CONNTRACK_NONE;
320320
}
321321

322322
return true;

0 commit comments

Comments
 (0)