Skip to content

Commit 00a25cc

Browse files
committed
Merge tag 'nf-next-25-03-23' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following batch contains Netfilter updates for net-next: 1) Use kvmalloc in xt_hashlimit, from Denis Kirjanov. 2) Tighten nf_conntrack sysctl accepted values for nf_conntrack_max and nf_ct_expect_max, from Nicolas Bouchinet. 3) Avoid lookup in nft_fib if socket is available, from Florian Westphal. 4) Initialize struct lsm_context in nfnetlink_queue to avoid hypothetical ENOMEM errors, Chenyuan Yang. 5) Use strscpy() instead of _pad when initializing xtables table name, kzalloc is already used to initialized the table memory area. From Thorsten Blum. 6) Missing socket lookup by conntrack information for IPv6 traffic in nft_socket, there is a similar chunk in IPv4, this was never added when IPv6 NAT was introduced. From Maxim Mikityanskiy. 7) Fix clang issues with nf_tables CONFIG_MITIGATION_RETPOLINE, from WangYuli. * tag 'nf-next-25-03-23' of git://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf-next: netfilter: nf_tables: Only use nf_skip_indirect_calls() when MITIGATION_RETPOLINE netfilter: socket: Lookup orig tuple for IPv6 SNAT netfilter: xtables: Use strscpy() instead of strscpy_pad() netfilter: nfnetlink_queue: Initialize ctx to avoid memory allocation error netfilter: fib: avoid lookup if socket is available netfilter: conntrack: Bound nf_conntrack sysctl writes netfilter: xt_hashlimit: replace vmalloc calls with kvmalloc ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 5e8df79 + e3a4182 commit 00a25cc

File tree

9 files changed

+79
-34
lines changed

9 files changed

+79
-34
lines changed

include/net/netfilter/nft_fib.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,27 @@ nft_fib_is_loopback(const struct sk_buff *skb, const struct net_device *in)
1818
return skb->pkt_type == PACKET_LOOPBACK || in->flags & IFF_LOOPBACK;
1919
}
2020

21+
static inline bool nft_fib_can_skip(const struct nft_pktinfo *pkt)
22+
{
23+
const struct net_device *indev = nft_in(pkt);
24+
const struct sock *sk;
25+
26+
switch (nft_hook(pkt)) {
27+
case NF_INET_PRE_ROUTING:
28+
case NF_INET_INGRESS:
29+
case NF_INET_LOCAL_IN:
30+
break;
31+
default:
32+
return false;
33+
}
34+
35+
sk = pkt->skb->sk;
36+
if (sk && sk_fullsock(sk))
37+
return sk->sk_rx_dst_ifindex == indev->ifindex;
38+
39+
return nft_fib_is_loopback(pkt->skb, indev);
40+
}
41+
2142
int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr, bool reset);
2243
int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
2344
const struct nlattr * const tb[]);

net/ipv4/netfilter/nft_fib_ipv4.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,11 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
7171
const struct net_device *oif;
7272
const struct net_device *found;
7373

74+
if (nft_fib_can_skip(pkt)) {
75+
nft_fib_store_result(dest, priv, nft_in(pkt));
76+
return;
77+
}
78+
7479
/*
7580
* Do not set flowi4_oif, it restricts results (for example, asking
7681
* for oif 3 will get RTN_UNICAST result even if the daddr exits
@@ -85,12 +90,6 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
8590
else
8691
oif = NULL;
8792

88-
if (nft_hook(pkt) == NF_INET_PRE_ROUTING &&
89-
nft_fib_is_loopback(pkt->skb, nft_in(pkt))) {
90-
nft_fib_store_result(dest, priv, nft_in(pkt));
91-
return;
92-
}
93-
9493
iph = skb_header_pointer(pkt->skb, noff, sizeof(_iph), &_iph);
9594
if (!iph) {
9695
regs->verdict.code = NFT_BREAK;

net/ipv6/netfilter/nf_socket_ipv6.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
103103
struct sk_buff *data_skb = NULL;
104104
int doff = 0;
105105
int thoff = 0, tproto;
106+
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
107+
enum ip_conntrack_info ctinfo;
108+
struct nf_conn const *ct;
109+
#endif
106110

107111
tproto = ipv6_find_hdr(skb, &thoff, -1, NULL, NULL);
108112
if (tproto < 0) {
@@ -136,6 +140,25 @@ struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
136140
return NULL;
137141
}
138142

143+
#if IS_ENABLED(CONFIG_NF_CONNTRACK)
144+
/* Do the lookup with the original socket address in
145+
* case this is a reply packet of an established
146+
* SNAT-ted connection.
147+
*/
148+
ct = nf_ct_get(skb, &ctinfo);
149+
if (ct &&
150+
((tproto != IPPROTO_ICMPV6 &&
151+
ctinfo == IP_CT_ESTABLISHED_REPLY) ||
152+
(tproto == IPPROTO_ICMPV6 &&
153+
ctinfo == IP_CT_RELATED_REPLY)) &&
154+
(ct->status & IPS_SRC_NAT_DONE)) {
155+
daddr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.in6;
156+
dport = (tproto == IPPROTO_TCP) ?
157+
ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port :
158+
ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
159+
}
160+
#endif
161+
139162
return nf_socket_get_sock_v6(net, data_skb, doff, tproto, saddr, daddr,
140163
sport, dport, indev);
141164
}

