Skip to content

Commit 3a3ec1b

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 updates for your net tree, they are: 1) Fix refcount leak when dumping the dying/unconfirmed conntrack lists, from Florian Westphal. 2) Fix crash in NAT when removing a netnamespace, also from Florian. 3) Fix a crash in IPVS when trying to remove an estimator out of the sysctl scope, from Julian Anastasov. 4) Add zone attribute to the routing to calculate the message size in ctnetlink events, from Ken-ichirou MATSUZAWA. 5) Another fix for the dying/unconfirmed list which was preventing to dump more than one memory page of entries (~17 entries in x86_64). 6) Fix missing RCU-safe list insertion in the rule replacement code in nf_tables. 7) Since the new transaction infrastructure is in place, we have to upgrade the chain use counter from u16 to u32 to avoid overflow after more than 2^16 rules are added. 8) Fix refcount leak when replacing rule in nf_tables. This problem was also introduced in new transaction. 9) Call the ->destroy() callback when releasing nft-xt rules to fix module refcount leaks. 10) Set the family in the netlink messages that contain set elements in nf_tables to make it consistent with other object types. 11) Don't dump NAT port information if it is unset in nft_nat. 12) Update the MAINTAINERS file, I have merged the ebtables entry into netfilter. While at it, also removed the netfilter users mailing list, the development list should be enough. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 62a02c9 + db9cf3a commit 3a3ec1b

File tree

8 files changed

+86
-31
lines changed

8 files changed

+86
-31
lines changed

MAINTAINERS

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3189,14 +3189,6 @@ L: linux-scsi@vger.kernel.org
31893189
S: Maintained
31903190
F: drivers/scsi/eata_pio.*
31913191

3192-
EBTABLES
3193-
L: netfilter-devel@vger.kernel.org
3194-
W: http://ebtables.sourceforge.net/
3195-
S: Orphan
3196-
F: include/linux/netfilter_bridge/ebt_*.h
3197-
F: include/uapi/linux/netfilter_bridge/ebt_*.h
3198-
F: net/bridge/netfilter/ebt*.c
3199-
32003192
EC100 MEDIA DRIVER
32013193
M: Antti Palosaari <crope@iki.fi>
32023194
L: linux-media@vger.kernel.org
@@ -6105,12 +6097,11 @@ F: Documentation/networking/s2io.txt
61056097
F: Documentation/networking/vxge.txt
61066098
F: drivers/net/ethernet/neterion/
61076099

6108-
NETFILTER/IPTABLES
6100+
NETFILTER ({IP,IP6,ARP,EB,NF}TABLES)
61096101
M: Pablo Neira Ayuso <pablo@netfilter.org>
61106102
M: Patrick McHardy <kaber@trash.net>
61116103
M: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
61126104
L: netfilter-devel@vger.kernel.org
6113-
L: netfilter@vger.kernel.org
61146105
L: coreteam@netfilter.org
61156106
W: http://www.netfilter.org/
61166107
W: http://www.iptables.org/

