Skip to content

Commit dac1dc7

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf
Pablo Neira Ayuso says: ==================== Netfilter/IPVS fixes for net 1) netlink socket notifier might win race to release objects that are already pending to be released via commit release path, reported by syzbot. 2) No need to postpone flow rule release to commit release path, this triggered the syzbot report, complementary fix to previous patch. 3) Use explicit signed chars in IPVS to unbreak arm, from Jason A. Donenfeld. 4) Missing check for proc entry creation failure in IPVS, from Zhengchao Shao. 5) Incorrect error path handling when BPF NAT fails to register, from Chen Zhongjin. 6) Prevent huge memory allocation in ipset hash types, from Jozsef Kadlecsik. Except the incorrect BPF NAT error path which is broken in 6.1-rc, anything else has been broken for several releases. * git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf: netfilter: ipset: enforce documented limit to prevent allocating huge memory netfilter: nf_nat: Fix possible memory leak in nf_nat_init() ipvs: fix WARNING in ip_vs_app_net_cleanup() ipvs: fix WARNING in __ip_vs_cleanup_batch() ipvs: use explicitly signed chars netfilter: nf_tables: release flow rule object from commit path netfilter: nf_tables: netlink notifier might race to release objects ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents ef1fdc9 + 510841d commit dac1dc7

File tree

5 files changed

+52
-37
lines changed

5 files changed

+52
-37
lines changed

net/netfilter/ipset/ip_set_hash_gen.h

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,8 @@
4242
#define AHASH_MAX_SIZE (6 * AHASH_INIT_SIZE)
4343
/* Max muber of elements in the array block when tuned */
4444
#define AHASH_MAX_TUNED 64
45-
4645
#define AHASH_MAX(h) ((h)->bucketsize)
4746

