mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
bpf: Guard conntrack opts error writes
The conntrack lookup and allocation kfuncs take an opts pointer together with an opts__sz argument. The verifier checks only the memory range described by opts__sz, but the wrappers unconditionally write opts->error whenever the internal lookup or allocation helper returns an error. For an invalid size smaller than the end of opts->error, that write can land outside the verifier-checked range. Keep returning NULL for invalid arguments, but only report the error through opts->error when the supplied size includes the field. This preserves error reporting for the supported 12-byte and 16-byte layouts, and for other invalid sizes that still include opts->error. Fixes:b4c2b9593a("net/netfilter: Add unstable CT lookup helpers for XDP and TC-BPF") Fixes:d7e79c97c0("net: netfilter: Add kfuncs to allocate and insert CT") Signed-off-by: Yiyang Chen <chenyy23@mails.tsinghua.edu.cn> Link: https://lore.kernel.org/r/9535e781fe14449b1d4e9bbc3baa7566a93bf512.1781765747.git.chenyy23@mails.tsinghua.edu.cn Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
8816d94303
commit
6f6183a395
|
|
@ -65,6 +65,15 @@ enum {
|
|||
NF_BPF_CT_OPTS_SZ = 16,
|
||||
};
|
||||
|
||||
static void *bpf_ct_opts_result(struct bpf_ct_opts *opts, u32 opts__sz, void *ret)
|
||||
{
|
||||
if (!IS_ERR(ret))
|
||||
return ret;
|
||||
if (opts__sz >= offsetofend(struct bpf_ct_opts, error))
|
||||
opts->error = PTR_ERR(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int bpf_nf_ct_tuple_parse(struct bpf_sock_tuple *bpf_tuple,
|
||||
u32 tuple_len, u8 protonum, u8 dir,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
|
|
@ -297,12 +306,7 @@ bpf_xdp_ct_alloc(struct xdp_md *xdp_ctx, struct bpf_sock_tuple *bpf_tuple,
|
|||
|
||||
nfct = __bpf_nf_ct_alloc_entry(dev_net(ctx->rxq->dev), bpf_tuple, tuple__sz,
|
||||
opts, opts__sz, 10);
|
||||
if (IS_ERR(nfct)) {
|
||||
opts->error = PTR_ERR(nfct);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct nf_conn___init *)nfct;
|
||||
return (struct nf_conn___init *)bpf_ct_opts_result(opts, opts__sz, nfct);
|
||||
}
|
||||
|
||||
/* bpf_xdp_ct_lookup - Lookup CT entry for the given tuple, and acquire a
|
||||
|
|
@ -331,11 +335,7 @@ bpf_xdp_ct_lookup(struct xdp_md *xdp_ctx, struct bpf_sock_tuple *bpf_tuple,
|
|||
|
||||
caller_net = dev_net(ctx->rxq->dev);
|
||||
nfct = __bpf_nf_ct_lookup(caller_net, bpf_tuple, tuple__sz, opts, opts__sz);
|
||||
if (IS_ERR(nfct)) {
|
||||
opts->error = PTR_ERR(nfct);
|
||||
return NULL;
|
||||
}
|
||||
return nfct;
|
||||
return bpf_ct_opts_result(opts, opts__sz, nfct);
|
||||
}
|
||||
|
||||
/* bpf_skb_ct_alloc - Allocate a new CT entry
|
||||
|
|
@ -363,12 +363,7 @@ bpf_skb_ct_alloc(struct __sk_buff *skb_ctx, struct bpf_sock_tuple *bpf_tuple,
|
|||
|
||||
net = skb->dev ? dev_net(skb->dev) : sock_net(skb->sk);
|
||||
nfct = __bpf_nf_ct_alloc_entry(net, bpf_tuple, tuple__sz, opts, opts__sz, 10);
|
||||
if (IS_ERR(nfct)) {
|
||||
opts->error = PTR_ERR(nfct);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (struct nf_conn___init *)nfct;
|
||||
return (struct nf_conn___init *)bpf_ct_opts_result(opts, opts__sz, nfct);
|
||||
}
|
||||
|
||||
/* bpf_skb_ct_lookup - Lookup CT entry for the given tuple, and acquire a
|
||||
|
|
@ -397,11 +392,7 @@ bpf_skb_ct_lookup(struct __sk_buff *skb_ctx, struct bpf_sock_tuple *bpf_tuple,
|
|||
|
||||
caller_net = skb->dev ? dev_net(skb->dev) : sock_net(skb->sk);
|
||||
nfct = __bpf_nf_ct_lookup(caller_net, bpf_tuple, tuple__sz, opts, opts__sz);
|
||||
if (IS_ERR(nfct)) {
|
||||
opts->error = PTR_ERR(nfct);
|
||||
return NULL;
|
||||
}
|
||||
return nfct;
|
||||
return bpf_ct_opts_result(opts, opts__sz, nfct);
|
||||
}
|
||||
|
||||
/* bpf_ct_insert_entry - Add the provided entry into a CT map
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user