include/net/netfilter/nf_tables.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,9 +503,9 @@ enum nft_chain_flags {
503503
* @net: net namespace that this chain belongs to
504504
* @table: table that this chain belongs to
505505
* @handle: chain handle
506-
* @flags: bitmask of enum nft_chain_flags
507506
* @use: number of jump references to this chain
508507
* @level: length of longest path to this chain
508+
* @flags: bitmask of enum nft_chain_flags
509509
* @name: name of the chain
510510
*/
511511
struct nft_chain {
@@ -514,9 +514,9 @@ struct nft_chain {
514514
struct net *net;
515515
struct nft_table *table;
516516
u64 handle;
517-
u8 flags;
518-
u16 use;
517+
u32 use;
519518
u16 level;
519+
u8 flags;
520520
char name[NFT_CHAIN_MAXNAMELEN];
521521
};
522522

net/netfilter/ipvs/ip_vs_ctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3778,6 +3778,7 @@ static void __net_exit ip_vs_control_net_cleanup_sysctl(struct net *net)
37783778
cancel_delayed_work_sync(&ipvs->defense_work);
37793779
cancel_work_sync(&ipvs->defense_work.work);
37803780
unregister_net_sysctl_table(ipvs->sysctl_hdr);
3781+
ip_vs_stop_estimator(net, &ipvs->tot_stats);
37813782
}
37823783

37833784
#else
@@ -3840,7 +3841,6 @@ void __net_exit ip_vs_control_net_cleanup(struct net *net)
38403841
struct netns_ipvs *ipvs = net_ipvs(net);
38413842

38423843
ip_vs_trash_cleanup(net);
3843-
ip_vs_stop_estimator(net, &ipvs->tot_stats);
38443844
ip_vs_control_net_cleanup_sysctl(net);
38453845
remove_proc_entry("ip_vs_stats_percpu", net->proc_net);
38463846
remove_proc_entry("ip_vs_stats", net->proc_net);

net/netfilter/nf_conntrack_netlink.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,9 @@ ctnetlink_nlmsg_size(const struct nf_conn *ct)
596596
#endif
597597
#ifdef CONFIG_NF_CONNTRACK_MARK
598598
+ nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
599+
#endif
600+
#ifdef CONFIG_NF_CONNTRACK_ZONES
601+
+ nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE */
599602
#endif
600603
+ ctnetlink_proto_size(ct)
601604
+ ctnetlink_label_size(ct)
@@ -1150,7 +1153,7 @@ static int ctnetlink_done_list(struct netlink_callback *cb)
11501153
static int
11511154
ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
11521155
{
1153-
struct nf_conn *ct, *last = NULL;
1156+
struct nf_conn *ct, *last;
11541157
struct nf_conntrack_tuple_hash *h;
11551158
struct hlist_nulls_node *n;
11561159
struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
@@ -1163,8 +1166,7 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
11631166
if (cb->args[2])
11641167
return 0;
11651168

1166-
if (cb->args[0] == nr_cpu_ids)
1167-
return 0;
1169+
last = (struct nf_conn *)cb->args[1];
11681170

11691171
for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
11701172
struct ct_pcpu *pcpu;
@@ -1174,7 +1176,6 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
11741176

11751177
pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
11761178
spin_lock_bh(&pcpu->lock);
1177-
last = (struct nf_conn *)cb->args[1];
11781179
list = dying ? &pcpu->dying : &pcpu->unconfirmed;
11791180
restart:
11801181
hlist_nulls_for_each_entry(h, n, list, hnnode) {
@@ -1193,7 +1194,9 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
11931194
ct);
11941195
rcu_read_unlock();
11951196
if (res < 0) {
1196-
nf_conntrack_get(&ct->ct_general);
1197+
if (!atomic_inc_not_zero(&ct->ct_general.use))
1198+
continue;
1199+
cb->args[0] = cpu;
11971200
cb->args[1] = (unsigned long)ct;
11981201
spin_unlock_bh(&pcpu->lock);
11991202
goto out;
@@ -1202,10 +1205,10 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
12021205
if (cb->args[1]) {
12031206
cb->args[1] = 0;
12041207
goto restart;
1205-
} else
1206-
cb->args[2] = 1;
1208+
}
12071209
spin_unlock_bh(&pcpu->lock);
12081210
}
1211+
cb->args[2] = 1;
12091212
out:
12101213
if (last)
12111214
nf_ct_put(last);
@@ -2039,6 +2042,9 @@ ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
20392042
#endif
20402043
#ifdef CONFIG_NF_CONNTRACK_MARK
20412044
+ nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
2045+
#endif
2046+
#ifdef CONFIG_NF_CONNTRACK_ZONES
2047+
+ nla_total_size(sizeof(u_int16_t)) /* CTA_ZONE */
20422048
#endif
20432049
+ ctnetlink_proto_size(ct)
20442050
;

net/netfilter/nf_nat_core.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,39 @@ static int nf_nat_proto_remove(struct nf_conn *i, void *data)
525525
return i->status & IPS_NAT_MASK ? 1 : 0;
526526
}
527527

528+
static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
529+
{
530+
struct nf_conn_nat *nat = nfct_nat(ct);
531+
532+
if (nf_nat_proto_remove(ct, data))
533+
return 1;
534+
535+
if (!nat || !nat->ct)
536+
return 0;
537+
538+
/* This netns is being destroyed, and conntrack has nat null binding.
539+
* Remove it from bysource hash, as the table will be freed soon.
540+
*
541+
* Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack()
542+
* will delete entry from already-freed table.
543+
*/
544+
if (!del_timer(&ct->timeout))
545+
return 1;
546+
547+
spin_lock_bh(&nf_nat_lock);
548+
hlist_del_rcu(&nat->bysource);
549+
ct->status &= ~IPS_NAT_DONE_MASK;
550+
nat->ct = NULL;
551+
spin_unlock_bh(&nf_nat_lock);
552+
553+
add_timer(&ct->timeout);
554+
555+
/* don't delete conntrack. Although that would make things a lot
556+
* simpler, we'd end up flushing all conntracks on nat rmmod.
557+
*/
558+
return 0;
559+
}
560+
528561
static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto)
529562
{
530563
struct nf_nat_proto_clean clean = {
@@ -795,7 +828,7 @@ static void __net_exit nf_nat_net_exit(struct net *net)
795828
{
796829
struct nf_nat_proto_clean clean = {};
797830

798-
nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean, 0, 0);
831+
nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean, 0, 0);
799832
synchronize_rcu();
800833
nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size);
801834
}