net/ipv6/netfilter/nft_fib_ipv6.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
170170
struct rt6_info *rt;
171171
int lookup_flags;
172172

173+
if (nft_fib_can_skip(pkt)) {
174+
nft_fib_store_result(dest, priv, nft_in(pkt));
175+
return;
176+
}
177+
173178
if (priv->flags & NFTA_FIB_F_IIF)
174179
oif = nft_in(pkt);
175180
else if (priv->flags & NFTA_FIB_F_OIF)
@@ -181,17 +186,13 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
181186
return;
182187
}
183188

184-
lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif, iph);
185-
186-
if (nft_hook(pkt) == NF_INET_PRE_ROUTING ||
187-
nft_hook(pkt) == NF_INET_INGRESS) {
188-
if (nft_fib_is_loopback(pkt->skb, nft_in(pkt)) ||
189-
nft_fib_v6_skip_icmpv6(pkt->skb, pkt->tprot, iph)) {
190-
nft_fib_store_result(dest, priv, nft_in(pkt));
191-
return;
192-
}
189+
if (nft_fib_v6_skip_icmpv6(pkt->skb, pkt->tprot, iph)) {
190+
nft_fib_store_result(dest, priv, nft_in(pkt));
191+
return;
193192
}
194193

194+
lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif, iph);
195+
195196
*dest = 0;
196197
rt = (void *)ip6_route_lookup(nft_net(pkt), &fl6, pkt->skb,
197198
lookup_flags);

