Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'nf-26-01-02' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf

Florian Westphal says:

====================
netfilter: updates for net

The following patchset contains Netfilter fixes for *net*:

1) Fix overlap detection for nf_tables with concatenated ranges.
There are cases where element could not be added due to a conflict
with existing range, while kernel reports success to userspace.
2) update selftest to cover this bug.
3) synproxy update path should use READ/WRITE once as we replace
config struct while packet path might read it in parallel.
This relies on said config struct to fit sizeof(long).
From Fernando Fernandez Mancera.
4) Don't return -EEXIST from xtables in module load path, a pending
patch to module infra will spot a warning if this happens.
From Daniel Gomez.
5) Fix a memory leak in nf_tables when chain hits 2**32 users
and rule is to be hw-offloaded, from Zilin Guan.
6) Avoid infinite list growth when insert rate is high in nf_conncount,
also from Fernando.

* tag 'nf-26-01-02' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
netfilter: nf_conncount: update last_gc only when GC has been performed
netfilter: nf_tables: fix memory leak in nf_tables_newrule()
netfilter: replace -EEXIST with -EBUSY
netfilter: nft_synproxy: avoid possible data-race on update operation
selftests: netfilter: nft_concat_range.sh: add check for overlap detection bug
netfilter: nft_set_pipapo: fix range overlap detection
====================

