summaryrefslogtreecommitdiff
path: root/net
AgeCommit message (Collapse)Author
29 hoursMerge tag '9p-for-7.4-rc2' of https://github.com/martinetd/linuxLinus Torvalds
Pull late 9p updates from Dominique Martinet: "This is mostly a huge wave of LLM-driven fixes. At least the LLM fixes sort of slowed down recently? Or maybe it's just the time of the cycle and/or I got used to it, time will tell... A few exceptions: - a new vsock transport was added, since it's a variant of the existing fd/tcp transport there is little harm in taking it in - there's an incomplete fix for when file actual size doesn't match the size attribute (e.g. exports of sysfs). The fix addresses when st_size > actual size with cache=none but just about everything else is still broken (st_size=0 with actual data regardless of cache, or with data cache st_size > actual is still wrong and so are symlinks with 0 size)... Maybe at some point I'll find time to understand how netfs works and address these :| - some fixes for the usbg transport by its author, thank you!" * tag '9p-for-7.4-rc2' of https://github.com/martinetd/linux: (39 commits) 9p: optimize p9_fcall struct 9p: reject RERROR/RLERROR with zero errcode 9p: do not store the create fid on special files 9p: fall back to the normal open path for non-regular files 9p: don't decrement a server-owned zero nlink 9p: fix kernel-doc warning for enum p9_session_flags 9p: treat read return values of 0 as EOF 9p/xen: validate the response size from the backend 9p: fix typo in file header comments 9p: remove duplicated assignment in v9fs_fill_super() 9p: fix typos and wrong parameter docs in vfs_inode.c 9p: fix header guard comment in acl.h net/9p/usbg: clear stale client pointer on close net/9p/usbg: remove bogus context initialization in alloc_requests net/9p/usbg: fix out_req buffer leak in disable_usb9pfs net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable() net/9p/usbg: always reset completion when disconnecting net/9p/usbg: set client to Disconnected on usb9pfs_disable net/9p/usbg: also disable endpoints on p9_usbg_close net/9p/usbg: Fix use-after-free in disable_usb9pfs() ...
45 hoursMerge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpfLinus Torvalds
Pull bpf fixes from Alexei Starovoitov: "Fix various bugs in bpf core and bpf-lwt. Looks like the speed of us fixing bugs is higher than the number of new bugs found. Not out of the woods yet. sockmap fixes will come later. - Various fixes (Alexei Starovoitov): - Use one may_goto time slice per prog invocation instead of one per stack frame to fix a soft lockup in loops that nest across calls - Fix use-after-free in btf__add_type() in libbpf - Invalidate a dynptr slice when its stack buffer is written or when the frame of the buffer returns - Fix the tracking of pointers to the stack in SCEV - Keep the valid bytes of a packet pointer in SCEV - Fix bpf_throw() in a prog with a private stack in x86 JIT - Compare the arguments of an extension prog with those of its target - Don't accept memory of the prog for struct arguments of KF_ACQUIRE kfuncs and for arguments of an empty struct type - Fix mmap() of an arena: refuse address 0 and a length above max_entries pages, etc. - Don't let bpf_skb_adjust_room() raise gso_size to GSO_BY_FRAGS - Fix lwt progs: reset skb->cb and don't leave a stale MAC header after a prog pushes an IP header, require BPF_LWT_REROUTE when an lwt_in prog changes the protocol, don't call into IPv6 when it is disabled, don't look for the SRH again in the End.BPF helpers, and set a dst for test runs of lwt_in progs - Fix bpf_dynptr_copy() for overlapping ranges in one packet (Ayushman Rout) - Various fixes (Chris Mason): - Reject memory of the prog for kfunc projection type arguments - Require prog fd or capability for cgroup prog detach - Keep the skb network offset signed in cgroup skb progs - Reject non-IPv6 packets in BPF_LWT_ENCAP_SEG6 - Limit the SRH length and move the MAC header in bpf_lwt_seg6_adjust_srh() - Move the transport header together with the headers that bpf_skb_adjust_room() and bpf_lwt_seg6_adjust_srh() move, and use the inner transport header after a decap - Check the offset in bpf_skb_generic_{push,pop}() - Mark jmp mode of ftrace direct trampolines on x86 by clearing bit 63 of the address instead of setting bit 0, since an ftrace callback can start at an odd address (Daniel Borkmann) - Fix psock update-side data races on sk->sk_prot and progs in sockmap (Jakub Sitnicki) - Fix skb_pull() BUG in __bpf_redirect_neigh(): make sure that the MAC and IP headers are there and are linear (Jamal Hadi Salim) - Fix jited line info that is off by the CFI preamble on x86-64, arm64 and riscv64 (Jose Fernandez) - Clamp the trace length in __bpf_get_stack() to fix a write after the end of the buffer (Josef Bacik) - Drop percpu_counter from the htab element count, since its lock can deadlock with NMI and tracing progs that update the same map (Puranjay Mohan) - Propagate scalar precision through stack arguments (Xu Yunxiang) - Fix callback recursion selftest with llvm24 (Yonghong Song) - Free the skb when bpf_xmit() fails to expand the headroom (Yuqiang Sun)" * tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: (61 commits) libbpf: Fix use-after-free in btf__add_type selftests/bpf: Exercise stack argument precision on state reuse bpf: Propagate scalar precision through stack arguments selftests/bpf: Fix callback recursion test with noipa global func selftests/bpf: Test one may_goto time slice per prog invocation bpf: End bpf_loop() when the time of may_goto is up bpf: One may_goto time slice per prog invocation bpf: Pass a pointer to arch_bpf_timed_may_goto() s390/bpf: Support internal-only MOV instruction to resolve per-CPU addrs selftests/bpf: End the loop of parallel_test_bitmap after 50 ms selftests/bpf: Give the first loop of cond_break5 an end selftests/bpf: Don't cast a pointer to .bss in arena_htab_asm bpf: Emit timed may_goto for JITed progs only selftests/bpf: Test writes to the buffer of bpf_dynptr_slice_rdwr() bpf: Invalidate a dynptr slice when its stack buffer is written selftests/bpf: Test a callee that overwrites a spilled pointer of its caller bpf: Don't trust pointers spilled in slots that a callee can write selftests/bpf: Test the join of fp+0 with a value that is not a pointer to stack bpf: Fix the join of fp+0 with a value that is not a pointer to stack selftests/bpf: Run arena_mmap serially and test MAP_FIXED addresses ...
3 daysbpf: lwt: Free the skb when bpf_xmit() fails to expand the headroomYuqiang Sun
When an LWT xmit program returns BPF_OK, bpf_xmit() makes sure that the skb still has room for the link layer header. If pskb_expand_head() fails there, bpf_xmit() returns -ENOMEM without freeing the skb. Its callers, lwtunnel_xmit() and then ip_finish_output2() or ip6_finish_output2(), take any return value other than LWTUNNEL_XMIT_CONTINUE to mean that the skb has been consumed, so nothing frees it. Each such failure leaks the skb, together with what it holds: its dst and its charge to the sending socket, so the socket is never freed either. The other error paths of bpf_xmit() (BPF_DROP, an illegal return code, a changed protocol, a failed reroute) all free the skb. Free it here too. The leak was found with kbound, a static analysis prototype for ownership mismatches at kernel interfaces, on v7.2.12; it is present in mainline. Build-tested with x86_64 and arm64 allmodconfig (W=1, sparse): no new warnings. Run-tested on QEMU (x86_64, KVM) with KASAN: a route through a dummy device with an LWT xmit program that pushes one byte with bpf_skb_change_head(), so the headroom check has to expand the head, and failslab limited to allocations under bpf_xmit(). Each of 10 pings then fails with ENOMEM. Without this patch each leaves a raw socket behind (RAW slab objects 6 -> 16); with it none does (6 -> 6), and nothing else is reported. Without injection both kernels go from 6 to 6. Fixes: 3a0af8fd61f9 ("bpf: BPF for lightweight tunnel infrastructure") Signed-off-by: Yuqiang Sun <izaiahsun@gmail.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101182343.17991-1-izaiahsun@gmail.com
3 daysbpf: Check the offset in bpf_skb_generic_{push,pop}()Chris Mason
To make room for len bytes at offset off, bpf_skb_generic_push() moves the first off bytes and clears len bytes after them. It assumes that the first off bytes are in the linear part. But in bpf_skb_adjust_room() off can be the end of the IP header, and this header can be in a frag. Then the function reads and writes after skb->tail, and can damage skb_shared_info. bpf_skb_generic_pop() checks off + len, but this u32 sum can wrap to a small value. bpf_skb_adjust_room() and bpf_skb_change_proto() calculate off from skb_mac_header_len(). This length is a very large u32 when network_header < mac_header. Then the check can pass, and memmove() reads and writes far outside the skb. Return -ENOMEM from both functions, like the present check, when off > skb->len. Thus the sum cannot wrap. In bpf_skb_generic_push() also pull the first off bytes into the linear part. Now bpf_skb_adjust_room() fails when a prog grows an skb that ends before off. network_header stays wrong. Fixes: 6578171a7ff0 ("bpf: add bpf_skb_change_proto helper") Fixes: 2be7e212d541 ("bpf: add bpf_skb_adjust_room helper") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-28-alexei.starovoitov@gmail.com
3 daysbpf: Use the inner transport header after a decapChris Mason
If skb->encapsulation is set, qdisc_pkt_len_segs_init() reads the TCP header of a GSO packet at skb->inner_transport_header. Otherwise it uses skb->transport_header. A decap with BPF_F_ADJ_ROOM_DECAP_L4_{GRE,UDP} removes the outer transport header. It clears skb->encapsulation if no tunnel flag remains in gso_type. The result in BPF_ADJ_ROOM_MAC mode is: before | MAC | outer IP | GRE | inner IP | TCP | payload transport_header ^ ^ inner_transport_header after | MAC | inner IP | TCP | payload transport_header ^ ^ inner_transport_header Then qdisc_pkt_len_segs_init() reads the inner IP header as a TCP header. Thus the kernel can drop a valid packet with SKB_DROP_REASON_SKB_BAD_GSO. Copy skb->inner_transport_header to skb->transport_header when a decap clears skb->encapsulation. Keep skb->transport_header if it is larger. This occurs if nothing sets the inner field. At tc ingress nothing changes for IPIP or GRO packets. Both fields are at the TCP header there. Fixes: ec20dee2f2c4 ("bpf: Clear decap state on skb_adjust_room shrink path") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-27-alexei.starovoitov@gmail.com
3 daysbpf: Move the transport header with the moved headersChris Mason
bpf_skb_net_hdr_pop() removes len bytes at offset off. bpf_skb_net_hdr_push() does the opposite. skb->data off before | A | removed | B | after | A | B | skb->data off mac_header and network_header move with A. transport_header moves only when it is equal to network_header. inner_transport_header never moves. This is correct only for a header in B. In bpf_lwt_seg6_adjust_srh() transport_header is in A. bpf_skb_adjust_room() can remove both transport headers. With an incorrect header offset, the stack can drop the skb or read outside of it. Also move transport_header with A when it is in A. Set it to offset off when it is in the removed bytes. In BPF_ADJ_ROOM_MAC mode it is then equal to network_header. Do not unset it, because skb_gso_validate_mac_len() uses it without a check. After a removal, set inner_transport_header to off when it is not in B and skb->encapsulation is set. A has only outer headers. Fixes: fe94cc290f53 ("bpf: Add IPv6 Segment Routing helpers") Fixes: 868d523535c2 ("bpf: add bpf_skb_adjust_room encap flags") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-26-alexei.starovoitov@gmail.com
3 daysbpf: Don't let lwt_in progs call into IPv6 when it is disabledAlexei Starovoitov
With ipv6.disable=1, inet6_init() returns before it registers any pernet subsystem. Thus net->ipv6.devconf_all and net->ipv6.seg6_data stay NULL. IS_ENABLED(CONFIG_IPV6) only says that the code is built in. bpf_lwt_input_reroute() and bpf_push_seg6_encap() call into IPv6, but do not test ipv6_mod_enabled(). An lwt_in prog also runs with ipv6.disable=1, and skb->protocol == htons(ETH_P_IPV6) does not prove that IPv6 is enabled. Thus the kernel dereferences NULL and crashes. Return -EAFNOSUPPORT before these calls if ipv6_mod_enabled() is false. BPF_LWT_REROUTE then drops an IPv6 skb. With IPv6 enabled nothing changes. The first Fixes tag is for bpf_push_seg6_encap(), which never had this test. The second tag is for bpf_lwt_input_reroute(). Until that commit it used ipv6_stub, which returned -EAFNOSUPPORT with ipv6.disable=1. Fixes: fe94cc290f53 ("bpf: Add IPv6 Segment Routing helpers") Fixes: ad84b1eefe28 ("bpf: remove ipv6_bpf_stub completely and use direct function calls") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-25-alexei.starovoitov@gmail.com
3 daysbpf: Require BPF_LWT_REROUTE when an lwt_in prog changes the protocolAlexei Starovoitov
When an lwt_in prog returns BPF_OK, bpf_input() calls orig_input(), the input handler of the route. This handler is for one IP version and needs a dst of the same family. But BPF_LWT_ENCAP_IP lets the prog push a header of the other IP version and thus change skb->protocol. Then the handler reads and changes a header of the other IP version. The push of an SRH also replaces the dst, because seg6_lookup_nexthop() puts an rt6_info into the skb. Then ip_forward() uses the rt6_info as a struct rtable. Drop the skb with -EINVAL when skb->protocol changes, as bpf_xmit() does. Drop it also when the family of the dst changes, because skb->protocol does not always show this change. Today no such skb leaves as the prog made it. A prog works as before if it returns BPF_LWT_REROUTE, or if it pushes an SRH on an IPv6 route. The commit in the first Fixes tag lets a prog change skb->protocol. The commit in the second tag adds the check to bpf_xmit() only. Fixes: 52f278774e79 ("bpf: implement BPF_LWT_ENCAP_IP mode in bpf_lwt_push_encap") Fixes: 3bd0b15281af ("bpf: add handling of BPF_LWT_REROUTE to lwt_bpf.c") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-24-alexei.starovoitov@gmail.com
3 daysbpf: Reset skb->cb after an lwt prog pushes an IP headerAlexei Starovoitov
IPCB(skb)->opt holds the offsets from the network header to the IPv4 options. But bpf_lwt_push_ip_encap() moves the network header and does not change IPCB(skb). Then ip_forward_options() and __ip_options_echo() use the old offsets on the pushed header. Thus the kernel corrupts the skb and the stack. If the family changes, the kernel also reads IP6CB(skb) as IPCB(skb), or the reverse. With CONFIG_IPV6_MIP6, it reads IPSKB_FORWARDED as frag_max_size and adds a needless fragment header. Reset skb->cb after the prog. bpf_lwt_push_ip_encap() cannot do it, because bpf_prog_run_save_cb() can restore skb->cb. For IPv4 in IPv4, clear IPCB(skb)->opt as ip_tunnel_xmit() does. If the family changes, clear the cb of the new family but keep iif, because ip6_forward() gets the input device from it. Behind a VRF, skb->skb_iif is the VRF device and cannot replace iif. Do nothing for IPv6 in IPv6, as in seg6_do_srh_encap(). Do the reset in bpf_input() only after a push. Without a push, ip_forward_options() needs the offsets. Do it in bpf_xmit() before each reroute, because an lwt_xmit prog can also change the options. Thus after a reroute without a push, ip_options_fragment() leaves the options in all fragments, and ICMP errors echo none. After BPF_OK or BPF_REDIRECT the skb goes to a device, thus bpf_xmit() does no reset. The inner IPv4 checksum can still be wrong after ip_rcv_options() changes an option. Fixes: 52f278774e79 ("bpf: implement BPF_LWT_ENCAP_IP mode in bpf_lwt_push_encap") Reported-by: Xiang Mei <xmei5@asu.edu> Suggested-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-23-alexei.starovoitov@gmail.com
3 daysbpf: Don't leave a stale MAC header in bpf_lwt_push_ip_encap()Alexei Starovoitov
With BPF_LWT_ENCAP_IP, bpf_lwt_push_encap() pushes a new IP header. The new header overwrites the MAC header of a received skb. But skb->mac_header continues to point to the same bytes. Code that reads the MAC header after the push, for example netfilter, gets bytes of the new header. before the push | MAC header | old IP | payload ^ mac_header ^ network_header today | new header | old IP | payload network_header ^ ^ mac_header this patch, lwt_in | MAC header | new header | old IP | payload ^ mac_header ^ network_header this patch, lwt_xmit | new header | old IP | payload network_header ^ mac_header is not set For lwt_in, move the MAC header in front of the new header before the memcpy(), as __seg6_do_srh_encap() does. skb_cow_head() already reserves len + skb->mac_len bytes. For lwt_xmit, the output path makes a new MAC header. Thus mark skb->mac_header as not set. This is the state of a locally generated skb. Fixes: 52f278774e79 ("bpf: implement BPF_LWT_ENCAP_IP mode in bpf_lwt_push_encap") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-22-alexei.starovoitov@gmail.com
3 daysbpf: Move the MAC header in bpf_lwt_seg6_adjust_srh()Chris Mason
bpf_skb_net_hdr_push() and bpf_skb_net_hdr_pop() change skb->data and skb->mac_header by len. That is correct in a tc prog, where skb->data is the MAC header. But bpf_lwt_seg6_adjust_srh() calls them in an End.BPF prog, where skb->data is the network header. The MAC header does not move: before push | free | MAC header | IPv6 | SRH | payload ^ head ^ mac_header ^ data today | free | MAC h| IPv6 | SRH + len | payload ^ head ^ mac_header ^ data this patch | free | MAC header | IPv6 | SRH + len | payload ^ head ^ mac_header ^ data Users of skb_mac_header() get incorrect bytes until __dev_queue_xmit() sets skb->mac_header again. skb_cow_head() reserves only len bytes. Thus the 16-bit offset skb->mac_header can wrap. A push also changes the "not set" value. In both cases skb_mac_header() points after the skb. Move the MAC header too. Pass len + skb->mac_len to skb_cow_head(). Keep the "not set" value. The second Fixes tag is for this case. Since that commit an End.BPF prog can get an skb with skb->mac_header not set. Fixes: fe94cc290f53 ("bpf: Add IPv6 Segment Routing helpers") Fixes: 20a081b7984c ("seg6: add VRF support for SRv6 End.DT6 behavior") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-21-alexei.starovoitov@gmail.com
3 daysbpf: Don't look for the SRH again in the End.BPF helpersAlexei Starovoitov
A packet can have two SRHs. Thus input_action_end_bpf() uses IP6_FH_F_SKIP_RH to skip routing headers with segments_left 0. The helpers bpf_lwt_seg6_store_bytes() and bpf_lwt_seg6_adjust_srh() can reallocate the head of the skb. Thus they look for the SRH again, but without this flag. +------------------------+ <- the helpers: srh_state->srh | SRH 1, segments_left 0 | +------------------------+ <- input_action_end_bpf(): srh_state->srh | SRH 2 | and srh_state->hdrlen +------------------------+ Then the helpers check offset against the wrong limits. If a helper changes TLVs, seg6_bpf_has_valid_srh() writes the length of SRH 2 to SRH 1. Neither helper changes the offset of the SRH from skb->data. Calculate the new address from this offset. To add IP6_FH_F_SKIP_RH is not sufficient, because advance_nextseg() can set segments_left of SRH 2 to 0. The helper bpf_lwt_seg6_action() can change the headers and still looks for the SRH. Fixes: fbbc5bc2ab8c ("seg6: ignore routing header with segments left equal to 0") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-20-alexei.starovoitov@gmail.com
3 daysbpf: Limit the SRH length in bpf_lwt_seg6_adjust_srh()Chris Mason
bpf_lwt_seg6_adjust_srh() lets an End.BPF prog change the size of the TLVs in the SRH. The helper keeps the SRH length in srh_state->hdrlen, in bytes and without the first 8 bytes. Later seg6_bpf_has_valid_srh() writes it to srh->hdrlen, an 8-bit field in units of 8 bytes. But srh_state->hdrlen has no upper limit, and the cast to u8 can truncate it. After that, seg6_validate_srh() gets the SRH length from srh->hdrlen, and thus it can accept the SRH. Then srh->hdrlen is too small, and a parser reads TLVs as the subsequent header. Return -EFAULT when the new srh_state->hdrlen is larger than 2040, the largest length that srh->hdrlen can hold. To replace a TLV in the largest SRH, a prog can no longer add bytes first. It must remove bytes first. Fixes: fe94cc290f53 ("bpf: Add IPv6 Segment Routing helpers") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-19-alexei.starovoitov@gmail.com
3 daysbpf: Set a dst for test runs of lwt_in progsAlexei Starovoitov
When an lwt prog runs on a route, the skb always has a dst. To push an SRH, bpf_lwt_push_encap() reads the device from this dst. But bpf_prog_test_run_skb() sets a dst for lwt_xmit progs only. Thus the helper dereferences a NULL dst in a test run of an lwt_in prog. Set the same dst, ip6_null_entry, for lwt_in progs. When IPv6 is disabled or not built, their test run now fails with -EOPNOTSUPP too. An lwt_out prog cannot call this helper. Fixes: fe94cc290f53 ("bpf: Add IPv6 Segment Routing helpers") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-18-alexei.starovoitov@gmail.com
3 daysbpf: Reject non-IPv6 packets in BPF_LWT_ENCAP_SEG6Chris Mason
The mode BPF_LWT_ENCAP_SEG6 of bpf_lwt_push_encap() pushes an IPv6 header and an SRH, and it replaces the dst. The SRH says that IPv6 follows, and skb->protocol does not change. Thus the mode assumes an IPv6 packet, but an lwt_in prog also runs for IPv4 packets. After the prog, bpf_input() calls orig_input() of the old dst. This IPv4 handler reads the pushed headers as IPv4. It can write after the packet data, and the kernel crashes. after the push orig_input() expects --------------------- -------------------- skb->protocol ETH_P_IP ETH_P_IP dst rt6_info rtable packet | IPv6 | SRH | IPv4 | | IPv4 | The mode BPF_LWT_ENCAP_SEG6_INLINE returns -EBADMSG for non-IPv6 packets. Apply this check to both modes. End.BPF does not change, because seg6_local_input() drops non-IPv6 packets. Fixes: fe94cc290f53 ("bpf: Add IPv6 Segment Routing helpers") Signed-off-by: Chris Mason <mason@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-17-alexei.starovoitov@gmail.com
3 daysbpf: Don't let bpf_skb_adjust_room() raise gso_size to GSO_BY_FRAGSAlexei Starovoitov
When bpf_skb_adjust_room() shrinks a TCP GSO skb, it adds the number of removed bytes to gso_size. gso_size has 16 bits, and nothing checks the sum. Thus gso_size can wrap to 0 or to a small size, or it can be GSO_BY_FRAGS. GSO_BY_FRAGS is not a size. It tells skb_segment() to read the length of each segment from the frag_list. If the TCP GSO skb has no frag_list, skb_segment() dereferences a NULL pointer. Return -ENOTSUPP and do not change the skb if the sum is GSO_BY_FRAGS or larger. With BPF_F_ADJ_ROOM_FIXED_GSO the helper does not change gso_size, so it shrinks the skb as before. Fixes: 2be7e212d541 ("bpf: add bpf_skb_adjust_room helper") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-16-alexei.starovoitov@gmail.com
4 daysbpf, sockmap: Fix psock update-side data races on sk->sk_prot and progsJakub Sitnicki
The update side of the sockmap psock lifecycle has several unsynchronized accesses to sk->sk_prot and psock prog state that KCSAN flags when the new update-vs-delete race selftest runs. The fix comes from Alexei [1]: * sock_map_link() installed psock programs and called sock_map_init_proto() before taking sk->sk_callback_lock, racing a concurrent teardown's tcp_bpf_update_proto() write of sk->sk_prot. Take the write_lock early, before psock_set_prog() and sock_map_init_proto(), and drop the psock->saved_data_ready gating from prog detection (it is re-checked under the lock before stopping progs). * sock_map_del_link() read psock->saved_data_ready outside the lock. Move the saved_data_ready check under write_lock_bh(&sk->sk_callback_lock) so prog teardown is serialized against the proto restore. * sock_map_psock_get_checked() and sock_map_sk_is_suitable() did plain sk->sk_prot reads. Convert to READ_ONCE() to mark the intentional racy read against the WRITE_ONCE() swap in sock_replace_proto(). With these changes the sock_map_link/psock_set_prog side of the reported KCSAN splats is silenced; the remaining teardown-vs-core-TCP pairings are the separate read-side annotation problem. [1] https://lore.kernel.org/bpf/DMBHB0TQOV1L.38MECMYFGUS5B@gmail.com Suggested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261030-bpf-next-v1-2-035eabf8eae7@cloudflare.com
4 daysbpf: Fix skb_pull() BUG in __bpf_redirect_neigh()Jamal Hadi Salim
The issue: This is a follow-up to the short link-layer header fixes from Eric. After vlan pop_eth, a privileged SCHED_ACT BPF program can call bpf_skb_change_head(skb, 1, 0) and then bpf_redirect_neigh(). __bpf_redirect_neigh() calls skb_pull(skb, sizeof(*ethh)) after checking only that mac_header < network_header. Nothing verifies that the MAC header is long enough, that it is linear, or that the IP header the redirect goes on to read is linear either. A SCHED_ACT BPF program can do: bpf_skb_change_head(skb, 1, 0); bpf_redirect_neigh(lo, NULL, 0, 0); after vlan pop_eth. The skb then has mac_len == 1 and only one byte of linear data; skb_pull(ETH_HLEN) trips the skb->len < skb->data_len BUG in __skb_pull(): kernel BUG at ./include/linux/skbuff.h:2839! RIP: skb_pull+0x40/0x50 Call Trace: skb_do_redirect -> packet_xmit -> packet_sendmsg Kernel panic - not syncing: Fatal exception in interrupt The v4 and v6 paths read ip_hdr() and ipv6_hdr() as soon as the MAC header is gone. On the AF_PACKET frame below that leaves headlen == 0 after the pull, so the network header sits at skb->tail and the route lookup reads ip4h->protocol, ip4h->saddr and ip4h->daddr past the linear area. The Fix: Use skb_network_offset(), which is the MAC header span, instead of skb->mac_len. mac_len is zero for locally generated tc egress and netkit packets, while the span still rejects the one-byte header produced by pop_eth + bpf_skb_change_head(skb, 1, 0). The single check also covers the mac_header >= network_header test it replaces. Use pskb_may_pull() to make the Ethernet header linear before it is read or pulled, and to make the IP header linear in both the v4 and the v6 path before ip_hdr()/ipv6_hdr() is read. The header pointers are taken after the pull, since pskb_may_pull() may reallocate skb->head. Conditions to recreate the bug: On x86-64 with 4 KiB pages, enable CONFIG_PACKET, CONFIG_BPF_SYSCALL, CONFIG_NET_SCH_INGRESS, CONFIG_NET_CLS_MATCHALL, CONFIG_NET_ACT_VLAN and CONFIG_NET_ACT_BPF. Run as root with BPF loading, network administration and raw-packet privileges. Bring lo up and attach a SCHED_ACT program that calls bpf_skb_change_head(skb, 1, 0), then returns bpf_redirect_neigh(skb->ifindex, NULL, 0, 0): ip link set lo up tc qdisc add dev lo clsact tc filter add dev lo egress matchall action vlan pop_eth pipe \ action bpf object-file neigh_chghead.o section action Send an untagged ETH_P_IP frame of ETH_HLEN + 8192 bytes through an AF_PACKET/SOCK_RAW socket bound to lo, without PACKET_VNET_HDR or PACKET_QDISC_BYPASS. Use a unicast destination MAC. The sender's skb has a 14-byte linear Ethernet prefix and a fragmented payload; pop_eth removes that prefix and change_head restores only one linear byte. The unfixed neighbor redirect then tries to pull 14 bytes and BUGs. Sending the same frame without pop_eth and change_head leaves the IP header in the frags, which is the route lookup reading past skb->tail. Fixes: b4ab31414970 ("bpf: Add redirect_neigh helper as redirect drop-in") Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Victor Nogueira <victor@mojatatu.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/netdev/20261027082604.1485903-1-edumazet@kernel.org/ Link: https://lore.kernel.org/all/2a0f5ff1d8db81b07fc4b344b8e68e3505fcbf36f72a471d1678b2f1cecd881b@mail.kernel.org/ Link: https://lore.kernel.org/netdev/DMII4JGTEUEG.2WRJPT6ODT6J0@gmail.com/ Link: https://patch.msgid.link/bpf_redirect_neigh_short_linear.v3.r0.20261031153053-1@mojatatu.com
5 daysxprtrdma: fix up the nfs/nfs-anna merge of the Write chunk head trimSasha Levin
Two fixes for the same Write chunk payload corruption meet in linux-next. In the nfs tree, commit a0db57fee35e ("xprtrdma: Fix Write chunk payload corruption on a short reply header") trims head[0].iov_len in rpcrdma_decode_msg(). In the nfs-anna tree, commit 9ee534a75912 ("xprtrdma: trim head iovec when the payload arrives via a Write chunk") trims it in rpcrdma_inline_fixup() and reduces buflen by the same amount. The merge resolution keeps the caller-side trim. By the time rpcrdma_inline_fixup() runs, head[0].iov_len already equals copy_len, so the block added by the nfs-anna commit never runs and its buflen reduction in rq_rcv_buf and rq_private_buf is lost. The helper is also still passed xdr_pad_size(writelist), while its kernel-doc now describes @writelist as the number of bytes conveyed by the Write chunk. Drop the caller-side trim and pass the full Write chunk length, so that rpcrdma_inline_fixup() is the only place that trims head[0] and reduces buflen. Compute the pad with xdr_pad_size() in the helper, so the padding from the nfs commit stays correct for lengths that are not a multiple of four. Its rpclen calculation and empty reply check stay in rpcrdma_decode_msg(). Fixes: 53ab189bdc14 ("Merge branch 'linux-next' of git://git.linux-nfs.org/projects/anna/linux-nfs.git") Link: https://lore.kernel.org/all/as4aacUf2Q78FMvY@sirena.org.uk/ Signed-off-by: Sasha Levin <sashal@kernel.org> Tested-by: Tim Menninger <tmenninger@everpuredata.com> Reviewed-by: Tim Menninger <tmenninger@everpuredata.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
5 daysMerge tag 'ceph-for-7.4-rc1' of https://github.com/ceph/ceph-clientLinus Torvalds
Pull ceph updates from Ilya Dryomov: "The two things of note here are the disablement of inline data support and a new lazyio mount option to enable LAZYIO behavior globally (instead of via an ioctl on a per-file basis), both from Xiubo. Despite being over a decade old, the inline data feature never lost its experimental status -- it has always been off by default and required passing --yes-i-really-mean-it flag to be turned on. It was officially deprecated in 2020 and is now in the process of being removed on the MDS side. For now it's still possible to re-enable it in Kconfig, but the code will eventually be dropped from the kernel client entirely. Outside of that we have a number of bug fixes, a series from Tal to help phase out older page APIs, some cleanups from Max and a large pile of LLM-based hardening patches. Xiubo is also back in a maintainer role, replacing Slava" * tag 'ceph-for-7.4-rc1' of https://github.com/ceph/ceph-client: (66 commits) ceph: fix uninitialized err in ceph_netfs_issue_read() MAINTAINERS: update ceph and libceph maintainers ceph: validate encoded xattr name lengths ceph: validate MDS reply fragtree split array length ceph: bound name skips in ceph_mdsmap_decode() by the message end ceph: validate fscrypt auth blob length ceph: check the caps of a closed file after caps_wanted_delay_min ceph: don't fail write_begin with -EAGAIN after flushing old snapc ceph: fail readdir when the MDS reply carries no dirfrag ceph: clamp MDS reply result code to the errno range libceph: initialize CRUSH choose argument weights libceph: fix out-of-bounds reads from repeated CRUSH bucket entries ceph: fix 32-bit overflow in readdir reply count check libceph: reject bad connect_seq in msgr1 READY reply ceph: Fix mds session leak in __open_export_target_session() ceph: Fix xattr buffer leak in __send_cap() ceph: fix integer overflow in the snap trace bounds check libceph: bound mon_command ack decode to front len ceph: use alloc_page() in fill_fscrypt_truncate() libceph: use alloc_page() in ceph_alloc_page_vector() ...
5 daysMerge tag 'vfs-7.4-rc1.fixes' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs fixes from Christian Brauner: - writeback: - Update dirtied_when instead of dirtied_time_when when a wb switch puts an inode at the newest end of the target b_dirty list. The list was left out of order so move_expired_inodes() could stop before older inodes, and the lazytime expiration timestamp was reset - Clear the old wb's dirty-I/O state and bandwidth contribution when a batch of inode switches leaves its dirty lists empty. An empty wb stayed scheduled for periodic writeback and inflated bdi->tot_write_bandwidth - Take wb_switch_rwsem across the inode scan of cleanup_offline_cgwb(). The v7.3-rc5 fix that rotates scanned inodes let a scan racing a sync()'s queue_io() move lazytime inodes past the sync's cutoff, so sync() returned without persisting their timestamps - Don't kick writeback for an IOCB_DONTCACHE write on an inode that has no wb yet. With cgroup writeback an O_DIRECT RWF_DONTCACHE write to a block device dereferenced NULL - statmount/listmount/listns: - Refuse statmount() string requests with a buffer that isn't larger than struct statmount - Don't wrap around with a U64_MAX cursor in listmount() and listns() - Don't end listns() at an inactive namespace - Only add init_ipc_ns and init_net to the namespace trees if CONFIG_IPC_NS and CONFIG_NET_NS are enabled - iomap: - Only mark blocks uptodate in __iomap_write_begin() after reading them and let __iomap_write_end() mark the zeroed blocks uptodate once the copy from userspace succeeded - Check a chunk against max_integrity_io_size() on its own before the bio size check - Only enforce block alignment for direct I/O into holes and unwritten extents if IOMAP_DIO_FSBLOCK_ALIGNED is set - backing-file: - Check S_APPEND and S_IMMUTABLE on the backing inode. FUSE passthrough opens the backing file with vfs_open() which skips may_open(), so anyone who may open the FUSE file for writing could overwrite an append-only backing file anywhere or write to an immutable one. Open, mmap and writes now check the backing inode the way may_open() and do_mmap() do - Always call kiocb_end_write() for a queued write - Let backing files inherit FMODE_NONOTIFY from the user file. The event fds fanotify creates for permission events on a stacked filesystem raised FS_OPEN_PERM on the real path from inside the listener's read() and deadlocked listeners with marks on both layers - pidfs: - Look the task up before checking for exit information in PIDFD_GET_INFO and start over if the task no longer owns the pid once all fields have been read. A caller racing release_task() got neither PIDFD_INFO_PID nor PIDFD_INFO_EXIT or ESRCH although the exit information was available, and a caller racing a sub-thread's exec reported that thread's tid as the pid - Clear the mask bits of fields that lie beyond the struct size the caller passed. The uapi header promises that the mask names no such field but a caller passing PIDFD_INFO_SIZE_VER0 got the coredump and supported mask bits set for fields that were never written - aio: - Give the aio ring a ->read_folio that fails with EIO so a fault on a ring whose file was truncated gets SIGBUS instead of jumping to NULL - Check nr_events against the ring size before doubling it in ioctx_alloc() - splice: - Only write back an implicit file position in do_splice() when the splice helper succeeded. splice doesn't take f_pos_lock so a failed splice restored a stale snapshot over a position that a concurrent getdents() had moved. On ext2 the next readdir then trusted an offset inside a directory entry - Retry tee() when the input pipe was emptied or the output pipe filled between the prep steps and link_pipe() instead of returning 0 while the input pipe still has writers, as splice_pipe_to_pipe() does - ucount: - Take the reference that pins a ucounts level on the 0 -> 1 transition before checking the rlimit - Read the parent ucounts before dropping the rlimit count in do_dec_rlimit_put_ucounts() - inode: - Rotate inodes whose page cache couldn't be dropped to the tail of the LRU - Skip inodes that another LRU walker is isolating - setns: - Set nsset->flags before anything in prepare_nsset() can fail so the error path drops the cred prepared for CLONE_NEWUSER. A failing setns() with CLONE_NEWUSER and CLONE_NEWNS leaked it together with its user namespace - Refuse setns(CLONE_NEWNS) for a task that shares its fs_struct again when more namespaces are requested - minix: - Restore uptodate on the pinned bitmap buffers before redirtying them after a failed writeback instead of tripping the warning in mark_buffer_dirty(), as ext2 and ext4 do for their superblock buffers - Reject rmdir() of a directory with a corrupted link count with EFSCORRUPTED instead of hitting the drop_nlink() warning - userns: Keep the exec securebits and their locks when creating or joining a user namespace. set_cred_user_ns() reset all securebits to SECUREBITS_DEFAULT so anyone who may create a user namespace could shed SECBIT_EXEC_RESTRICT_FILE and SECBIT_EXEC_DENY_INTERACTIVE with a single unshare(CLONE_NEWUSER) - fs: Honor FOP_UNSIGNED_OFFSET in sys_llseek() and in the pread64(), pwrite64(), preadv() and pwritev() wrappers - proc/kcore: Advance the vmalloc retry in read_kcore_iter() by the last vread_iter() copy instead of the running total - eventpoll: Return the error when the wakeup source for EPOLLWAKEUP can't be created in EPOLL_CTL_MOD instead of reporting success without suspend protection - coredump: Mark do_coredump() noinline_for_stack - nsfs: Check the trailing bytes of a namespace file handle in bytes instead of words - netfs: Restore the per-level and per-point decoding of the debug mask - exportfs: Release the directory file get_name() opened with __fput_sync(). From nfsd's kernel threads the deferred fputs arrived faster than delayed_fput retired them and each pinned the directory's readdir state, growing unreclaimable slab by about 90 MB per second under a parallel tree walk - fs: Call ramfs_kill_sb() for a ramfs rootfs. Since rootfs can be unmounted as of v7.0 its struct ramfs_fs_info was leaked - signal: Check the blocked mask for every entry dequeue_synchronous_signal() looks at. The scan could select a blocked synchronous signal and deliver it while blocked - super: Convert the superblock device table from an rhltable to a plain hashtable under a spinlock. This fixes a bug from v7.3 where fs_bdev_freeze() froze a btrfs filesystem through a stale member that open_ctree() had already released while the freeze was waiting for SB_BORN - fork: Leave rcu_users at zero until copy_process() can't fail anymore. bpf_task_acquire() handed out trusted references to the new task from the task_alloc LSM hook and sched_ext's ops.init_task() and a failing fork freed the task behind them - xattr: Always run cap_convert_nscap() for a security.capability write. A zero-length setxattr() skipped it and let an unprivileged caller without CAP_SETFCAP or write permission on the file plant an empty security.capability xattr that made every execve() of the binary fail with EINVAL - namei: Skip the S_ISDIR assertion in - proc: Refuse to mount on entries below /proc/<pid>/net like fd/, fdinfo/ and map_files/. proc_net_d_revalidate() always fails so the first lookup by anyone with search permission ran d_invalidate() on the dentry and detached every mount on it, locked mounts included - libfs: Hold one mount reference for all pins instead of one per pin. The pin count is what keeps the mount alive, so the per-pin reference only cost a mntget() and a mntput() through mntput_no_expire_slowpath() for every debugfs, tracefs, securityfs or configfs file that comes and goes - iov_iter: Return 0 from iov_iter_alignment() for an empty iterator of any type - watch_queue: Give info_id its own storage instead of overlaying it with rcu_head - filelock: Take an active superblock reference while waiting for a delegation break. After a lazy umount closing the delegation holder could shut down the superblock under the waiter whose final iput() then ran shmem_evict_inode() on freed state - fs: Skip the copy_file_range() write limit checks when there is no data to copy - bpf: Allow bpf_d_path() from fentry on filp_close_sync(). Since close_range() became synchronous this cycle close(), close_range() and the closes on exec and exit no longer go through filp_close(). fexit stays rejected since the file may be gone by then - fs_pin: Dequeue the wait entry unconditionally in pin_kill(). A spuriously woken waiter kept its on-stack entry queued, took that as proof that the pin was alive and used the freed acct structure when umount() of the accounting file raced acct(2) - dcache: Don't fail __d_obtain_alias() for an inode without links and aliases. The ESTALE check added this cycle broke open_by_handle_at() and nfsd file handle decoding on NFS and FUSE where i_nlink is just what the server last reported and the handle may well still be valid - selftests/ovl: Fix the mountinfo expectations of the detached layer test which has failed since it was added * tag 'vfs-7.4-rc1.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (60 commits) fs: don't fail __d_obtain_alias() for unlinked inodes ns: don't add init_ipc_ns and init_net without namespace support aio: avoid request count overflow in ioctx_alloc() selftests/ovl: fix detached layer mountinfo expectations bpf: Allow bpf_d_path() from filp_close_sync() fs: skip copy_file_range write limits when there is no data minix: reject rmdir of a directory with a corrupted link count fs_pin: do not trust the pin after a spurious wakeup in pin_kill() ucount: read the parent ucounts before dropping the rlimit count splice: retry tee() instead of returning 0 when it races selftests/pidfd: test that fields beyond the struct size are not reported pidfs: do not report fields that do not fit into the caller's struct fs: let backing files inherit FMODE_NONOTIFY from the user file splice: avoid stale f_pos writeback on error backing-file: always end a queued write filelock: keep superblock active through delegation wait watch_queue: keep info_id separate from rcu_head iomap: only follow dio alignment requirement if specified iov_iter: fix NULL deref in iov_iter_alignment() backing-file: enforce append-only and immutable backing inodes ...
5 daysns: don't add init_ipc_ns and init_net without namespace supportChristian Brauner
When CONFIG_IPC_NS or CONFIG_NET_NS are turned off we still add the initial ipc and network namespace to the namespace trees. ipc_ns_init() calls ns_tree_add(&init_ipc_ns) whenever CONFIG_SYSVIPC is set and setup_net() calls ns_tree_add_raw() on init_net whenever CONFIG_NET is set. But without CONFIG_IPC_NS and CONFIG_NET_NS these aren't namespaces userspace can do anything with. They don't have proc_ns_operations so there's no /proc/<pid>/ns/{ipc,net} for them, nsfs_fh_to_dentry() refuses them with -EOPNOTSUPP, and since ns->ops is NULL __ns_tree_add_raw() doesn't add them to the owner list of init_user_ns either. So they end up half registered. That's also not how we treat any of the other namespace types. Without CONFIG_UTS_NS, CONFIG_PID_NS, CONFIG_TIME_NS or CONFIG_USER_NS the initial namespace is never added to the tree. listns() walks the unified tree and calls is_current_namespace() for every namespace it finds via may_list_ns(). But is_current_namespace() only knows about CLONE_NEWIPC and CLONE_NEWNET if CONFIG_IPC_NS and CONFIG_NET_NS are set. Otherwise we end up in the default case and its VFS_WARN_ON_ONCE(). Any unprivileged caller can trigger that with a plain listns() call: WARNING: CPU: 0 PID: 526 at fs/nsfs.c:508 is_current_namespace+0x12f/0x440 Call Trace: legitimize_ns+0x25f/0x4c0 do_listns+0x185/0x5c0 __do_sys_listns+0x13b/0x300 Instead of teaching is_current_namespace() about namespaces that can't be opened, only add the initial namespaces to the tree if their namespace type is enabled. Move the registration of init_ipc_ns into ipc/namespace.c which is only built with CONFIG_IPC_NS. That also fixes CONFIG_SYSVIPC=n, CONFIG_POSIX_MQUEUE=y, CONFIG_IPC_NS=y where ipc/shm.c isn't built and init_ipc_ns was never added at all. For the network namespace only call ns_tree_add_raw() if CONFIG_NET_NS is set. Without CONFIG_NET_NS cleanup_net() isn't built and init_net is never removed so there's nothing to balance. Fixes: 74b24a582e1f ("ipc: support ns lookup") Fixes: 195f7422298d ("net: support ns lookup") Reported-by: kernel test robot <yi1.lai@intel.com> Closes: https://lore.kernel.org/oe-lkp/202610260917.6248e316-lkp@intel.com Cc: stable@vger.kernel.org # v6.18+ Link: https://patch.msgid.link/20261030-work-nsfs-init_ns_tree-v1-1-7ec0adb47c54@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
6 daysMerge tag 'net-7.4-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Current release - new code bugs: - mctp: usblib: fix assertion breaking esoteric builds Previous releases - regressions: - Revert advertising the TCP MSS from the configured MTU - netlink: check sk_rcvbuf before charging the dump skb - eth: - ti: am65-cpts: fix support for PTP_EXTTS_REQUEST2 ioctl - mlx4: always create the eth and ib auxiliary devices - tg3: invert restart quirk logic to restrict SNP power-down bypass - bnxt: recycle agg buffers when Rx head buffer allocation fails Previous releases - always broken: - net: fix frag_list leak in skb_segment_list() error path - sctp: reject forged cookie peer_addr with unknown address family - vxlan: keep reserved_bits across changelink - net: limit priority VLAN untag depth - inet: frags: prevent acceptance of partially authenticated reassembly - gro: do not GRO GSO packets with inconsistent payload - tcp: avoid double destroy in tcp_abort() of an unaccepted child" * tag 'net-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (137 commits) tun: drop batched packets while the device is down selftests: net: netlink-dumps: start a dump with a notification queued netlink: check sk_rcvbuf before charging the dump skb net/sched: act_ife: do not consume the inner header on egress openvswitch: use eth_type_trans_careful() in internal_dev_recv() net: use eth_type_trans_careful() in __dev_forward_skb2() loopback: use eth_type_trans_careful() net: add eth_type_trans_careful() tcp: initialize mapped children before route lookup tcp: fix reordering addition overflow in MTU probing tcp: avoid double destroy in tcp_abort() of an unaccepted child net: bgmac: fix TX DMA unmapping and slot cleanup gro: do not GRO GSO packets with inconsistent payload net/packet: check TX_RING fragments before memory accounting eth: bnxt: hand XDP frags over to the copybreak skb eth: bnxt: free XDP frags when xdp_do_redirect() fails eth: bnxt: don't leak buffers when XDP agg buffer allocation fails eth: bnxt: resize Rx head buffers when rx-copybreak changes eth: bnxt: recycle agg buffers when Rx head buffer allocation fails netdev-genl: ignore NETDEV_UNREGISTER rebroadcasts ...
6 daysMerge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpfLinus Torvalds
Pull bpf fixes from Alexei Starovoitov: - Remove BPF_F_ARENA_SCALAR flag and .arena.data section in libbpf that were added for rust-bpf in this merge window. We found a cleaner approach that does it on compiler side instead of kernel/libbpf. No released kernel has them (Alexei Starovoitov) - Fix bpf_send_signal_task() returning -EPERM when it is called from a kernel thread (Aditya Sharma) - Various fixes (Alexei Starovoitov): - Use emit_rsb_call() to call bpf_unwind_target() in x86 JIT to fix objtool warning during the build - Fix scalar evolution: clear delta of a widened register, don't widen a pointer to a buffer, don't clamp a register whose type changed in the loop, and reset the range of a clamped packet pointer - Finish the insn in the state that maybe_fork_scalars() splits off, so that pruning doesn't drop it at the head of a counted loop - Preserve the registers that carry stack arguments across arch_bpf_timed_may_goto() on x86-64, arm64 and riscv64 - Don't re-sort subprog_info[] for every new subprogram - Fix flaky map_kptr and rcu_reentry selftests - Use memmove() in bpf_skb_load_bytes(), bpf_skb_load_bytes_relative() and bpf_xdp_load_bytes(), since the destination can be a slice of the same packet (Ayushman Rout) - Fixes and follow-ups for scalar evolution: reject pointer operands in 32-bit recurrences and latches, don't intersect with the current register range on clamp to avoid a false 'verifier bug', avoid false infinite loop reports, and recognize a 32-bit copy of the induction variable (Eduard Zingerman) - Fix out-of-bounds write to btf->types[] for split BTF and propagate btf_add_type() errors in btf_check_all_metas() (Feng Yang) - Fix use-after-free in bpf_timer callback that fires after its inner map was freed (Mani Tofigh) - Fix x86 JIT stopping before jumps converge: size backward jumps by the insns they jump over (Mykyta Yatsenko) - Fix use-after-free of struct_ops trampoline: dissociate struct_ops progs before the grace period of the map (Qiliang Yuan) - Validate stack argument reads against the caller state to fix out-of-bounds read in the verifier, and reject callbacks with stack arguments (Weiming Shi) - Tie borrowed iterator results and pointers loaded from trusted fields to the lifetime of their source, so that iterator next, destroy and reference release invalidate them (Xu Yunxiang) * tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf: (48 commits) bpf: Don't re-sort subprog_info[] for every new subprogram bpf: Fix out-of-bounds btf->types write for split BTF selftests/bpf: Test stack arguments across may_goto bpf: Keep stack arguments in arch_bpf_timed_may_goto() selftests/bpf: Test maybe_fork_scalars() at the head of a counted loop bpf: Finish the insn in the state that maybe_fork_scalars() splits off selftests/bpf: Test the clamp of pointers in scalar evolution bpf: Reset the range of a packet pointer that scalar evolution clamps bpf: Don't clamp a register whose type changed in the loop selftests/bpf: Test a loop that moves a pointer to a buffer bpf: Don't widen a pointer to a buffer in scalar evolution selftests/bpf: Avoid a page fault in rcu_reentry while the handler is armed selftests/bpf: Wait for the last maps of map_kptr to be freed selftests/bpf: Test that a widened register is not linked bpf: Clear delta of a register that scalar evolution widens bpf, x86: Remove r0_on_stack from fetching atomics in arena bpf: Remove BPF_F_ARENA_SCALAR selftests/bpf: Remove tests for arena access through numbers libbpf: Keep format strings of bpf_printk() in .rodata libbpf: Remove .arena.data ...
6 daysnetlink: check sk_rcvbuf before charging the dump skbJhonata Poma-Hansen
Since commit ae8f160e7eb2 ("netlink: Fix wraparounds of sk->sk_rmem_alloc."), netlink_dump() charges the dump skb first and queues it only if sk_rmem_alloc is still below sk_rcvbuf. Commit a215b5723922 ("netlink: make sure we allow at least one dump skb") added an exception for an empty socket. A dump that starts while something else is still charged to a socket with a small receive buffer fails with ENOBUFS and stays running. Every recvmsg() retries it, fails again and sets sk_err, so a reader that peeks before reading, as libnl does, gets ENOBUFS on the read after each peek, never consumes the message at the head of the queue and spins forever. I hit this with "iw dev wlan0 scan" hanging at 100% CPU on an arm64 board with a 6.6 based kernel (iw 5.19 sets SO_RCVBUF to 8KiB). A kprobe trace showed the scan dump starting while the NEW_SCAN_RESULTS notification iw had just read was still charged to its socket, because iw had preempted the sender before netlink_broadcast() returned. Check the limit before charging, as before ae8f160e7eb2, which also covers the empty socket. netlink_recvmsg() continues a dump only at or below half of sk_rcvbuf, so the skb is then always queued, and a dump goes over the limit by at most one skb. Refuse a skb that would take sk_rmem_alloc past INT_MAX, so the wraparound stays fixed. Reproduced on net in a KVM guest with a userspace reproducer and the selftest in the next patch; both pass with this fix. Fixes: ae8f160e7eb2 ("netlink: Fix wraparounds of sk->sk_rmem_alloc.") Signed-off-by: Jhonata Poma-Hansen <jhonata.poma@gmail.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Link: https://patch.msgid.link/20261027-netlink-dump-livelock-v2-1-c4bb05352a33@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daysnet/sched: act_ife: do not consume the inner header on egressJamal Hadi Salim
The issue: tcf_ife_decode() unconditionally calls eth_type_trans(), which pulls ETH_HLEN. On egress this consumes the inner Ethernet header, and the device receives an skb whose data points to the L3 header: - loopback_xmit() parses L3 data as Ethernet: the "ethertype" comes from the inner IPv4 source address, and the decapsulated packet is dropped or misparsed. - a real NIC transmits the frame without its Ethernet header. (The __skb_pull() BUG this used to trigger in loopback_xmit() when the remaining linear area was short is handled by "loopback: use eth_type_trans_careful()".) The Fix: Parse the inner Ethernet header with eth_type_trans() in both directions, then restore the egress data position and MAC length. On ingress the existing behavior is unchanged. On egress, push the inner Ethernet header back after parsing so the xmit path sees the original frame and later actions see a consistent network header. Conditions to recreate the bug: - egress tc filter on lo: action ife decode pipe; - AF_PACKET SOCK_RAW frame: outer Ethernet with ETH_P_IFE, IFE metadata, inner Ethernet + a valid IPv4 ICMP echo request to a local address; - before this patch, no echo is received; after it, the echo is delivered and answered. Fixes: ef6980b6becb ("introduce IFE action") Cc: stable@vger.kernel.org Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> [edumazet: reworded changelog, the crash is now handled in loopback] Signed-off-by: Eric Dumazet <edumazet@kernel.org> Acked-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261028122703.2093730-6-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daysopenvswitch: use eth_type_trans_careful() in internal_dev_recv()Eric Dumazet
OVS actions like pop_eth followed by pop_mpls(ETH_P_TEB) or pop_nsh can expose an inner Ethernet header which is not in the linear part of the skb. Output to an internal port then crashes in eth_type_trans(): flow: in_port(0),eth(),eth_type(0x8847),mpls(lse=0x00010140) actions: pop_eth,pop_mpls(0x6558),0 # AF_PACKET SOCK_RAW on dp0: eth / mpls / eth / 4096 bytes of payload kernel BUG at include/linux/skbuff.h:2839! RIP: 0010:eth_type_trans (include/linux/etherdevice.h:635 net/ethernet/eth.c:163) Call Trace: internal_dev_recv (net/openvswitch/vport-internal_dev.c:202) openvswitch do_execute_actions (net/openvswitch/actions.c:1296) openvswitch ovs_execute_actions (net/openvswitch/actions.c:1606) openvswitch ovs_dp_process_packet (net/openvswitch/datapath.c:310) openvswitch ovs_vport_receive (net/openvswitch/vport.c:448) openvswitch internal_dev_xmit (net/openvswitch/vport-internal_dev.c:42) openvswitch dev_hard_start_xmit (include/linux/netdevice.h:5455 include/linux/netdevice.h:5464 net/core/dev.c:4057 net/core/dev.c:4073) __dev_queue_xmit (net/core/dev.c:5066) packet_sendmsg (net/packet/af_packet.c:3157 net/packet/af_packet.c:3189) Use eth_type_trans_careful(), and drop the packet if the Ethernet header can not be pulled. This covers all OVS actions at the consumer, instead of fixing each producer. Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support") Fixes: f66b53fdbb22 ("openvswitch: New MPLS actions for layer 2 tunnelling") Signed-off-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Aaron Conole <aconole@redhat.com> Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com> Tested-by: Jamal Hadi Salim <jhs@mojatatu.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20261028122703.2093730-5-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daysnet: use eth_type_trans_careful() in __dev_forward_skb2()Eric Dumazet
A tc egress BPF program can push a tiny link-layer header with bpf_skb_change_head() on an skb whose head is almost empty, then redirect it to an Ethernet device ingress. __bpf_redirect_common() only checks mac_header < network_header, and __dev_forward_skb2() crashes in eth_type_trans(): tc filter add dev lo egress pref 1 matchall action vlan pop_eth continue tc filter add dev lo egress pref 2 bpf da obj prog.o # prog: bpf_skb_change_head(skb, 1, 0); # return bpf_redirect(veth1_ifindex, BPF_F_INGRESS); # AF_PACKET SOCK_RAW on lo: eth / eth / 8192 bytes of payload kernel BUG at include/linux/skbuff.h:2839! RIP: 0010:eth_type_trans (include/linux/etherdevice.h:635 net/ethernet/eth.c:163) Call Trace: __dev_forward_skb2 (net/core/dev.c:2507) dev_forward_skb_nomtu (net/core/dev.c:2546) __dev_queue_xmit (net/core/dev.c:4738 net/core/dev.c:4998) packet_sendmsg (net/packet/af_packet.c:3157 net/packet/af_packet.c:3189) Use eth_type_trans_careful(), and drop the packet if the Ethernet header can not be pulled. This also covers other dev_forward_skb() users (veth, macvlan, ipvlan, netdevsim, l2tp_eth). Update the empty_skb BPF selftest: at lwt_xmit, BPF_PROG_TEST_RUN strips the Ethernet header, so the "veth ETH_HLEN+1" packet is a 1-byte skb. Redirecting it to veth ingress used to read the Ethernet header past skb->tail and deliver a 1-byte frame; it is now dropped with NET_RX_DROP, as veth_xmit() already does at egress. Fixes: 3a0af8fd61f9 ("bpf: BPF for lightweight tunnel infrastructure") Signed-off-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com> Tested-by: Jamal Hadi Salim <jhs@mojatatu.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20261028122703.2093730-4-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daystcp: initialize mapped children before route lookupKyle Zeng
IPv4 passive opens on a dual-stack listener go through tcp_v4_syn_recv_sock() with tcp_v6_mapped_child_init() as the optional initializer. The callback currently runs after the output route lookup. If that lookup fails, tcp_done() destroys a clone whose pinet6 and ipv6_fl_list still refer to the listener's state. With the flowlabel list head in inet_sock, fl6_free_socklist() walks the clone's list and RCU-frees its nodes without unlinking them from the live listener. Subsequent flowlabel operations can use or free the nodes again. Commit 858d2a4f67ff ("tcp: fix potential race in tcp_v6_syn_recv_sock()") moved the initializer before ehash insertion, but did not cover this error path. Invoke the existing initializer after the IPv4 fields it consumes have been set, but before route lookup can fail. It needs neither the destination nor sk_setup_caps(), and all later disposal paths remain covered. Fixes: 1c17f4373d4d ("ipv6: Move ipv6_fl_list from ipv6_pinfo to inet_sock.") Signed-off-by: Kyle Zeng <kylebot@openai.com> Signed-off-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20261028154101.2153360-1-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daystcp: fix reordering addition overflow in MTU probingKyle Zeng
Commit efb8763d7bbb ("net: ipv4: bound TCP reordering sysctl writes and MTU probe sizes") widened size_needed and the MSS multiplication, but tp->reordering + 1 is still evaluated as u32. RTAX_REORDERING accepts an unrestricted u32, and tcp_init_metrics() can install U32_MAX. In that case the extra-data requirement becomes zero. A write queue with probe_size - 1 data bytes and a FIN satisfies the sequence-space check. The coalescing walk can pass the queue head to tcp_skb_can_collapse(), and tcp_clone_payload() can produce an skb whose advertised payload exceeds the data in its fragments. Local delivery followed by TCP_ZEROCOPY_RECEIVE can then walk beyond the fragment array. KASAN reports a slab-out-of-bounds read in can_map_frag(). Cast reordering before incrementing it so the arithmetic handles the entire u32 metric range. For U32_MAX, the required size exceeds the 32-bit queue and window limits, so the existing checks skip the probe. The calculation is unchanged for all other reordering values. Fixes: efb8763d7bbb ("net: ipv4: bound TCP reordering sysctl writes and MTU probe sizes") Cc: stable@vger.kernel.org Cc: Wyatt Feng <bronzed_45_vested@icloud.com> Cc: Ren Wei <n05ec@lzu.edu.cn> Signed-off-by: Kyle Zeng <kylebot@openai.com> Signed-off-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Neal Cardwell <ncardwell@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://patch.msgid.link/20261028160226.2170244-1-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daystcp: avoid double destroy in tcp_abort() of an unaccepted childKyle Zeng
tcp_abort() checks for TCP_CLOSE while only owning the socket lock, then grabs the BH lock before calling tcp_done_with_error(). For a child still sitting in a listener accept queue (which can be reached via SOCK_DESTROY or bpf_sock_destroy()), inet_csk_listen_stop() can run in this window: it only holds the child BH lock, and calls inet_child_forget(), which disconnects, orphans and destroys the child. tcp_abort() then calls tcp_done_with_error() -> tcp_done(), which sees SOCK_DEAD and calls inet_csk_destroy_sock() a second time, leading to a double sock_put() and a use-after-free. Recheck TCP_CLOSE after acquiring the BH lock, unless we just closed a listener ourselves, in which case tcp_done_with_error() must still run to report the error. Note that the WARN_ON(sock_owned_by_user(child)) in inet_csk_listen_stop() can still trigger in this window. Fixes: bac76cf89816 ("tcp: fix forever orphan socket caused by tcp_abort") Signed-off-by: Kyle Zeng <kylebot@openai.com> [edumazet: recheck TCP_CLOSE under the BH lock instead of moving the test, smaller diff] Signed-off-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20261028160847.2170959-1-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daysgro: do not GRO GSO packets with inconsistent payloadKyle Zeng
tcp_gro_receive() excludes empty non-GSO packets with the unsigned len - 1 check, but its GSO branch only checks that gso_size matches the held packet's MSS. A trusted TCP GSO skb can reach GRO again with no payload after TC pedit increases its TCP data offset. If the skb is fully linear, skb_gro_receive() then enters its fragment transfer path with nr_frags == 0. The do-while loop copies skb_frag_t entries backwards beyond both fragment arrays. An unprivileged process using its own user and network namespaces can trigger a KASAN slab-out-of-bounds write and panic through veth, pedit and GRE. More generally, the payload of such a packet can be shrunk to any value, making it inconsistent with its gso_segs, and a GSO packet with gso_segs == 0 contributes no segment to the GRO packet. Do not aggregate GSO packets with gso_segs == 0, and require the payload of GSO packets to be consistent with gso_segs and gso_size, the last segment being allowed to be short. This rejects the empty skb before either TCP merge helper, and covers both IPv4 and IPv6. Fixes: 5eddb24901ee ("gro: add support of (hw)gro packets to gro stack") Signed-off-by: Kyle Zeng <kylebot@openai.com> [edumazet: check payload against gso_segs, refuse gso_segs == 0] Signed-off-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20261028171350.2205175-1-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daysnet/packet: check TX_RING fragments before memory accountingKyle Zeng
tpacket_fill_skb() adds the full non-linear payload length to skb->truesize and sk_wmem_alloc before checking MAX_SKB_FRAGS. With PACKET_VNET_HDR, userspace can submit a ring-sized frame even when it greatly exceeds the device MTU. A near-INT_MAX frame can saturate sk_wmem_alloc before the fragment loop rejects it. A subsequent refcount_add(0x40000001) can temporarily turn REFCOUNT_SATURATED into 1. A concurrent TX completion can then drop that apparent last reference and free the still-live packet socket before refcount_warn_saturate() restores the counter. Check that the remaining payload fits in MAX_SKB_FRAGS pages before accounting it. Include the initial page offset in the calculation, and move the existing -EFAULT handling out of the fragment loop. This preserves the accepted packet sizes and error code while preventing an invalid frame from injecting an oversized byte charge. Fixes: 69e3c75f4d54 ("net: TX_RING and packet mmap") Cc: stable@vger.kernel.org Cc: Willem de Bruijn <willemdebruijn.kernel@gmail.com> Signed-off-by: Kyle Zeng <kylebot@openai.com> [edumazet: use net_warn_ratelimited() instead of pr_err(), add a Fixes: tag] Signed-off-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20261028181450.2221013-1-edumazet@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daysnetdev-genl: ignore NETDEV_UNREGISTER rebroadcastsNaman Gulati
netdev_wait_allrefs_any() re-sends NETDEV_UNREGISTER every second while it waits for the last references on a device to be dropped. By then netdev_run_todo() has already marked the device NETREG_UNREGISTERED and RTNL has been dropped at least once since the initial notification sent by unregister_netdevice_many_notify(). netdev_genl_netdevice_event() does not tell these rebroadcasts apart from the initial notification and sends a NETDEV_CMD_DEV_DEL_NTF multicast for each of them. At best this spams NETDEV_NLGRP_MGMT listeners with duplicate notifications; at worst the pernet state of the netns the device belongs to is already gone and the handler dereferences a NULL pointer. default_device_exit_batch() only unregisters the devices still listed in the exiting netns; it does not wait for in-flight unregistrations of devices that were already unlisted (the barrier doing that was removed by commit 8a4fc54b07d7 ("net: get rid of rtnl_lock_unregistering()")). So when a device is unregistered by something other than the cleanup_net() of its own netns while references on it are still held, e.g. a veth whose peer in another netns gets deleted, and that netns exits while the device is stuck in netdev_wait_allrefs_any(), the remaining pernet exit handlers run and genl_pernet_exit() sets net->genl_sock to NULL. The next rebroadcast then crashes in genl_has_listeners(): BUG: KASAN: null-ptr-deref in netlink_has_listeners+0x3d/0x3f0 net/netlink/af_netlink.c:1388 Read of size 8 at addr 0000000000000578 by task syz.0.0/5325 Call Trace: <TASK> netlink_has_listeners+0x3d/0x3f0 net/netlink/af_netlink.c:1388 genl_has_listeners include/net/genetlink.h:644 [inline] netdev_genl_dev_notify+0x161/0x450 net/core/netdev-genl.c:93 netdev_genl_netdevice_event+0x98/0x3c0 net/core/netdev-genl.c:1491 notifier_call_chain+0x1a5/0x3d0 kernel/notifier.c:85 netdev_wait_allrefs_any net/core/dev.c:11690 [inline] netdev_run_todo+0x731/0x1060 net/core/dev.c:11808 rtnl_unlock net/core/rtnetlink.c:157 [inline] rtnl_dellink+0x68f/0x810 net/core/rtnetlink.c:3707 syzbot hit this by moving one end of a veth pair into a short-lived netns while netdevsim's deferred FIB event processing still held a reference on it, and then deleting the other end (repro [1]). While the source of this bug is netdevsim deferring FIB processing for and holding onto the device reference for O(seconds) which is being fixed separately [2], any driver may introduce such a delay and trigger the null-ptr-deref. Skip the rebroadcasts, which are the only NETDEV_UNREGISTER events delivered with reg_state == NETREG_UNREGISTERED. The notifications sent by unregister_netdevice_many_notify() and, for a device leaving a netns, by __dev_change_net_namespace() are issued under RTNL in the same critical section that unlists the device, before its netns can be torn down, and keep being handled. This mirrors what ip6_route_dev_notify() already does to cope with the rebroadcasts. This change should not break the UAPI spec as it defines dev-del-ntf as a "Notification about device disappearing." which is a single event. The rebroadcast in netdev_wait_allrefs_any() exists to re-kick in-kernel subsystems holding references; netdev-genl happens to be on the notifier chain and forwards it. [1] https://gist.github.com/NamanGulati/2d1b49b8757f9a88b0bd6e55018c02ae [2] https://lore.kernel.org/r/20261023191517.607834-1-kuniyu@google.com Fixes: d3d854fd6a1d ("netdev-genl: create a simple family for netdev stuff") Reported-by: syzbot+1269fe6cc2016008124e@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6adf9f64.6200f071.51519.0ed1.GAE@google.com/ Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Signed-off-by: Naman Gulati <namangulati@google.com> Link: https://patch.msgid.link/20261026221306.3151025-1-namangulati@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
6 daystcp: check congestion control restriction firstZhiling Zou
tcp_set_default_congestion_control() takes a reference to an algorithm before checking whether a non-init network namespace may select it. A rejected request returns -EPERM without dropping the reference. This affects module-backed algorithms too; BPF is not required. For example, after root loads tcp_bbr, a user with CAP_NET_ADMIN in a non-init network namespace can repeatedly request it as the default although it is not in tcp_allowed_congestion_control. Each rejected write leaks a module reference. Since module->refcnt is an atomic_t, 2^31 such writes can make it negative; later module_put() calls warn, and rmmod can hit the BUG_ON() in try_release_module_ref(). Check the namespace restriction before acquiring the reference, as tcp_set_congestion_control() already does. Fixes: 8d432592f30f ("net: Only allow init netns to set default tcp cong to a restricted algo") Cc: stable@vger.kernel.org Reported-by: Vega <vega@nebusec.ai> Suggested-by: Eric Dumazet <edumazet@kernel.org> Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://patch.msgid.link/71c142b2d45af6a2fe7fc6cd4a5ca52c53afbe23.1793075984.git.zhilinz@nebusec.ai Signed-off-by: Paolo Abeni <pabeni@redhat.com>
6 daysnet/sched: sch_teql: fix use-after-free on lower qdisc dropowen kwan
The issue: teql_master_xmit() tests the slave's ndo_start_xmit() return value against NETDEV_TX_OK alone. A slave that consumes the skb but returns an error code (rc < NET_XMIT_MASK, e.g. NET_XMIT_DROP) is treated as if the skb were still owned, so the loop restores skb->dev and calls __skb_pull() on it. A VLAN slave returns the result of dev_queue_xmit() from its ndo_start_xmit() (propagated since cbbef5e18307), and when the lower qdisc drops the packet that value is NET_XMIT_DROP after the skb has been freed, giving a use-after-free in teql_master_xmit(). The Fix: test for consumption with dev_xmit_complete(), which accepts NETDEV_TX_OK and every rc < NET_XMIT_MASK, matching other callers that need to distinguish consumed results from busy. Only NETDEV_TX_OK keeps the packet counted in tx_packets/tx_bytes and advances the slave; a consumed result that is neither a success nor NET_XMIT_CN ends the attempt and is charged to tx_dropped, so lower-qdisc drops are no longer reported as good transmits. NET_XMIT_CN is counted like success because it can accompany acceptance of the current packet: pfifo_head_drop drops the old head, enqueues the current skb and returns NET_XMIT_CN. Conditions to recreate the bug: With CONFIG_NET_SCH_TEQL, CONFIG_VLAN_8021Q and CONFIG_DUMMY enabled, add lkrdummy0 (dummy) and lkrvlan0 (VLAN id 37 on lkrdummy0); set a pfifo limit 0 root on lkrdummy0 and a teql0 root on lkrvlan0; bring teql0 up with an address and send one UDP packet to it. The VLAN xmit returns NET_XMIT_DROP from the lower qdisc while holding a freed skb. Fixes: 572a9d7b6fc7 ("net: allow to propagate errors through ->ndo_hard_start_xmit()") Link: https://lore.kernel.org/netdev/179248763469.3135.1739559328868319628@kernel.org/ Link: https://lore.kernel.org/netdev/20261023162821.GN708417@horms.kernel.org/ Cc: stable@vger.kernel.org Signed-off-by: owen kwan <owen@verialabs.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/QDISC-Y0BY.v2.r0.20261024060625-2@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
6 daysnet/sched: sch_teql: fix slaves_lock IRQ deadlockJamal Hadi Salim
This is a followup of commit e5b811fe7931 ("net/sched: sch_teql: Introduce slaves_lock to avoid race condition and UAF") as reported by Sashiko. The issue: master->slaves_lock serializes the master's ring of slave qdiscs. The control paths -- teql_dequeue(), teql_destroy() and teql_qdisc_init() -- take it with spin_lock_bh(), while teql_master_xmit() (the master's ndo_start_xmit) takes it with plain spin_lock(). netpoll_send_skb() wraps the transmit in local_irq_save(), and __netpoll_send_skb() asserts lockdep_assert_irqs_disabled(), so teql_master_xmit() reached from netconsole always acquires slaves_lock with hard IRQs disabled. On PREEMPT_RT spinlock_t is an rtmutex, and Documentation/locking/locktypes.rst names local_irq_disable(); spin_lock(&lock); as a sequence that breaks there because the rtmutex requires a fully preemptible context. This is reachable without any panic: the nbcon printer thread calls netconsole's write_thread() callback on every message. The usual remedy -- folding the IRQ disable into the lock with spin_lock_irqsave() -- is unavailable because the local_irq_save() is netpoll's, not ours. On non-RT the same asymmetry leaves slaves_lock acquirable with hard IRQs disabled on one path and held with hard IRQs enabled on another. That is only exploitable during the panic console flush (netconsole is CON_NBCON_ATOMIC_UNSAFE, so console_is_usable() admits its write_atomic() only from nbcon_atomic_flush_unsafe(), which panic() alone calls), and even then an IRQ-saving lock does not help if the holder oopsed inside the section or was stopped by panic_other_cpus_shutdown(). So the non-RT half is hardening; the PREEMPT_RT half is the bug. The Fix: take slaves_lock as a raw spinlock with IRQs saved at every site. Since skb_queue_purge() takes the queue's spinlock_t and may not nest inside a raw lock on PREEMPT_RT, move its call in teql_destroy() outside the raw section; dat->q is the dying qdisc's own queue and was never serialized by slaves_lock, so the move is behaviour-neutral. The new critical sections contain only RCU pointer assignments and netdev_get_tx_queue(); skb_queue_purge(), netif_wake_queue() and dev_reset_queue() are all outside them. teql_destroy()'s ring walk is O(slaves), two pointer loads and a compare per iteration, so even a large ring is microseconds with IRQs off. Keeping the purge conditional rather than dropping it outright is the conservative call for a backport. Some context: commit 6301f6a34ed8 ("net/sched: sch_teql: move rcu_read_lock()/spin_lock() from _bh variants") hardened the parent fix; together they addressed the master->slaves resurrection use-after-free and the xmit-side BH warning but left the reverse direction -- a hard IRQ re-entering xmit while a control path holds the lock -- unaddressed. Conditions to recreate the bug: - CONFIG_PREEMPT_RT, CONFIG_NET_SCH_TEQL, CONFIG_DUMMY and CONFIG_NETCONSOLE. - Run `ip link add dev teqlslave0 type dummy`, bring teqlslave0 up, attach it with `tc qdisc add dev teqlslave0 root teql0`, and bring teql0 up. - Configure a netconsole target on teql0 with explicit local and remote IP addresses and a remote MAC address, then emit a console message. The nbcon printer thread reaches teql_master_xmit() with hard IRQs disabled by netpoll; taking slaves_lock as a spinlock_t is invalid on PREEMPT_RT. No panic or concurrent qdisc change is required. - Reachable by an admin with CAP_NET_ADMIN; teql devices exist only in the initial netns (no per-netns ops), so a user namespace does not suffice. Fixes: e5b811fe7931 ("net/sched: sch_teql: Introduce slaves_lock to avoid race condition and UAF") Reported-by: Sashiko (gemini) <sashiko-bot@kernel.org> Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260630150922.238714-1-jhs%40mojatatu.com Link: https://lore.kernel.org/netdev/20260630150922.238714-1-jhs@mojatatu.com/ Cc: stable@vger.kernel.org Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/QDISC-Y0BY.v2.r0.20261024060625-1@mojatatu.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
6 daysnet: mctp: free reassembly head skb when key_add fails on SOMJoas Antonio dos Santos
When a start-of-message fragment creates a new reassembly key on the broadcast/bind path, mctp_frag_queue() stores the skb as key->reasm_head before the key is made observable with mctp_key_add(). If mctp_key_add() fails (a race with another SOM packet for the same source/dest/tag, or the receiving socket going away), the error path only drops the key reference via mctp_key_unref(). The final key destructor frees the key itself but not key->reasm_head, and since the key was never added to any list, neither the expiry worker nor socket teardown can reach it to release the queued fragment. The skb is leaked. Free key->reasm_head on the key_add failure path before releasing the key. Other teardown paths (__mctp_key_done_in(), EOM delivery) already clear reasm_head before the final unref, so this only affects the failure path. Fixes: 4a992bbd3650 ("mctp: Implement message fragmentation & reassembly") Signed-off-by: Joas Antonio dos Santos <joasantonio108@gmail.com> Reported-by: Guikun Yang <yangguikun19@qq.com> Closes: https://lore.kernel.org/all/tencent_43A65D51143E18518EA968DF9323694EFD08@qq.com/ Acked-by: Jeremy Kerr <jk@codeconstruct.com.au> Link: https://patch.msgid.link/179287946888.17431.11219154409333681184@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
7 days9p: reject RERROR/RLERROR with zero errcodeHui Peng
In p9_check_errors() (net/9p/client.c), a malicious or buggy 9p server returning P9_RERROR or P9_RLERROR with ecode == 0 causes p9_check_errors() to return 0 (success) while leaving the unparsed response payload as if the expected reply message type succeeded. Map ecode == 0 on RERROR / RLERROR to -EPROTO. Link: https://lore.kernel.org/all/20260919221734.3708000-1-benquike@gmail.com/ Signed-off-by: Hui Peng <benquike@gmail.com> Message-ID: <20261029055801.3-1-asmadeus@codewreck.org> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
7 days9p/xen: validate the response size from the backendYehyeong Lee
p9_xen_response() takes the length of an incoming response from the ring -- the first field of the 9p header, which the Xen transport reuses as its framing header -- and uses it to advance the consumer index, but never checks that it is at least the header size or no larger than the number of bytes the backend has actually produced. A malicious or buggy backend can post a response whose size is smaller than the header (for example 0). The consumer index then never advances, so the response work re-reads the same ring contents instead of making progress. In testing this raced with the teardown that the malformed reply triggers and dereferenced a freed p9_client: 9pfs 9pfs-0: Wrong req tag=ffff BUG: kernel NULL pointer dereference, address: 0000000000000060 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 0 UID: 0 PID: 11 Comm: kworker/0:1 Not tainted 7.2.0-rc5 #6 PREEMPT(lazy) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014 Workqueue: events p9_xen_response RIP: 0010:idr_find+0x4/0x10 RSP: 0018:ffffbf5d80063de8 EFLAGS: 00010202 RAX: 0000000000000001 RBX: ffffa229c21195a0 RCX: ffffa229c2400000 RDX: ffffa229c11c2200 RSI: 000000000000ffff RDI: 0000000000000050 RBP: 000000000000ffff R08: 3fffffffffffdfff R09: ffffffffffffffff R10: 3fffffffffffdfff R11: ffffffff87a60e80 R12: 0000000000000050 R13: 0000000000000000 R14: 000000000000ffff R15: 0000000000100000 FS: 0000000000000000(0000) GS:ffffa22a7661c000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000060 CR3: 000000003ac34002 CR4: 0000000000770ef0 PKRU: 55555554 Call Trace: <TASK> p9_tag_lookup+0x2b/0x90 p9_xen_response+0x17c/0x2e0 process_one_work+0x16a/0x3a0 worker_thread+0x172/0x2e0 kthread+0xdd/0x110 ret_from_fork+0x18b/0x240 ret_from_fork_asm+0x1a/0x30 </TASK> Modules linked in: CR2: 0000000000000060 ---[ end trace 0000000000000000 ]--- Reject a response whose size is outside [sizeof(header), queued] before using it, matching the validation the backend already applies to incoming requests. Fixes: f66c72bea129 ("xen/9pfs: receive responses") Cc: stable@vger.kernel.org Signed-off-by: Yehyeong Lee <yhlee@isslab.korea.ac.kr> Reviewed-by: Juergen Gross <jgross@suse.com> Message-ID: <20261005125640.274054-1-yhlee@isslab.korea.ac.kr> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
7 daysnet: bridge: netlink: do not clear the vlan info dump errorLinkui Xiao
br_fill_ifinfo() assigns the result of br_fill_vlan_tunnel_info() over the result of br_fill_ifvlaninfo() or br_fill_ifvlaninfo_compressed() instead of only running the second helper when the first one succeeded. When the vlan information no longer fits in the skb but the port has no vlan mapped to a tunnel dst, br_fill_vlan_tunnel_info() walks the vlan list and returns 0 without touching the skb. The -EMSGSIZE is lost, br_fill_ifinfo() completes a message whose IFLA_AF_SPEC is truncated, and the dump carries on to the next interface instead of stopping, so userspace silently sees an incomplete vlan list. Only fill the tunnel information when the vlan information was filled successfully. This was flagged as a pre-existing issue in the Sashiko review of the net-next series, which noted that the VLAN fill result is overwritten before it is tested (see the Link tag below). Not triggered or tested. Fixes: efa5356b0d97 ("bridge: per vlan dst_metadata netlink support") Link: https://lore.kernel.org/bridge/ed1de95e-e112-4076-93f0-6f7668e657ad@blackwall.org/T/#u#5 Signed-off-by: Linkui Xiao <xiaolinkui@kylinos.cn> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/20261027085200.1501599-1-xiaolinkui@126.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
7 daysipv6: Protect multiple routes insertion by table lock.Kuniyuki Iwashima
syzbot reported the warning below. [0] While call_fib6_multipath_entry_notifiers() is called locklessly, fib6_siblings could be changed concurrently, leading to the warning (and later null-ptr-deref). Let's protect multiple routes insertion with tb6_lock. Along with that, __ip6_ins_rt() and ip6_route_del() are changed to fib6_add() and fib6_del(). Note that fib6_del() finally calls rt6_multipath_rebalance(), which requires rcu_read_lock(). [0]: i != fen6_info->nsiblings WARNING: drivers/net/netdevsim/fib.c:831 at nsim_fib6_event_init drivers/net/netdevsim/fib.c:831 [inline], CPU#0: syz.0.157/6279 WARNING: drivers/net/netdevsim/fib.c:831 at nsim_fib6_prepare_event drivers/net/netdevsim/fib.c:947 [inline], CPU#0: syz.0.157/6279 WARNING: drivers/net/netdevsim/fib.c:831 at nsim_fib_event_schedule_work drivers/net/netdevsim/fib.c:1003 [inline], CPU#0: syz.0.157/6279 WARNING: drivers/net/netdevsim/fib.c:831 at nsim_fib_event_nb+0x1029/0x11d0 drivers/net/netdevsim/fib.c:1043, CPU#0: syz.0.157/6279 Modules linked in: CPU: 0 UID: 0 PID: 6279 Comm: syz.0.157 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026 RIP: 0010:nsim_fib6_event_init drivers/net/netdevsim/fib.c:831 [inline] RIP: 0010:nsim_fib6_prepare_event drivers/net/netdevsim/fib.c:947 [inline] RIP: 0010:nsim_fib_event_schedule_work drivers/net/netdevsim/fib.c:1003 [inline] RIP: 0010:nsim_fib_event_nb+0x1029/0x11d0 drivers/net/netdevsim/fib.c:1043 Code: eb 0d 4d 89 fd e8 b7 c5 6c fa be 01 00 00 00 48 89 df e8 5a 38 85 fd 4d 89 ef 4c 8b 6c 24 20 e9 4a f3 ff ff e8 98 c5 6c fa 90 <0f> 0b 90 e9 db fa ff ff 89 e9 80 e1 07 80 c1 03 38 c1 0f 8c df f0 RSP: 0018:ffffc900047bef10 EFLAGS: 00010293 RAX: ffffffff875b59a8 RBX: 0000000000000002 RCX: ffff888079770000 RDX: 0000000000000000 RSI: 0000000000000002 RDI: 0000000000000001 RBP: ffffc900047bf0a0 R08: ffff88805c0bb02f R09: 1ffff1100b817605 R10: dffffc0000000000 R11: ffffed100b817606 R12: dffffc0000000000 R13: 0000000000000000 R14: 0000000000000001 R15: ffff88802c792000 FS: 00007f334ba076c0(0000) GS:ffff888123ad0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f334ba06ff8 CR3: 000000007a5b2000 CR4: 00000000003526f0 Call Trace: <TASK> notifier_call_chain+0x1a5/0x3d0 kernel/notifier.c:85 atomic_notifier_call_chain+0xda/0x180 kernel/notifier.c:223 call_fib_notifiers+0x31/0x60 net/core/fib_notifier.c:36 call_fib6_multipath_entry_notifiers+0xf5/0x160 net/ipv6/ip6_fib.c:428 ip6_route_multipath_add net/ipv6/route.c:5542 [inline] inet6_rtm_newroute+0x14f5/0x1a30 net/ipv6/route.c:5664 rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7163 netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2572 netlink_unicast_kernel net/netlink/af_netlink.c:1335 [inline] netlink_unicast+0x7bd/0x940 net/netlink/af_netlink.c:1361 netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1916 sock_sendmsg_nosec+0x14e/0x190 net/socket.c:800 __sock_sendmsg net/socket.c:818 [inline] ____sys_sendmsg+0x54e/0x850 net/socket.c:2715 ___sys_sendmsg+0x2a5/0x360 net/socket.c:2769 __sys_sendmmsg+0x273/0x4d0 net/socket.c:2858 __do_sys_sendmmsg net/socket.c:2885 [inline] __se_sys_sendmmsg net/socket.c:2882 [inline] __x64_sys_sendmmsg+0xa0/0xc0 net/socket.c:2882 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline] do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f334ab9e1d9 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f334ba07028 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: ffffffffffffffda RBX: 00007f334ae26090 RCX: 00007f334ab9e1d9 RDX: 04000000000001f2 RSI: 0000200000000000 RDI: 0000000000000004 RBP: 00007f334ac35888 R08: 0000000000000000 R09: 0000000000000000 R10: 00000000000000fc R11: 0000000000000246 R12: 0000000000000000 R13: 00007f334ae26128 R14: 00007f334ae26090 R15: 00007ffd96688aa8 </TASK> Fixes: 169fd62799e8 ("ipv6: Get rid of RTNL for SIOCADDRT and RTM_NEWROUTE.") Reported-by: syzbot+751b587577d0ebca10f2@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/6adbaed6.67317f00.38c4bc.001b.GAE@google.com/T/ Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: David Ahern <dsahern@kernel.org> Link: https://patch.msgid.link/20261027065247.2871134-1-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
7 daystls: Honor O_NONBLOCK in tls_sw_splice_read()Chuck Lever
tls_sw_splice_read() takes its blocking behavior from SPLICE_F_NONBLOCK alone. When splicing from a socket to a pipe, do_splice() sets that flag from the pipe's O_NONBLOCK, not the socket's. On a nonblocking socket, a splice(2) call without SPLICE_F_NONBLOCK therefore sleeps in tls_rx_rec_wait() until a record arrives. tcp_splice_read() instead reads sock->file->f_flags and returns -EAGAIN. Polling first does not avoid the sleep once tls_sw_splice_read() consumes zero-length records, as it does after a later patch in this series. tls_sw_sock_is_readable() reports the socket readable while any record sits on rx_list, including a zero-length record that delivers no bytes to the pipe. For TLS 1.3 the strparser announces a record before decryption, when its plaintext length is still unknown, so the readiness test cannot screen such a record out. A splice that consumes the record and waits for the next stalls every connection an event loop multiplexes. An LLM audit of the TLS read paths found this defect. Treat the socket's O_NONBLOCK as nonblocking too. A caller that sets O_NONBLOCK on the socket and splices without SPLICE_F_NONBLOCK now gets -EAGAIN where the splice blocked before. sendfile(2) from a TLS socket changes the same way, because do_sendfile() leaves the input file's O_NONBLOCK out of the splice flags. Both now behave as they do on a plain TCP socket. Fixes: c46234ebb4d1 ("tls: RX path for ktls") Signed-off-by: Chuck Lever <cel@kernel.org> Link: https://patch.msgid.link/20261027015215.605919-2-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
7 daysnet/sched: fix packet reordering on requeueAntonio Quartulli
dev_requeue_skb() appends requeued skbs to the tail of q->gso_skb, while dequeue_skb() takes them back one at a time from the head. If the driver returns NETDEV_TX_BUSY again for the first of them, it moves behind the skbs still parked there and is sent after them. This showed up as heavy TCP reordering while benchmarking over veth, which returns NETDEV_TX_BUSY whenever its ring is full since commit dc82a33297fc ("veth: apply qdisc backpressure on full ptr_ring to reduce TX drops"). Requeue the skbs at the head of gso_skb, keeping their order. With 4 TCP streams over a veth pair with a pfifo qdisc, this removes about 1.3M out-of-order segments and 15-37k retransmits per 15 seconds, and raises throughput from about 40 to 76 Gbit/s. Fixes: a53851e2c321 ("net: sched: explicit locking in gso_cpu fallback") Fixes: 9540d977618c ("net: sched: fix skb leak in dev_requeue_skb()") Cc: stable@vger.kernel.org Signed-off-by: Antonio Quartulli <antonio@mandelbit.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Acked-by: Jesper Dangaard Brouer <hawk@kernel.org> Link: https://patch.msgid.link/20261026153113.3275494-1-antonio@mandelbit.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
7 daysnet: dcb: initialize PFC value before calling getpfccfgJoas Antonio dos Santos
dcbnl_getpfccfg() and dcbnl_cee_fill() pass the address of an uninitialized stack u8 to the driver's getpfccfg() op and then put it into the netlink reply unconditionally. The op returns void, so the core cannot tell whether the driver wrote the value. i40e_dcbnl_get_pfc_cfg() and ice_dcbnl_get_pfc_cfg() return without writing *setting unless the DCBX agent is host managed and in CEE mode. Both drivers normally run with firmware managed DCBX (DCB_CAP_DCBX_LLD_MANAGED), and i40e with FW LLDP disabled runs host managed in IEEE mode, so on a DCB capable i40e/ice port the PFC values in DCB_CMD_PFC_GCFG and DCB_CMD_CEE_GET replies, and in the CEE part of RTNLGRP_DCB notifications, come from uninitialized stack. The same u8 is reused for all eight priorities, so this is one byte per reply. dcb_doit() only requires CAP_NET_ADMIN for RTM_SETDCB, so the GET commands are available to unprivileged users. Set the value to 0 before each call, like the PG config path already presets its outputs to DCB_ATTR_VALUE_UNDEFINED. 0 is also what the reply contains today on kernels built with CONFIG_INIT_STACK_ALL_ZERO, so nothing changes for those. Found by code inspection, compile-tested only (W=1). I don't have i40e/ice hardware to check the reply. Fixes: b94b013eb626 ("ice: Implement DCBNL support") Fixes: 5effa78e7c94 ("i40e: Add netlink callbacks support for software based DCB") Signed-off-by: Joas Antonio dos Santos <joasantonio108@gmail.com> Link: https://patch.msgid.link/179289284460.50470.572724041164324949@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
7 daysRevert "net: advertise TCP MSS from the configured MTU, not the learned PMTU"Yongjian Wang
This reverts commit 2640e6419594 ("net: advertise TCP MSS from the configured MTU, not the learned PMTU"). That commit stopped the learned PMTU from lowering the MSS we advertise in SYN and SYN-ACK. For symmetric paths it argued that "the peer runs its own PMTU discovery and usually already knows the real path MTU". That only holds if ICMP "fragmentation needed" can reach the peer. When the peer sits behind a firewall that drops inbound ICMP, its PMTU discovery is a black hole (RFC 2923, section 2.1), and the smaller MSS we advertised was the only thing keeping its full-size segments off the narrow hop. Inbound ICMP filtering is very common in enterprise and carrier networks, and it is pervasive in mainland China. We hit this in production after the commit was backported to 6.12.111: TCP connections that reach a server through a relay with a smaller-MTU hop complete the handshake, then stall as soon as the client sends full-size segments. Clients on networks that let ICMP through, and connections that bypass the relay, are unaffected, which made it hard to trace back to the kernel. Reproducer, network namespaces on a single host: cli --(1500)-- r1 --(1456)-- r2 --(1500)-- srv r1 drops ICMP frag-needed towards cli. srv has already learned PMTU 1456 towards cli, then cli uploads 1 MB to srv: kernel SYN-ACK MSS 1 MB upload 6.12.107 1416 OK 6.12.111 1460 stalls, times out 7.3-rc7 1460 stalls, times out 7.3-rc7 + this revert 1416 OK The asymmetric case the commit was written for does not need a new default: the advertised MSS can already be set per route with the advmss metric, which takes precedence over default_advmss(). With this revert applied, on an asymmetric path where srv learned PMTU 1456 towards cli while cli->srv is 1500 end to end: srv route to cli SYN-ACK MSS largest cli->srv segment default 1416 1404 advmss 1460 1460 1448 So DSR-style setups can opt in with "ip route ... advmss <mss>", while hosts whose peers cannot complete PMTU discovery keep working by default. Fixes: 2640e6419594 ("net: advertise TCP MSS from the configured MTU, not the learned PMTU") Closes: https://lore.kernel.org/regressions/4F0FAEB6-A13B-47F3-BFF1-C706686C6F64@gmail.com/ Cc: stable@vger.kernel.org Signed-off-by: Yongjian Wang <echoowall@gmail.com> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://patch.msgid.link/20261026-advmss-revert-v1-2-272fa4b7ecb6@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
7 daysnet: sched: em_ipt: validate hook value from netlinkFang Xieyan
em_ipt_change() accepts the user-provided TCA_EM_IPT_HOOK value without validating its range. The value is later used in check_match() as "1 << im->hook". A hook value of 32 or greater causes undefined behavior and may undermine the xt match hook-mask validation. The value is also passed to nf_hook_state_init() as a hook index. Reject hook values outside the supported IPv4/IPv6 Netfilter hook range after checking the required attributes, before loading the xt match or allocating the match state. Reviewed-by: Weibin Liu <liuwb@xiaopeng.com> Signed-off-by: Fang Xieyan <fangxy@xiaopeng.com> Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>
7 daysnet: sched: prevent scheduling deactivated qdiscsKyle Zeng
TAPRIO can schedule a deactivated qdisc after some_qdisc_is_busy() has reported it idle. Commit 47e8dbb6e763 ("net/sched: do not reset queues in graft operations") made graft deactivation skip queue reset, leaving TAPRIO's timer armed. A late callback schedules NET_TX softirq work, whose dequeue path can race the unlocked child-queue reset in taprio_reset(). The same skb can be queued for deferred freeing by RTNL and dequeued for transmission. In the reproducer, the TAP reader frees it before __rtnl_unlock() reads its next pointer. KASAN reports a slab-use-after-free in __rtnl_unlock+0xa3/0xd0, with a read of size 8 from the freed skb. Reject deactivated qdiscs in __netif_schedule(). Callers' RCU protection lets the existing grace period join earlier scheduling calls before the busy check. Restart nonempty transmit queues on reactivation so suppressed scheduling does not strand packets. Fixes: 47e8dbb6e763 ("net/sched: do not reset queues in graft operations") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/netdev/20260805102514.740834-1-david.lee@trailofbits.com/ Assisted-by: Codex:gpt-5.6-sol Codex:gpt-5.5-cyber Signed-off-by: Kyle Zeng <kylebot@openai.com> Co-developed-by: David Lee <david.lee@trailofbits.com> Signed-off-by: David Lee <david.lee@trailofbits.com> Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>
7 daysinet: frags: prevent acceptance of partially authenticated reassemblyJérémy Jean
A reassembled skb retains the secpath from its first fragment, which makes it possible for the final policy check to accept bytes that were not covered by the transform recorded on the skb. This can affect IPsec tunnel traffic, including AH and ESP, and allow a packet to be accepted even though only part of its payload was authenticated. Reject a fragment when its secpath differs from the fragments already in the queue, and keep overlap statistics limited to actual overlaps. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr> Reviewed-by: Eric Dumazet <edumazet@kernel.org> Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>
8 daystls: keep TX and RX hardware offload on the same deviceRishikesh Jethwani
After TX is offloaded on device A, a route change, or a change in the usable-slave set of an 802.3ad or balance-xor (layer3+4) bond, can make RX setup program device B. tls_device_attach() sees the existing TLS destructor and keeps ctx->netdev pointing at A. The RX driver state on B is then untracked: tls_dev_resync() and tls_dev_del() are invoked on A for a context it never created, and neither socket close nor NETDEV_DOWN on B calls tls_dev_del() for B, so the driver context leaks. The reverse setup order has the same problem. Check the shared device binding under device_offload_lock before each tls_dev_add(). Permit the first attachment and a second direction on the same device. Reject a different device, including when the old binding was cleared by NETDEV_DOWN: the TLS destructor remains installed and tls_device_attach() cannot establish a new binding. Setup then falls back to software for the requested direction. The RX check precedes allocation and software setup. TX uses its existing resource unwind path without calling the driver. Document the shared binding and clarify that fallback is per direction. This issue was discovered during code review and subsequently reproduced on hardware using mlx5 and TLS 1.2 AES-GCM-128. Changing the route between TX and RX setup installed the second direction on a different device. Driver traces showed successful adds on both devices, but both deletes at socket close targeted the first device, leaving an orphaned context on the second. Both setup orders reproduced the leak, even though all current core TLS context counters returned to zero. No crash was observed. With the fix, the same tests correctly fall back to software for the second direction and leave no orphaned hardware context. Fixes: 4799ac81e52a ("tls: Add rx inline crypto offload") Signed-off-by: Rishikesh Jethwani <rjethwani@purestorage.com> Signed-off-by: Dave Miller <davem@davem-thinkpadp1gen8.ibmlond.csb>