net/netfilter/nf_conntrack_standalone.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,9 @@ static struct ctl_table nf_ct_sysctl_table[] = {
618618
.data = &nf_conntrack_max,
619619
.maxlen = sizeof(int),
620620
.mode = 0644,
621-
.proc_handler = proc_dointvec,
621+
.proc_handler = proc_dointvec_minmax,
622+
.extra1 = SYSCTL_ZERO,
623+
.extra2 = SYSCTL_INT_MAX,
622624
},
623625
[NF_SYSCTL_CT_COUNT] = {
624626
.procname = "nf_conntrack_count",
@@ -654,7 +656,9 @@ static struct ctl_table nf_ct_sysctl_table[] = {
654656
.data = &nf_ct_expect_max,
655657
.maxlen = sizeof(int),
656658
.mode = 0644,
657-
.proc_handler = proc_dointvec,
659+
.proc_handler = proc_dointvec_minmax,
660+
.extra1 = SYSCTL_ONE,
661+
.extra2 = SYSCTL_INT_MAX,
658662
},
659663
[NF_SYSCTL_CT_ACCT] = {
660664
.procname = "nf_conntrack_acct",
@@ -947,7 +951,9 @@ static struct ctl_table nf_ct_netfilter_table[] = {
947951
.data = &nf_conntrack_max,
948952
.maxlen = sizeof(int),
949953
.mode = 0644,
950-
.proc_handler = proc_dointvec,
954+
.proc_handler = proc_dointvec_minmax,
955+
.extra1 = SYSCTL_ZERO,
956+
.extra2 = SYSCTL_INT_MAX,
951957
},
952958
};
953959

net/netfilter/nf_tables_core.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,25 +21,22 @@
2121
#include <net/netfilter/nf_log.h>
2222
#include <net/netfilter/nft_meta.h>
2323

24-
#if defined(CONFIG_MITIGATION_RETPOLINE) && defined(CONFIG_X86)
25-
24+
#ifdef CONFIG_MITIGATION_RETPOLINE
2625
static struct static_key_false nf_tables_skip_direct_calls;
2726

28-
static bool nf_skip_indirect_calls(void)
27+
static inline bool nf_skip_indirect_calls(void)
2928
{
3029
return static_branch_likely(&nf_tables_skip_direct_calls);
3130
}
3231

33-
static void __init nf_skip_indirect_calls_enable(void)
32+
static inline void __init nf_skip_indirect_calls_enable(void)
3433
{
3534
if (!cpu_feature_enabled(X86_FEATURE_RETPOLINE))
3635
static_branch_enable(&nf_tables_skip_direct_calls);
3736
}
3837
#else
39-
static inline bool nf_skip_indirect_calls(void) { return false; }
40-
4138
static inline void nf_skip_indirect_calls_enable(void) { }
42-
#endif
39+
#endif /* CONFIG_MITIGATION_RETPOLINE */
4340

4441
static noinline void __nft_trace_packet(const struct nft_pktinfo *pkt,
4542
const struct nft_verdict *verdict,

net/netfilter/nfnetlink_queue.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ nfqnl_build_packet_message(struct net *net, struct nfqnl_instance *queue,
567567
enum ip_conntrack_info ctinfo = 0;
568568
const struct nfnl_ct_hook *nfnl_ct;
569569
bool csum_verify;
570-
struct lsm_context ctx;
570+
struct lsm_context ctx = { NULL, 0, 0 };
571571
int seclen = 0;
572572
ktime_t tstamp;
573573

net/netfilter/xt_hashlimit.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include <linux/random.h>
1616
#include <linux/jhash.h>
1717
#include <linux/slab.h>
18-
#include <linux/vmalloc.h>
1918
#include <linux/proc_fs.h>
2019
#include <linux/seq_file.h>
2120
#include <linux/list.h>
@@ -294,16 +293,15 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg,
294293
if (size < 16)
295294
size = 16;
296295
}
297-
/* FIXME: don't use vmalloc() here or anywhere else -HW */
298-
hinfo = vmalloc(struct_size(hinfo, hash, size));
296+
hinfo = kvmalloc(struct_size(hinfo, hash, size), GFP_KERNEL);
299297
if (hinfo == NULL)
300298
return -ENOMEM;
301299
*out_hinfo = hinfo;
302300

303301
/* copy match config into hashtable config */
304302
ret = cfg_copy(&hinfo->cfg, (void *)cfg, 3);
305303
if (ret) {
306-
vfree(hinfo);
304+
kvfree(hinfo);
307305
return ret;
308306
}
309307

@@ -322,7 +320,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg,
322320
hinfo->rnd_initialized = false;
323321
hinfo->name = kstrdup(name, GFP_KERNEL);
324322
if (!hinfo->name) {
325-
vfree(hinfo);
323+
kvfree(hinfo);
326324
return -ENOMEM;
327325
}
328326
spin_lock_init(&hinfo->lock);
@@ -344,7 +342,7 @@ static int htable_create(struct net *net, struct hashlimit_cfg3 *cfg,
344342
ops, hinfo);
345343
if (hinfo->pde == NULL) {
346344
kfree(hinfo->name);
347-
vfree(hinfo);
345+
kvfree(hinfo);
348346
return -ENOMEM;
349347
}
350348
hinfo->net = net;
@@ -433,7 +431,7 @@ static void htable_put(struct xt_hashlimit_htable *hinfo)
433431
cancel_delayed_work_sync(&hinfo->gc_work);
434432
htable_selective_cleanup(hinfo, true);
435433
kfree(hinfo->name);
436-
vfree(hinfo);
434+
kvfree(hinfo);
437435
}
438436
}
439437

net/netfilter/xt_repldata.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
if (tbl == NULL) \
3030
return NULL; \
3131
term = (struct type##_error *)&(((char *)tbl)[term_offset]); \
32-
strscpy_pad(tbl->repl.name, info->name, sizeof(tbl->repl.name)); \
32+
strscpy(tbl->repl.name, info->name); \
3333
*term = (struct type##_error)typ2##_ERROR_INIT; \
3434
tbl->repl.valid_hooks = hook_mask; \
3535
tbl->repl.num_entries = nhooks + 1; \

0 commit comments

Comments
 (0)