Link: https://patch.msgid.link/20260102114128.7007-1-fw@strlen.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+56 -12
+1 -1
net/bridge/netfilter/ebtables.c
··· 1299 1299 list_for_each_entry(tmpl, &template_tables, list) { 1300 1300 if (WARN_ON_ONCE(strcmp(t->name, tmpl->name) == 0)) { 1301 1301 mutex_unlock(&ebt_mutex); 1302 - return -EEXIST; 1302 + return -EBUSY; 1303 1303 } 1304 1304 } 1305 1305
+1 -1
net/netfilter/nf_conncount.c
··· 229 229 230 230 nf_ct_put(found_ct); 231 231 } 232 + list->last_gc = (u32)jiffies; 232 233 233 234 add_new_node: 234 235 if (WARN_ON_ONCE(list->count > INT_MAX)) { ··· 249 248 conn->jiffies32 = (u32)jiffies; 250 249 list_add_tail(&conn->node, &list->head); 251 250 list->count++; 252 - list->last_gc = (u32)jiffies; 253 251 254 252 out_put: 255 253 if (refcounted)
+2 -2
net/netfilter/nf_log.c
··· 89 89 if (pf == NFPROTO_UNSPEC) { 90 90 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) { 91 91 if (rcu_access_pointer(loggers[i][logger->type])) { 92 - ret = -EEXIST; 92 + ret = -EBUSY; 93 93 goto unlock; 94 94 } 95 95 } ··· 97 97 rcu_assign_pointer(loggers[i][logger->type], logger); 98 98 } else { 99 99 if (rcu_access_pointer(loggers[pf][logger->type])) { 100 - ret = -EEXIST; 100 + ret = -EBUSY; 101 101 goto unlock; 102 102 } 103 103 rcu_assign_pointer(loggers[pf][logger->type], logger);
+2 -1
net/netfilter/nf_tables_api.c
··· 4439 4439 4440 4440 if (!nft_use_inc(&chain->use)) { 4441 4441 err = -EMFILE; 4442 - goto err_release_rule; 4442 + goto err_destroy_flow; 4443 4443 } 4444 4444 4445 4445 if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { ··· 4489 4489 4490 4490 err_destroy_flow_rule: 4491 4491 nft_use_dec_restore(&chain->use); 4492 + err_destroy_flow: 4492 4493 if (flow) 4493 4494 nft_flow_rule_destroy(flow); 4494 4495 err_release_rule:
+2 -2
net/netfilter/nft_set_pipapo.c
··· 1317 1317 else 1318 1318 dup_end = dup_key; 1319 1319 1320 - if (!memcmp(start, dup_key->data, sizeof(*dup_key->data)) && 1321 - !memcmp(end, dup_end->data, sizeof(*dup_end->data))) { 1320 + if (!memcmp(start, dup_key->data, set->klen) && 1321 + !memcmp(end, dup_end->data, set->klen)) { 1322 1322 *elem_priv = &dup->priv; 1323 1323 return -EEXIST; 1324 1324 }
+3 -3
net/netfilter/nft_synproxy.c
··· 48 48 struct tcphdr *_tcph, 49 49 struct synproxy_options *opts) 50 50 { 51 - struct nf_synproxy_info info = priv->info; 51 + struct nf_synproxy_info info = READ_ONCE(priv->info); 52 52 struct net *net = nft_net(pkt); 53 53 struct synproxy_net *snet = synproxy_pernet(net); 54 54 struct sk_buff *skb = pkt->skb; ··· 79 79 struct tcphdr *_tcph, 80 80 struct synproxy_options *opts) 81 81 { 82 - struct nf_synproxy_info info = priv->info; 82 + struct nf_synproxy_info info = READ_ONCE(priv->info); 83 83 struct net *net = nft_net(pkt); 84 84 struct synproxy_net *snet = synproxy_pernet(net); 85 85 struct sk_buff *skb = pkt->skb; ··· 340 340 struct nft_synproxy *newpriv = nft_obj_data(newobj); 341 341 struct nft_synproxy *priv = nft_obj_data(obj); 342 342 343 - priv->info = newpriv->info; 343 + WRITE_ONCE(priv->info, newpriv->info); 344 344 } 345 345 346 346 static struct nft_object_type nft_synproxy_obj_type;
+1 -1
net/netfilter/x_tables.c
··· 1764 1764 int xt_register_template(const struct xt_table *table, 1765 1765 int (*table_init)(struct net *net)) 1766 1766 { 1767 - int ret = -EEXIST, af = table->af; 1767 + int ret = -EBUSY, af = table->af; 1768 1768 struct xt_template *t; 1769 1769 1770 1770 mutex_lock(&xt[af].mutex);
+44 -1
tools/testing/selftests/net/netfilter/nft_concat_range.sh
··· 29 29 net6_port_net6_port net_port_mac_proto_net" 30 30 31 31 # Reported bugs, also described by TYPE_ variables below 32 - BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch doublecreate" 32 + BUGS="flush_remove_add reload net_port_proto_match avx2_mismatch doublecreate insert_overlap" 33 33 34 34 # List of possible paths to pktgen script from kernel tree for performance tests 35 35 PKTGEN_SCRIPT_PATHS=" ··· 410 410 411 411 TYPE_doublecreate=" 412 412 display cannot create same element twice 413 + type_spec ipv4_addr . ipv4_addr 414 + chain_spec ip saddr . ip daddr 415 + dst addr4 416 + proto icmp 417 + 418 + race_repeat 0 419 + 420 + perf_duration 0 421 + " 422 + 423 + TYPE_insert_overlap=" 424 + display reject overlapping range on add 413 425 type_spec ipv4_addr . ipv4_addr 414 426 chain_spec ip saddr . ip daddr 415 427 dst addr4 ··· 1962 1950 err "Could not flush and re-create element in one transaction" 1963 1951 return 1 1964 1952 fi 1953 + 1954 + return 0 1955 + } 1956 + 1957 + add_fail() 1958 + { 1959 + if nft add element inet filter test "$1" 2>/dev/null ; then 1960 + err "Returned success for add ${1} given set:" 1961 + err "$(nft -a list set inet filter test )" 1962 + return 1 1963 + fi 1964 + 1965 + return 0 1966 + } 1967 + 1968 + test_bug_insert_overlap() 1969 + { 1970 + local elements="1.2.3.4 . 1.2.4.1" 1971 + 1972 + setup veth send_"${proto}" set || return ${ksft_skip} 1973 + 1974 + add "{ $elements }" || return 1 1975 + 1976 + elements="1.2.3.0-1.2.3.4 . 1.2.4.1" 1977 + add_fail "{ $elements }" || return 1 1978 + 1979 + elements="1.2.3.0-1.2.3.4 . 1.2.4.2" 1980 + add "{ $elements }" || return 1 1981 + 1982 + elements="1.2.3.4 . 1.2.4.1-1.2.4.2" 1983 + add_fail "{ $elements }" || return 1 1965 1984 1966 1985 return 0 1967 1986 }