diff options
| author | Paolo Abeni <pabeni@redhat.com> | 2026-03-19 15:39:33 +0100 |
|---|---|---|
| committer | Paolo Abeni <pabeni@redhat.com> | 2026-03-19 15:39:33 +0100 |
| commit | e7577a06ae28287ca415aec5c12277e3a80ee372 (patch) | |
| tree | 7af84ba5d5237a2e248b26c25e83e66de1349bae | |
| parent | d75ec7e8ba1979a1eb0b9211d94d749cdce849c8 (diff) | |
| parent | dbdfaae9609629a9569362e3b8f33d0a20fd783c (diff) | |
Merge tag 'nf-26-03-19' 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 UaF when netfilter bpf link goes away while nfnetlink dumps
current hook list, we have to wait until rcu readers are gone.
2) Fix UaF when flowtable fails to register all devices, similar
bug as 1). From Pablo Neira Ayuso.
3) nfnetlink_osf fails to properly validate option length fields.
From Weiming Shi.
netfilter pull request nf-26-03-19
* tag 'nf-26-03-19' of https://git.kernel.org/pub/scm/linux/kernel/git/netfilter/nf:
nfnetlink_osf: validate individual option lengths in fingerprints
netfilter: nf_tables: release flowtable after rcu grace period on error
netfilter: bpf: defer hook memory release until rcu readers are done
====================
Link: https://patch.msgid.link/20260319093834.19933-1-fw@strlen.de
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
| -rw-r--r-- | net/netfilter/nf_bpf_link.c | 2 | ||||
| -rw-r--r-- | net/netfilter/nf_tables_api.c | 1 | ||||
| -rw-r--r-- | net/netfilter/nfnetlink_osf.c | 13 |
3 files changed, 15 insertions, 1 deletions
diff --git a/net/netfilter/nf_bpf_link.c b/net/netfilter/nf_bpf_link.c index 6f3a6411f4af..c20031891b86 100644 --- a/net/netfilter/nf_bpf_link.c +++ b/net/netfilter/nf_bpf_link.c @@ -170,7 +170,7 @@ static int bpf_nf_link_update(struct bpf_link *link, struct bpf_prog *new_prog, static const struct bpf_link_ops bpf_nf_link_lops = { .release = bpf_nf_link_release, - .dealloc = bpf_nf_link_dealloc, + .dealloc_deferred = bpf_nf_link_dealloc, .detach = bpf_nf_link_detach, .show_fdinfo = bpf_nf_link_show_info, .fill_link_info = bpf_nf_link_fill_link_info, diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 9b1c8d0a35fb..3922cff1bb3d 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -9203,6 +9203,7 @@ static int nf_tables_newflowtable(struct sk_buff *skb, return 0; err_flowtable_hooks: + synchronize_rcu(); nft_trans_destroy(trans); err_flowtable_trans: nft_hooks_destroy(&flowtable->hook_list); diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c index 94e3eac5743a..45d9ad231a92 100644 --- a/net/netfilter/nfnetlink_osf.c +++ b/net/netfilter/nfnetlink_osf.c @@ -302,7 +302,9 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, { struct nf_osf_user_finger *f; struct nf_osf_finger *kf = NULL, *sf; + unsigned int tot_opt_len = 0; int err = 0; + int i; if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -318,6 +320,17 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, if (f->opt_num > ARRAY_SIZE(f->opt)) return -EINVAL; + for (i = 0; i < f->opt_num; i++) { + if (!f->opt[i].length || f->opt[i].length > MAX_IPOPTLEN) + return -EINVAL; + if (f->opt[i].kind == OSFOPT_MSS && f->opt[i].length < 4) + return -EINVAL; + + tot_opt_len += f->opt[i].length; + if (tot_opt_len > MAX_IPOPTLEN) + return -EINVAL; + } + if (!memchr(f->genre, 0, MAXGENRELEN) || !memchr(f->subtype, 0, MAXGENRELEN) || !memchr(f->version, 0, MAXGENRELEN)) |
