Skip to content

Commit 743b83f

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: nft_socket: only do sk lookups when indev is available
Check if the incoming interface is available and NFT_BREAK in case neither skb->sk nor input device are set. Because nf_sk_lookup_slow*() assume packet headers are in the 'in' direction, use in postrouting is not going to yield a meaningful result. Same is true for the forward chain, so restrict the use to prerouting, input and output. Use in output work if a socket is already attached to the skb. Fixes: 554ced0 ("netfilter: nf_tables: add support for native socket matching") Reported-and-tested-by: Topi Miettinen <[email protected]> Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 626873c commit 743b83f

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

net/netfilter/nft_socket.c

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,32 @@ nft_sock_get_eval_cgroupv2(u32 *dest, struct sock *sk, const struct nft_pktinfo
5454
}
5555
#endif
5656

57+
static struct sock *nft_socket_do_lookup(const struct nft_pktinfo *pkt)
58+
{
59+
const struct net_device *indev = nft_in(pkt);
60+
const struct sk_buff *skb = pkt->skb;
61+
struct sock *sk = NULL;
62+
63+
if (!indev)
64+
return NULL;
65+
66+
switch (nft_pf(pkt)) {
67+
case NFPROTO_IPV4:
68+
sk = nf_sk_lookup_slow_v4(nft_net(pkt), skb, indev);
69+
break;
70+
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
71+
case NFPROTO_IPV6:
72+
sk = nf_sk_lookup_slow_v6(nft_net(pkt), skb, indev);
73+
break;
74+
#endif
75+
default:
76+
WARN_ON_ONCE(1);
77+
break;
78+
}
79+
80+
return sk;
81+
}
82+
5783
static void nft_socket_eval(const struct nft_expr *expr,
5884
struct nft_regs *regs,
5985
const struct nft_pktinfo *pkt)
@@ -67,20 +93,7 @@ static void nft_socket_eval(const struct nft_expr *expr,
6793
sk = NULL;
6894

6995
if (!sk)
70-
switch(nft_pf(pkt)) {
71-
case NFPROTO_IPV4:
72-
sk = nf_sk_lookup_slow_v4(nft_net(pkt), skb, nft_in(pkt));
73-
break;
74-
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
75-
case NFPROTO_IPV6:
76-
sk = nf_sk_lookup_slow_v6(nft_net(pkt), skb, nft_in(pkt));
77-
break;
78-
#endif
79-
default:
80-
WARN_ON_ONCE(1);
81-
regs->verdict.code = NFT_BREAK;
82-
return;
83-
}
96+
sk = nft_socket_do_lookup(pkt);
8497

8598
if (!sk) {
8699
regs->verdict.code = NFT_BREAK;
@@ -224,13 +237,24 @@ static bool nft_socket_reduce(struct nft_regs_track *track,
224237
return nft_expr_reduce_bitwise(track, expr);
225238
}
226239

240+
static int nft_socket_validate(const struct nft_ctx *ctx,
241+
const struct nft_expr *expr,
242+
const struct nft_data **data)
243+
{
244+
return nft_chain_validate_hooks(ctx->chain,
245+
(1 << NF_INET_PRE_ROUTING) |
246+
(1 << NF_INET_LOCAL_IN) |
247+
(1 << NF_INET_LOCAL_OUT));
248+
}
249+
227250
static struct nft_expr_type nft_socket_type;
228251
static const struct nft_expr_ops nft_socket_ops = {
229252
.type = &nft_socket_type,
230253
.size = NFT_EXPR_SIZE(sizeof(struct nft_socket)),
231254
.eval = nft_socket_eval,
232255
.init = nft_socket_init,
233256
.dump = nft_socket_dump,
257+
.validate = nft_socket_validate,
234258
.reduce = nft_socket_reduce,
235259
};
236260

0 commit comments

Comments
 (0)