48-
/* Max number of elements can be tuned */
49-
#ifdef IP_SET_HASH_WITH_MULTI
50-
static u8
51-
tune_bucketsize(u8 curr, u32 multi)
52-
{
53-
u32 n;
54-
55-
if (multi < curr)
56-
return curr;
57-
58-
n = curr + AHASH_INIT_SIZE;
59-
/* Currently, at listing one hash bucket must fit into a message.
60-
* Therefore we have a hard limit here.
61-
*/
62-
return n > curr && n <= AHASH_MAX_TUNED ? n : curr;
63-
}
64-
#define TUNE_BUCKETSIZE(h, multi) \
65-
((h)->bucketsize = tune_bucketsize((h)->bucketsize, multi))
66-
#else
67-
#define TUNE_BUCKETSIZE(h, multi)
68-
#endif
69-
7047
/* A hash bucket */
7148
struct hbucket {
7249
struct rcu_head rcu; /* for call_rcu */
@@ -936,7 +913,12 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
936913
goto set_full;
937914
/* Create a new slot */
938915
if (n->pos >= n->size) {
939-
TUNE_BUCKETSIZE(h, multi);
916+
#ifdef IP_SET_HASH_WITH_MULTI
917+
if (h->bucketsize >= AHASH_MAX_TUNED)
918+
goto set_full;
919+
else if (h->bucketsize < multi)
920+
h->bucketsize += AHASH_INIT_SIZE;
921+
#endif
940922
if (n->size >= AHASH_MAX(h)) {
941923
/* Trigger rehashing */
942924
mtype_data_next(&h->next, d);

net/netfilter/ipvs/ip_vs_app.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,13 +599,19 @@ static const struct seq_operations ip_vs_app_seq_ops = {
599599
int __net_init ip_vs_app_net_init(struct netns_ipvs *ipvs)
600600
{
601601
INIT_LIST_HEAD(&ipvs->app_list);
602-
proc_create_net("ip_vs_app", 0, ipvs->net->proc_net, &ip_vs_app_seq_ops,
603-
sizeof(struct seq_net_private));
602+
#ifdef CONFIG_PROC_FS
603+
if (!proc_create_net("ip_vs_app", 0, ipvs->net->proc_net,
604+
&ip_vs_app_seq_ops,
605+
sizeof(struct seq_net_private)))
606+
return -ENOMEM;
607+
#endif
604608
return 0;
605609
}
606610

607611
void __net_exit ip_vs_app_net_cleanup(struct netns_ipvs *ipvs)
608612
{
609613
unregister_ip_vs_app(ipvs, NULL /* all */);
614+
#ifdef CONFIG_PROC_FS
610615
remove_proc_entry("ip_vs_app", ipvs->net->proc_net);
616+
#endif
611617
}

net/netfilter/ipvs/ip_vs_conn.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,8 +1265,8 @@ static inline int todrop_entry(struct ip_vs_conn *cp)
12651265
* The drop rate array needs tuning for real environments.
12661266
* Called from timer bh only => no locking
12671267
*/
1268-
static const char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
1269-
static char todrop_counter[9] = {0};
1268+
static const signed char todrop_rate[9] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
1269+
static signed char todrop_counter[9] = {0};
12701270
int i;
12711271

12721272
/* if the conn entry hasn't lasted for 60 seconds, don't drop it.
@@ -1447,20 +1447,36 @@ int __net_init ip_vs_conn_net_init(struct netns_ipvs *ipvs)
14471447
{
14481448
atomic_set(&ipvs->conn_count, 0);
14491449

1450-
proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net,
1451-
&ip_vs_conn_seq_ops, sizeof(struct ip_vs_iter_state));
1452-
proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net,
1453-
&ip_vs_conn_sync_seq_ops,
1454-
sizeof(struct ip_vs_iter_state));
1450+
#ifdef CONFIG_PROC_FS
1451+
if (!proc_create_net("ip_vs_conn", 0, ipvs->net->proc_net,
1452+
&ip_vs_conn_seq_ops,
1453+
sizeof(struct ip_vs_iter_state)))
1454+
goto err_conn;
1455+
1456+
if (!proc_create_net("ip_vs_conn_sync", 0, ipvs->net->proc_net,
1457+
&ip_vs_conn_sync_seq_ops,
1458+
sizeof(struct ip_vs_iter_state)))
1459+
goto err_conn_sync;
1460+
#endif
1461+
14551462
return 0;
1463+
1464+
#ifdef CONFIG_PROC_FS
1465+
err_conn_sync:
1466+
remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
1467+
err_conn:
1468+
return -ENOMEM;
1469+
#endif
14561470
}
14571471

14581472
void __net_exit ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs)
14591473
{
14601474
/* flush all the connection entries first */
14611475
ip_vs_conn_flush(ipvs);
1476+
#ifdef CONFIG_PROC_FS
14621477
remove_proc_entry("ip_vs_conn", ipvs->net->proc_net);
14631478
remove_proc_entry("ip_vs_conn_sync", ipvs->net->proc_net);
1479+
#endif
14641480
}
14651481

14661482
int __init ip_vs_conn_init(void)

net/netfilter/nf_nat_core.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1152,7 +1152,16 @@ static int __init nf_nat_init(void)
11521152
WARN_ON(nf_nat_hook != NULL);
11531153
RCU_INIT_POINTER(nf_nat_hook, &nat_hook);
11541154

1155-
return register_nf_nat_bpf();
1155+
ret = register_nf_nat_bpf();
1156+
if (ret < 0) {
1157+
RCU_INIT_POINTER(nf_nat_hook, NULL);
1158+
nf_ct_helper_expectfn_unregister(&follow_master_nat);
1159+
synchronize_net();
1160+
unregister_pernet_subsys(&nat_net_ops);
1161+
kvfree(nf_nat_bysource);
1162+
}
1163+
1164+
return ret;
11561165
}
11571166

11581167
static void __exit nf_nat_cleanup(void)

net/netfilter/nf_tables_api.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8465,9 +8465,6 @@ static void nft_commit_release(struct nft_trans *trans)
84658465
nf_tables_chain_destroy(&trans->ctx);
84668466
break;
84678467
case NFT_MSG_DELRULE:
8468-
if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
8469-
nft_flow_rule_destroy(nft_trans_flow_rule(trans));
8470-
84718468
nf_tables_rule_destroy(&trans->ctx, nft_trans_rule(trans));
84728469
break;
84738470
case NFT_MSG_DELSET:
@@ -8973,6 +8970,9 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
89738970
nft_rule_expr_deactivate(&trans->ctx,
89748971
nft_trans_rule(trans),
89758972
NFT_TRANS_COMMIT);
8973+
8974+
if (trans->ctx.chain->flags & NFT_CHAIN_HW_OFFLOAD)
8975+
nft_flow_rule_destroy(nft_trans_flow_rule(trans));
89768976
break;
89778977
case NFT_MSG_NEWSET:
89788978
nft_clear(net, nft_trans_set(trans));
@@ -10030,6 +10030,8 @@ static int nft_rcv_nl_event(struct notifier_block *this, unsigned long event,
1003010030
nft_net = nft_pernet(net);
1003110031
deleted = 0;
1003210032
mutex_lock(&nft_net->commit_mutex);
10033+
if (!list_empty(&nf_tables_destroy_list))
10034+
rcu_barrier();
1003310035
again:
1003410036
list_for_each_entry(table, &nft_net->tables, list) {
1003510037
if (nft_table_has_owner(table) &&

0 commit comments

Comments
 (0)