Skip to content

Commit 20b8364

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 your net tree, they are: 1) Missing check for full sock in ip_route_me_harder(), from Florian Westphal. 2) Incorrect sip helper structure initilization that breaks it when several ports are used, from Christophe Leroy. 3) Fix incorrect assumption when looking up for matching with adjacent intervals in the nft_set_rbtree. 4) Fix broken netlink event error reporting in nf_tables that results in misleading ESRCH errors propagated to userspace listeners. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 4511555 + 25e94a9 commit 20b8364

File tree

5 files changed

+66
-91
lines changed

5 files changed

+66
-91
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -988,9 +988,9 @@ struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
988988
const struct nlattr *nla, u32 objtype,
989989
u8 genmask);
990990

991-
int nft_obj_notify(struct net *net, struct nft_table *table,
992-
struct nft_object *obj, u32 portid, u32 seq,
993-
int event, int family, int report, gfp_t gfp);
991+
void nft_obj_notify(struct net *net, struct nft_table *table,
992+
struct nft_object *obj, u32 portid, u32 seq,
993+
int event, int family, int report, gfp_t gfp);
994994

995995
/**
996996
* struct nft_object_type - stateful object type

net/ipv4/netfilter.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned int addr_t
2323
struct rtable *rt;
2424
struct flowi4 fl4 = {};
2525
__be32 saddr = iph->saddr;
26-
__u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
26+
const struct sock *sk = skb_to_full_sk(skb);
27+
__u8 flags = sk ? inet_sk_flowi_flags(sk) : 0;
2728
struct net_device *dev = skb_dst(skb)->dev;
2829
unsigned int hh_len;
2930

@@ -40,7 +41,7 @@ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned int addr_t
4041
fl4.daddr = iph->daddr;
4142
fl4.saddr = saddr;
4243
fl4.flowi4_tos = RT_TOS(iph->tos);
43-
fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
44+
fl4.flowi4_oif = sk ? sk->sk_bound_dev_if : 0;
4445
if (!fl4.flowi4_oif)
4546
fl4.flowi4_oif = l3mdev_master_ifindex(dev);
4647
fl4.flowi4_mark = skb->mark;
@@ -61,7 +62,7 @@ int ip_route_me_harder(struct net *net, struct sk_buff *skb, unsigned int addr_t
6162
xfrm_decode_session(skb, flowi4_to_flowi(&fl4), AF_INET) == 0) {
6263
struct dst_entry *dst = skb_dst(skb);
6364
skb_dst_set(skb, NULL);
64-
dst = xfrm_lookup(net, dst, flowi4_to_flowi(&fl4), skb->sk, 0);
65+
dst = xfrm_lookup(net, dst, flowi4_to_flowi(&fl4), sk, 0);
6566
if (IS_ERR(dst))
6667
return PTR_ERR(dst);
6768
skb_dst_set(skb, dst);

net/netfilter/nf_conntrack_sip.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,8 +1628,6 @@ static int __init nf_conntrack_sip_init(void)
16281628
ports[ports_c++] = SIP_PORT;
16291629

16301630
for (i = 0; i < ports_c; i++) {
1631-
memset(&sip[i], 0, sizeof(sip[i]));
1632-
16331631
nf_ct_helper_init(&sip[4 * i], AF_INET, IPPROTO_UDP, "sip",
16341632
SIP_PORT, ports[i], i, sip_exp_policy,
16351633
SIP_EXPECT_MAX,

net/netfilter/nf_tables_api.c

Lines changed: 55 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -461,16 +461,15 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
461461
return -1;
462462
}
463463

464-
static int nf_tables_table_notify(const struct nft_ctx *ctx, int event)
464+
static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
465465
{
466466
struct sk_buff *skb;
467467
int err;
468468

469469
if (!ctx->report &&
470470
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
471-
return 0;
471+
return;
472472

473-
err = -ENOBUFS;
474473
skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
475474
if (skb == NULL)
476475
goto err;
@@ -482,14 +481,11 @@ static int nf_tables_table_notify(const struct nft_ctx *ctx, int event)
482481
goto err;
483482
}
484483

485-
err = nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
486-
ctx->report, GFP_KERNEL);
484+
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
485+
ctx->report, GFP_KERNEL);
486+
return;
487487
err:
488-
if (err < 0) {
489-
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES,
490-
err);
491-
}
492-
return err;
488+
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
493489
}
494490

495491
static int nf_tables_dump_tables(struct sk_buff *skb,
@@ -1050,16 +1046,15 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, struct net *net,
10501046
return -1;
10511047
}
10521048

1053-
static int nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
1049+
static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
10541050
{
10551051
struct sk_buff *skb;
10561052
int err;
10571053

10581054
if (!ctx->report &&
10591055
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
1060-
return 0;
1056+
return;
10611057

1062-
err = -ENOBUFS;
10631058
skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
10641059
if (skb == NULL)
10651060
goto err;
@@ -1072,14 +1067,11 @@ static int nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
10721067
goto err;
10731068
}
10741069

1075-
err = nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1076-
ctx->report, GFP_KERNEL);
1070+
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1071+
ctx->report, GFP_KERNEL);
1072+
return;
10771073
err:
1078-
if (err < 0) {
1079-
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1080-
err);
1081-
}
1082-
return err;
1074+
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
10831075
}
10841076

10851077
static int nf_tables_dump_chains(struct sk_buff *skb,
@@ -1934,18 +1926,16 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net,
19341926
return -1;
19351927
}
19361928

1937-
static int nf_tables_rule_notify(const struct nft_ctx *ctx,
1938-
const struct nft_rule *rule,
1939-
int event)
1929+
static void nf_tables_rule_notify(const struct nft_ctx *ctx,
1930+
const struct nft_rule *rule, int event)
19401931
{
19411932
struct sk_buff *skb;
19421933
int err;
19431934

19441935
if (!ctx->report &&
19451936
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
1946-
return 0;
1937+
return;
19471938

1948-
err = -ENOBUFS;
19491939
skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
19501940
if (skb == NULL)
19511941
goto err;
@@ -1958,14 +1948,11 @@ static int nf_tables_rule_notify(const struct nft_ctx *ctx,
19581948
goto err;
19591949
}
19601950

1961-
err = nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1962-
ctx->report, GFP_KERNEL);
1951+
nfnetlink_send(skb, ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1952+
ctx->report, GFP_KERNEL);
1953+
return;
19631954
err:
1964-
if (err < 0) {
1965-
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES,
1966-
err);
1967-
}
1968-
return err;
1955+
nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
19691956
}
19701957

19711958
struct nft_rule_dump_ctx {
@@ -2696,19 +2683,18 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
26962683
return -1;
26972684
}
26982685

2699-
static int nf_tables_set_notify(const struct nft_ctx *ctx,
2700-
const struct nft_set *set,
2701-
int event, gfp_t gfp_flags)
2686+
static void nf_tables_set_notify(const struct nft_ctx *ctx,
2687+
const struct nft_set *set, int event,
2688+
gfp_t gfp_flags)
27022689
{
27032690
struct sk_buff *skb;
27042691
u32 portid = ctx->portid;
27052692
int err;
27062693

27072694
if (!ctx->report &&
27082695
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
2709-
return 0;
2696+
return;
27102697

2711-
err = -ENOBUFS;
27122698
skb = nlmsg_new(NLMSG_GOODSIZE, gfp_flags);
27132699
if (skb == NULL)
27142700
goto err;
@@ -2719,12 +2705,11 @@ static int nf_tables_set_notify(const struct nft_ctx *ctx,
27192705
goto err;
27202706
}
27212707

2722-
err = nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES,
2723-
ctx->report, gfp_flags);
2708+
nfnetlink_send(skb, ctx->net, portid, NFNLGRP_NFTABLES, ctx->report,
2709+
gfp_flags);
2710+
return;
27242711
err:
2725-
if (err < 0)
2726-
nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, err);
2727-
return err;
2712+
nfnetlink_set_err(ctx->net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
27282713
}
27292714

27302715
static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
@@ -3504,20 +3489,19 @@ static int nf_tables_fill_setelem_info(struct sk_buff *skb,
35043489
return -1;
35053490
}
35063491

3507-
static int nf_tables_setelem_notify(const struct nft_ctx *ctx,
3508-
const struct nft_set *set,
3509-
const struct nft_set_elem *elem,
3510-
int event, u16 flags)
3492+
static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
3493+
const struct nft_set *set,
3494+
const struct nft_set_elem *elem,
3495+
int event, u16 flags)
35113496
{
35123497
struct net *net = ctx->net;
35133498
u32 portid = ctx->portid;
35143499
struct sk_buff *skb;
35153500
int err;
35163501

35173502
if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
3518-
return 0;
3503+
return;
35193504

3520-
err = -ENOBUFS;
35213505
skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
35223506
if (skb == NULL)
35233507
goto err;
@@ -3529,12 +3513,11 @@ static int nf_tables_setelem_notify(const struct nft_ctx *ctx,
35293513
goto err;
35303514
}
35313515

3532-
err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, ctx->report,
3533-
GFP_KERNEL);
3516+
nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, ctx->report,
3517+
GFP_KERNEL);
3518+
return;
35343519
err:
3535-
if (err < 0)
3536-
nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
3537-
return err;
3520+
nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
35383521
}
35393522

35403523
static struct nft_trans *nft_trans_elem_alloc(struct nft_ctx *ctx,
@@ -4476,18 +4459,17 @@ static int nf_tables_delobj(struct net *net, struct sock *nlsk,
44764459
return nft_delobj(&ctx, obj);
44774460
}
44784461

4479-
int nft_obj_notify(struct net *net, struct nft_table *table,
4480-
struct nft_object *obj, u32 portid, u32 seq, int event,
4481-
int family, int report, gfp_t gfp)
4462+
void nft_obj_notify(struct net *net, struct nft_table *table,
4463+
struct nft_object *obj, u32 portid, u32 seq, int event,
4464+
int family, int report, gfp_t gfp)
44824465
{
44834466
struct sk_buff *skb;
44844467
int err;
44854468

44864469
if (!report &&
44874470
!nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
4488-
return 0;
4471+
return;
44894472

4490-
err = -ENOBUFS;
44914473
skb = nlmsg_new(NLMSG_GOODSIZE, gfp);
44924474
if (skb == NULL)
44934475
goto err;
@@ -4499,21 +4481,18 @@ int nft_obj_notify(struct net *net, struct nft_table *table,
44994481
goto err;
45004482
}
45014483

4502-
err = nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
4484+
nfnetlink_send(skb, net, portid, NFNLGRP_NFTABLES, report, gfp);
4485+
return;
45034486
err:
4504-
if (err < 0) {
4505-
nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, err);
4506-
}
4507-
return err;
4487+
nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
45084488
}
45094489
EXPORT_SYMBOL_GPL(nft_obj_notify);
45104490

4511-
static int nf_tables_obj_notify(const struct nft_ctx *ctx,
4512-
struct nft_object *obj, int event)
4491+
static void nf_tables_obj_notify(const struct nft_ctx *ctx,
4492+
struct nft_object *obj, int event)
45134493
{
4514-
return nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid,
4515-
ctx->seq, event, ctx->afi->family, ctx->report,
4516-
GFP_KERNEL);
4494+
nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
4495+
ctx->afi->family, ctx->report, GFP_KERNEL);
45174496
}
45184497

45194498
static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
@@ -4543,17 +4522,17 @@ static int nf_tables_fill_gen_info(struct sk_buff *skb, struct net *net,
45434522
return -EMSGSIZE;
45444523
}
45454524

4546-
static int nf_tables_gen_notify(struct net *net, struct sk_buff *skb, int event)
4525+
static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb,
4526+
int event)
45474527
{
45484528
struct nlmsghdr *nlh = nlmsg_hdr(skb);
45494529
struct sk_buff *skb2;
45504530
int err;
45514531

45524532
if (nlmsg_report(nlh) &&
45534533
!nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
4554-
return 0;
4534+
return;
45554535

4556-
err = -ENOBUFS;
45574536
skb2 = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
45584537
if (skb2 == NULL)
45594538
goto err;
@@ -4565,14 +4544,12 @@ static int nf_tables_gen_notify(struct net *net, struct sk_buff *skb, int event)
45654544
goto err;
45664545
}
45674546

4568-
err = nfnetlink_send(skb2, net, NETLINK_CB(skb).portid,
4569-
NFNLGRP_NFTABLES, nlmsg_report(nlh), GFP_KERNEL);
4547+
nfnetlink_send(skb2, net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
4548+
nlmsg_report(nlh), GFP_KERNEL);
4549+
return;
45704550
err:
4571-
if (err < 0) {
4572-
nfnetlink_set_err(net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
4573-
err);
4574-
}
4575-
return err;
4551+
nfnetlink_set_err(net, NETLINK_CB(skb).portid, NFNLGRP_NFTABLES,
4552+
-ENOBUFS);
45764553
}
45774554

45784555
static int nf_tables_getgen(struct net *net, struct sock *nlsk,

net/netfilter/nft_set_rbtree.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,10 @@ static bool nft_rbtree_lookup(const struct net *net, const struct nft_set *set,
6060
d = memcmp(this, key, set->klen);
6161
if (d < 0) {
6262
parent = parent->rb_left;
63-
/* In case of adjacent ranges, we always see the high
64-
* part of the range in first place, before the low one.
65-
* So don't update interval if the keys are equal.
66-
*/
67-
if (interval && nft_rbtree_equal(set, this, interval))
63+
if (interval &&
64+
nft_rbtree_equal(set, this, interval) &&
65+
nft_rbtree_interval_end(this) &&
66+
!nft_rbtree_interval_end(interval))
6867
continue;
6968
interval = rbe;
7069
} else if (d > 0)

0 commit comments

Comments
 (0)