net/netfilter/nf_tables_api.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,9 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
17301730
if (!create || nlh->nlmsg_flags & NLM_F_REPLACE)
17311731
return -EINVAL;
17321732
handle = nf_tables_alloc_handle(table);
1733+
1734+
if (chain->use == UINT_MAX)
1735+
return -EOVERFLOW;
17331736
}
17341737

17351738
if (nla[NFTA_RULE_POSITION]) {
@@ -1789,14 +1792,15 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
17891792

17901793
if (nlh->nlmsg_flags & NLM_F_REPLACE) {
17911794
if (nft_rule_is_active_next(net, old_rule)) {
1792-
trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE,
1795+
trans = nft_trans_rule_add(&ctx, NFT_MSG_DELRULE,
17931796
old_rule);
17941797
if (trans == NULL) {
17951798
err = -ENOMEM;
17961799
goto err2;
17971800
}
17981801
nft_rule_disactivate_next(net, old_rule);
1799-
list_add_tail(&rule->list, &old_rule->list);
1802+
chain->use--;
1803+
list_add_tail_rcu(&rule->list, &old_rule->list);
18001804
} else {
18011805
err = -ENOENT;
18021806
goto err2;
@@ -1826,6 +1830,7 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb,
18261830
list_del_rcu(&nft_trans_rule(trans)->list);
18271831
nft_rule_clear(net, nft_trans_rule(trans));
18281832
nft_trans_destroy(trans);
1833+
chain->use++;
18291834
}
18301835
err2:
18311836
nf_tables_rule_destroy(&ctx, rule);
@@ -2845,7 +2850,7 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)
28452850
goto nla_put_failure;
28462851

28472852
nfmsg = nlmsg_data(nlh);
2848-
nfmsg->nfgen_family = NFPROTO_UNSPEC;
2853+
nfmsg->nfgen_family = ctx.afi->family;
28492854
nfmsg->version = NFNETLINK_V0;
28502855
nfmsg->res_id = 0;
28512856

net/netfilter/nft_compat.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,15 @@ static void
195195
nft_target_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
196196
{
197197
struct xt_target *target = expr->ops->data;
198+
void *info = nft_expr_priv(expr);
199+
struct xt_tgdtor_param par;
200+
201+
par.net = ctx->net;
202+
par.target = target;
203+
par.targinfo = info;
204+
par.family = ctx->afi->family;
205+
if (par.target->destroy != NULL)
206+
par.target->destroy(&par);
198207

199208
module_put(target->me);
200209
}
@@ -382,6 +391,15 @@ static void
382391
nft_match_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
383392
{
384393
struct xt_match *match = expr->ops->data;
394+
void *info = nft_expr_priv(expr);
395+
struct xt_mtdtor_param par;
396+
397+
par.net = ctx->net;
398+
par.match = match;
399+
par.matchinfo = info;
400+
par.family = ctx->afi->family;
401+
if (par.match->destroy != NULL)
402+
par.match->destroy(&par);
385403

386404
module_put(match->me);
387405
}

net/netfilter/nft_nat.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,14 @@ static int nft_nat_dump(struct sk_buff *skb, const struct nft_expr *expr)
175175
if (nla_put_be32(skb,
176176
NFTA_NAT_REG_ADDR_MAX, htonl(priv->sreg_addr_max)))
177177
goto nla_put_failure;
178-
if (nla_put_be32(skb,
179-
NFTA_NAT_REG_PROTO_MIN, htonl(priv->sreg_proto_min)))
180-
goto nla_put_failure;
181-
if (nla_put_be32(skb,
182-
NFTA_NAT_REG_PROTO_MAX, htonl(priv->sreg_proto_max)))
183-
goto nla_put_failure;
178+
if (priv->sreg_proto_min) {
179+
if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MIN,
180+
htonl(priv->sreg_proto_min)))
181+
goto nla_put_failure;
182+
if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MAX,
183+
htonl(priv->sreg_proto_max)))
184+
goto nla_put_failure;
185+
}
184186
return 0;
185187

186188
nla_put_failure:

0 commit comments

Comments
 (0)