| Age | Commit message (Collapse) | Author |
|
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>
|
|
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()
...
|
|
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
...
|
|
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>
|
|
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
...
|
|
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
...
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
inet_csk_update_fastreuse() initializes the reuse caches only when
tb->bhash2 is empty, but both inet_csk_get_port() and
__inet_inherit_port() link tb2 before calling it, so the first-bind
branch is never taken.
As a result, SO_REUSEADDR binds never get fastreuse=1 and keep
scanning existing owners, and SO_REUSEPORT starts in STRICT instead
of ANY.
Initialize the caches when tb2 is the only entry in tb->bhash2 and has
no owners. Timewait sockets are also linked on tb2->owners, so this is
equivalent to the old hlist_empty(&tb->owners) test.
Found by manual code inspection and confirmed with GDB. Binding 16000
SO_REUSEADDR sockets to one address/port in a KVM guest takes 4.18 s
before and 19.4 ms after this patch. Existing bind/reuse selftests
pass. Analysis and testing were assisted by an AI tool (Codex).
Fixes: 8002d44fe84d ("tcp: Check hlist_empty(&tb->bhash2) instead of hlist_empty(&tb->owners).")
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Signed-off-by: Zhewei Yuan <yzwlhm@gmail.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Jason Xing <kerneljasonxing@gmail.com>
Link: https://patch.msgid.link/20261026095208.58504-1-yzwlhm@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
When DEVLINK_CMD_REGION_NEW is issued without a snapshot id, the kernel
allocates one with __devlink_region_snapshot_id_get(). That helper counts
the caller as a user of the id, and the caller must release this hold
once it is done.
devlink_nl_region_new_doit() never drops it. The refcount of the id goes
1 (allocation) -> 2 (snapshot created) and stays at 2. When the snapshot
is deleted the count only drops to 1, so the id is never erased from
the snapshot_ids xarray. The id then stays in use for the lifetime of
the devlink instance: requesting a snapshot with that explicit id fails
with -EEXIST, and there is no snapshot left to delete to clean it up.
Reproducer steps:
# devlink region new pci/0000:13:00.0/device-caps
pci/0000:13:00.0/device-caps: snapshot 0
# devlink region del pci/0000:13:00.0/device-caps snapshot 0
# devlink region new pci/0000:13:00.0/device-caps snapshot 0
kernel answers: File exists
Drop the caller's reference right after the snapshot has been created,
as the snapshot then holds its own.
Fixes: 043b3e22768d ("devlink: let kernel allocate region snapshot id")
Reported-by: Guikun Yang <yangguikun19@qq.com>
Closes: https://lore.kernel.org/netdev/tencent_BE912BA710539F285F9FCF28E854ABEFCD07@qq.com/
Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
Link: https://patch.msgid.link/20261026174403.512-1-fmancera@suse.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
store_rps_dev_flow_table_cnt() accepts rps_flow_cnt == 1. For count == 1
the round-up loop leaves mask == 0, which is stored as log == 0 in the
tag (tag_ptr |= ilog2(mask) + 1). get_rps_cpu() then calls
rfs_slot() -> hash_32(hash, rps_tag_to_log(tag_ptr)) with log == 0:
include/linux/hash.h:68
return __hash_32(val) >> (32 - bits); /* bits == 0 -> shift by 32 */
The shift by 32 is undefined and yields the full 32-bit hash, which is
used to index the one-entry rps_dev_flow[] table unchecked:
UBSAN: shift-out-of-bounds in ./include/linux/hash.h:68:24
shift exponent 32 is too large for 32-bit type 'unsigned int'
__ubsan_handle_shift_out_of_bounds+0x11c/0x208
get_rps_cpu+0x12fc/0x1344
netif_rx_internal+0x1e0/0x4d4
rps_dev_flow[] is then read (rflow->cpu) and written (last_qtail) out of
bounds on the packet path. Require at least two entries.
Fixes: f3483c8e1da6 ("net: rfs: hash function change")
Signed-off-by: Dudu Lu <phx0fer@gmail.com>
Link: https://patch.msgid.link/20261021155522.67521-1-phx0fer@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
The priority VLAN receive path can repeatedly remove VID 0 tags and retry
packet processing. Unlike the read-only VLAN protocol parser, this path has
no limit on the number of nested tags it consumes.
Each skb_vlan_untag() advances skb->data and resets header offsets. The
offsets are stored in 16-bit fields. With enough nested tags, the network
or transport offset can wrap. A later protocol handler can then derive a
large pull length from the wrapped offsets and access memory outside the
skb allocation.
Apply the existing VLAN_MAX_DEPTH limit to the exceptional VID 0 retry.
Count the tag already stored in skb VLAN metadata as the first level, then
stop before untagging a ninth level. Keep the accounting inside this
uncommon branch so the regular VLAN receive path is unaffected.
A single VID 0 priority tag before a real VLAN tag is valid. No normal
deployment was found that intentionally emits multiple consecutive VID 0
tags; permitting eight levels is therefore conservative.
The issue was found while researching the Linux network receive path for
Google kvmCTF, with OpenAI Codex (gpt-5.6-sol) assisting the analysis. The
affected path, reproducer and fix were manually reviewed and tested.
Fixes: 36b2f61a42c2 ("net: handle 802.1P vlan 0 packets properly")
Cc: stable@vger.kernel.org
Reviewed-by: Willem de Bruijn <willemb@google.com>
Signed-off-by: Kamil Sawicki <user148783812897@gmail.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261024004835.17862-1-user148783812897@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
__netif_set_xps_queue() walks the OLD dev_maps to free its entries. The
per-row trip count uses the NEW num_tc while the row stride uses the OLD
dev_maps->num_tc, so when dev->num_tc was raised without rebuilding the
XPS map the last row indexes attr_map[] past the allocation:
BUG: KASAN: slab-out-of-bounds in __netif_set_xps_queue+0x1458/0x1ee8
Read of size 8 at addr ffff000014f69458 by task insmod/112
The loop frees entries in dev_maps, so both the trip count and the stride
must come from dev_maps->num_tc. The map is sized
XPS_CPU_DEV_MAPS_SIZE(old num_tc)/XPS_RXQ_DEV_MAPS_SIZE(old num_tc, ...),
so iterating the new (larger) num_tc reads past the end.
Fixes: 255c04a87f43 ("net: embed num_tc in the xps maps")
Signed-off-by: Dudu Lu <phx0fer@gmail.com>
Reviewed-by: Antoine Tenart <atenart@kernel.org>
Link: https://patch.msgid.link/20261021155538.67867-1-phx0fer@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
When RTAX_CWND is locked, user is able to pass 0 into it.
This could lead to writing 0 to tp->snd_cwnd, leading to a
division by zero error.
Oops: divide error: 0000 [#1] SMP KASAN NOPTI
Call Trace:
<IRQ>
tcp_reno_cong_avoid (net/ipv4/tcp_cong.c:510 (discriminator 1))
tcp_ack (net/ipv4/tcp_input.c:3517 net/ipv4/tcp_input.c:3873 net/ipv4/tcp_input.c:4440)
tcp_rcv_established (net/ipv4/tcp_input.c:6685)
tcp_v4_do_rcv (net/ipv4/tcp_ipv4.c:1854)
tcp_v4_rcv (net/ipv4/tcp_ipv4.c:2248)
ip_protocol_deliver_rcu (net/ipv4/ip_input.c:207 (discriminator 1))
ip_local_deliver_finish (net/ipv4/ip_input.c:241 (discriminator 1))
ip_local_deliver (./include/linux/netfilter.h:325 ./include/linux/netfilter.h:319 net/ipv4/ip_input.c:262)
ip_rcv (./include/net/dst.h:481 (discriminator 6) net/ipv4/ip_input.c:492 (discriminator 6) ./include/linux/netfilter.h:325 (discriminator 6) ./include/li)
__netif_receive_skb_one_core (net/core/dev.c:6297 (discriminator 4))
__netif_receive_skb (net/core/dev.c:6410)
process_backlog (net/core/dev.c:6761)
__napi_poll.constprop.0 (net/core/dev.c:7830)
net_rx_action (net/core/dev.c:7893 net/core/dev.c:8050)
handle_softirqs (kernel/softirq.c:645)
__irq_exit_rcu (kernel/softirq.c:679 kernel/softirq.c:519 kernel/softirq.c:758)
irq_exit_rcu (kernel/softirq.c:775)
sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1062 (discriminator 35) arch/x86/kernel/apic/apic.c:1062 (discriminator 35))
RIP: 0010:tcp_cong_avoid_ai (net/ipv4/tcp_cong.c:482)
Fix by checking if user pass in zero as parameter and if lock is present.
Fixes: 814d488c6126 ("tcp: fix the timid additive increase on stretch ACKs")
Cc: stable@vger.kernel.org
Suggested-by: Eric Dumazet <edumazet@kernel.org>
Reported-by: co+71b6509cb791e531@bugs.sh
Signed-off-by: Kaho Jiang <kj2864@nyu.edu>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261021235732.1313305-2-kj2864@nyu.edu
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
rds, rds_rdma and rds_tcp each have their own module_init(). When they
are built in, those run in link order, so rds_init() goes first, but
do_initcalls() does not stop when it fails. The transports then
initialize against a core that has already been torn down: rds_wq has
been destroyed, yet rds_ib_dev_put(), rds_ib_unregister_client() and
rds_tcp_accept_work() still queue onto or flush it, and
rds_trans_register() hands the transports to a core whose socket
family may never have been registered.
This was seen with CONFIG_SYSCTL=n, where rds_sysctl_init() failed and
rds_ib_init()'s error path then flushed the freed rds_wq [1], but any
rds_init() failure after rds_threads_init() has the same effect.
Record whether rds_init() succeeded and have rds_rdma_init() and
rds_tcp_init() bail out with -ENODEV otherwise. Modular builds are
unaffected: the transports need symbols exported by rds.ko, so they
cannot be loaded unless rds_init() succeeded.
[1] https://lore.kernel.org/oe-lkp/202610190310.9737b2e3-lkp@intel.com
Fixes: 55b7ed0b582f ("RDS: Common RDMA transport code")
Fixes: 70041088e3b9 ("RDS: Add TCP transport to RDS")
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20261021195837.142802-3-achender@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
With CONFIG_SYSCTL=n, register_net_sysctl() and register_net_sysctl_sz()
are inline stubs that return NULL. rds_sysctl_init(),
rds_ib_sysctl_init() and rds_tcp_init_net() all treat that NULL as
-ENOMEM, so RDS refuses to initialize at all even though every tunable
has a sane compiled-in default.
When RDS is built in, that is worse than a missing feature: the failed
rds_init() destroys rds_wq, but the rds_rdma initcall still runs, and
when rds_ib_sysctl_init() fails the same way, the error path in
rds_ib_init() flushes the already freed workqueue:
BUG: KASAN: slab-use-after-free in touch_wq_lockdep_map
...
__flush_workqueue
rds_ib_init
rds_rdma_init
...
Allocated by task 1:
alloc_workqueue_noprof
rds_threads_init
rds_init
...
Freed by task 0:
kfree
rcu_do_batch
Only treat the NULL return as a failure when sysctl support is actually
compiled in. The exit paths need no change: unregister_net_sysctl_table()
is an empty stub with CONFIG_SYSCTL=n and already tolerates a NULL header
otherwise.
The underlying problem of built-in transports initializing after
rds_init() has failed is independent of sysctl and is addressed
separately.
Reported-by: kernel test robot <yi1.lai@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202610190310.9737b2e3-lkp@intel.com
Fixes: 3e5048495c85 ("RDS: sysctls")
Fixes: e6babe4cc4ce ("RDS/IB: Stats and sysctls")
Fixes: c6a58ffed536 ("RDS: TCP: Add sysctl tunables for sndbuf/rcvbuf on rds-tcp socket")
Suggested-by: Joel Granados <joel.granados@kernel.org>
Signed-off-by: Allison Henderson <achender@kernel.org>
Reviewed-by: Joel Granados <joel.granados@kernel.org>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Link: https://patch.msgid.link/20261021195837.142802-2-achender@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
xp_assign_dev() sets XDP_UMEM_SG_FLAG before checking whether the
device supports multibuffer zero-copy. If assignment fails, xsk_bind()
destroys the pool but retains the registered UMEM. A subsequent bind
without XDP_USE_SG inherits the stale flag.
The flag also changes RX buffer sizing after DMA mapping. On igc, a
failed SG bind followed by a non-SG retry with 4096-byte chunks and
1792 bytes of headroom passes admission with 2048 bytes, but programs
a 1024-byte RX buffer. On I225-V hardware, an ordinary 1514-byte frame
is truncated to 1024 bytes or 1008 with RX timestamps enabled.
Restoring the original flags eliminates the truncation in both cases.
Save the UMEM flags before assignment and restore them on failure.
Discovered during development of AF_XDP changes for igc.
Fixes: d609f3d228a8 ("xsk: add multi-buffer support for sockets sharing umem")
Cc: stable@vger.kernel.org
Signed-off-by: Paul Moses <p@1g4.org>
Acked-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
Link: https://patch.msgid.link/20261021224705.2078753-1-p@1g4.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
tcp_tso_autosize() right-shifts the u32 returned by tcp_min_rtt() by
sysctl_tcp_tso_rtt_log. The sysctl uses proc_dou8vec_minmax() without
an upper bound, so it accepts values through 255. Values above 31 make
the shift undefined.
A process with CAP_NET_ADMIN in the target network namespace can set the
per-netns sysctl. With CONFIG_UBSAN_SHIFT=y, setting it to 32 and sending
TCP data over loopback triggers:
UBSAN: shift-out-of-bounds in net/ipv4/tcp_output.c:2264:30
shift exponent 32 is too large for 32-bit type 'unsigned int'
Call Trace:
__ubsan_handle_shift_out_of_bounds
tcp_tso_segs
tcp_write_xmit
__tcp_push_pending_frames
tcp_push
tcp_sendmsg_locked
Limit the sysctl to 31, the largest valid shift count for a u32, and
document the accepted range. Writes of larger values now fail with
-EINVAL.
On a UBSAN/KASAN build of the net tree, values 0 and 31 remained
accepted, values 32 and 255 returned -EINVAL, and TCP traffic with the
valid boundary values produced no sanitizer diagnostics.
Fixes: 65466904b015 ("tcp: adjust TSO packet sizes based on min_rtt")
Cc: stable@vger.kernel.org
Signed-off-by: Yingjie Wang <1075151112@qq.com>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Neal Cardwell <ncardwell@google.com>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/tencent_31D2FFCCE76C50A695A1270151F825E90906@qq.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
TIPC assumes that the received skb is not shared with other users.
However, syzbot reports a bug triggered by receiving a shared skb:
...
RIP: 0010:pskb_expand_head+0x135a/0x13a0 net/core/skbuff.c:2308
__pskb_pull_tail+0x111/0x1870 net/core/skbuff.c:2890
skb_cow_data+0x2ed/0xc50 net/core/skbuff.c:5398
tipc_aead_decrypt net/tipc/crypto.c:892 [inline]
tipc_crypto_rcv+0x346/0x23d0 net/tipc/crypto.c:1843
tipc_rcv+0x4b7/0x1040 net/tipc/node.c:2119
tipc_l2_rcv_msg+0x2d9/0x470 net/tipc/bearer.c:669
deliver_ptype_list_skb net/core/dev.c:2533 [inline]
...
The root cause is that local delivery hooks in the kernel (e.g.,
deliver_skb()) may increment the skb's reference count (`users`) before
TIPC processes it on ingress.
Fix this by calling skb_share_check() to ensure exclusive ownership
before passing the skb to tipc_rcv(). As TIPC needs to modify the skb's
data, the cloned skb needs to be uncloned when needed. This can be
addressed in separate patch.
Reported-by: syzbot+0017742620a9d06f06ef@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0017742620a9d06f06ef
Closes: https://lore.kernel.org/all/20261018145928.58317-1-ngocthang2710.1999@gmail.com/T/
Fixes: b97bf3fd8f6a ("[TIPC] Initial merge")
Co-developed-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Signed-off-by: Nguyen Ngoc Thang <ngocthang2710.1999@gmail.com>
Signed-off-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Link: https://patch.msgid.link/20261023052921.54220-1-tung.quang.nguyen@est.tech
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
A packet can race with VIF publication and make ipmr_find_vif() return
-1 even though the VIF device pointer is already visible. The parent VIF
device check can then pass with an invalid ingress VIF. For (*,G)
entries, this can also let the packet be forwarded back out its ingress
VIF.
Drop packets whose ingress VIF lookup fails in both IPv4 and IPv6
forwarding, before checking the MFC parent device. This prevents
forwarding with an unknown ingress VIF and avoids the (*,G) hairpin.
Without the early check, the negative index can reach the IPv4 offload
lookup only for an skb marked for L3 forwarding offload, currently done
by mlxsw. The race is rare; the supplied PoC reports only the UBSAN
negative-index diagnostic.
Fixes: 4eadb88244d1 ("ipmr: do not acquire mrt_lock while calling ip_mr_forward()")
Fixes: 9b1c21d898fd ("ip6mr: do not acquire mrt_lock while calling ip6_mr_forward()")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Link: https://lore.kernel.org/netdev/b966eb102e98f299e45be59ada033a8766e4c6df.1791899747.git.zhilinz@nebusec.ai/
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Suggested-by: Naman Gulati <namangulati@google.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Naman Gulati <namangulati@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/5271fcb94a4d9e697ed64a348e92ea9e74faab1c.1792608753.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
reg_vif_xmit() passes the packet to ipmr_cache_report() which copies its
IP header into the IGMPMSG_WHOLEPKT report that is queued to the mroute
socket. Nothing guarantees that the packet contains a full IP header, so
when a short packet is injected on the register device (e.g., using
AF_PACKET), the copy reads past the end of the packet and a recvmsg() on
the mroute socket leaks the uninitialized bytes to user space [1].
IPv6 has the same problem [2]. Its reg_vif_xmit() does call
pskb_inet_may_pull(), but the helper keys off skb->protocol and does not
pull anything when the protocol is neither IPv4 nor IPv6.
Fix by dropping packets whose protocol does not match the address family
of the register device or that do not contain a full network header.
[1]
BUG: KMSAN: kernel-infoleak in _copy_to_iter
raw_recvmsg
Uninit was stored to memory at:
ipmr_cache_report
reg_vif_xmit
packet_sendmsg
Uninit was created at:
__alloc_skb
sock_alloc_send_pskb
packet_sendmsg
Bytes 1-3 of 21 are uninitialized
[2]
BUG: KMSAN: kernel-infoleak in _copy_to_iter
rawv6_recvmsg
Uninit was stored to memory at:
ip6mr_cache_report
reg_vif_xmit
packet_sendmsg
Uninit was created at:
__alloc_skb
sock_alloc_send_pskb
packet_sendmsg
Bytes 8-23 of 41 are uninitialized
Fixes: 14fb64e1f449 ("[IPV6] MROUTE: Support PIM-SM (SSM).")
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <netdev-bot+sashiko@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/0545f0c83f5ee2f6696210f87268e811ef655715.1792476357.git.zhilinz%40nebusec.ai
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261025071729.34967-3-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
For an unresolved multicast route query, ipmr_get_route() builds a
synthetic IP header in the headroom obtained from
skb_realloc_headroom(), which does not zero the memory it allocates.
Only a few fields are initialized, leaving others as stale heap
contents.
ipmr_cache_report() copies this header into the IGMPMSG_NOCACHE report
that is queued to the mroute socket, so a recvmsg() on that socket leaks
the uninitialized bytes to user space: the 'tos' field [1] and the 'id'
and 'frag_off' fields [2].
Fix by zeroing the IP header before filling in the few fields that are
used, so that the entire header is initialized, as in ip6mr_get_route().
[1]
BUG: KMSAN: kernel-infoleak in _copy_to_iter
raw_recvmsg
Uninit was stored to memory at:
ipmr_cache_report
ipmr_cache_unresolved
ipmr_get_route
Uninit was created at:
pskb_expand_head
skb_realloc_headroom
ipmr_get_route
Byte 1 of 28 is uninitialized
[2]
BUG: KMSAN: kernel-infoleak in _copy_to_iter
raw_recvmsg
Uninit was stored to memory at:
ipmr_cache_report
ipmr_cache_unresolved
ipmr_get_route
Uninit was created at:
pskb_expand_head
skb_realloc_headroom
ipmr_get_route
Bytes 4-7 of 28 are uninitialized
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <netdev-bot+sashiko@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/0545f0c83f5ee2f6696210f87268e811ef655715.1792476357.git.zhilinz%40nebusec.ai
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261025071729.34967-2-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
reg_vif_xmit() hands the skb to ipmr_cache_report() as an
IGMPMSG_WHOLEPKT report. When the mroute socket has IP_PKTINFO
enabled, ipmr_cache_report() calls ipv4_pktinfo_prepare() on the
original skb, which reads skb->cb[] as IPCB.
By the time the pimreg device transmits the packet, skb->cb[] is not
IPCB anymore: qdisc_pkt_len_init() overwrites IPCB(skb)->iif with
qdisc_skb_cb(skb)->pkt_len, and any qdisc installed on the device or a
tc BPF program writing skb->cb[] fills the area holding the IP options
and IPCB(skb)->flags.
For locally generated packets routed out pimreg (they carry an rtable
dst), the mroute socket can therefore receive a bogus ipi_ifindex
(the packet length), and the l3mdev slave test in
ipv4_pktinfo_prepare() is driven by stale qdisc data.
Clear IPCB before building the report, as done for IPv6 in
commit 238164201431 ("ip6mr: clear skb->cb[] in reg_vif_xmit()").
The skb is freed right after, so nothing else depends on its control
block.
Fixes: bb7403655b3c ("ipmr: support IP_PKTINFO on cache report IGMP msg")
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20261025111337.142787-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
An SKB_GSO_DODGY packet can carry untrusted gso_size and headers.
For instance, gso_size=1 and hdr_len=65532 for a 524275-byte frame
makes qdisc_pkt_len_segs_init() compute an accounted length of
about 4,294,574,091 bytes (after gso_segs silently wrapped in a u16).
With DRR quantum 256, the dequeue path then needs ~16.8 million
deficit refills before it can dequeue the skb, keeping the CPU in
the qdisc path long enough to trigger the soft-lockup watchdog.
Commit 8f735d64382d ("net/sched: bound qdisc_pkt_len to prevent
qdisc soft lockup") added QDISC_PKT_LEN_MAX to bound size table
amplification. Use the same bound for DODGY packets:
- Make gso_segs a u32 and drop packets whose segment count does
not fit GSO_MAX_SEGS, instead of silently truncating it.
- Drop packets whose estimated qdisc_pkt_len() would exceed
QDISC_PKT_LEN_MAX.
Fixes: 15e5a0307164 ("net_sched: better precise estimation on packet length for untrusted packets")
Reported-by: shaos <shawnq1@163.com>
Closes: https://lore.kernel.org/netdev/20261022144755.65025-1-shawnq1@163.com/
Signed-off-by: Eric Dumazet <edumazet@kernel.org>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20261022155436.117507-1-edumazet@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
taprio_module_init() registers taprio_device_notifier and then returns
register_qdisc()'s error directly. When register_qdisc() fails the
notifier stays registered, but the loader's failure path frees the module
image without ever calling the __exit function, so netdev_chain is left
pointing at taprio_device_notifier.notifier_call -- a function pointer
that lives in text that has just been freed.
register_qdisc() has two failure returns: -EEXIST (duplicate .id) and
-EINVAL (malformed cl_ops). taprio_class_ops satisfies every checked
implication, so -EINVAL is unreachable and -EEXIST is the only reachable
failure; it needs a pre-existing "taprio" entry in qdisc_base. In-tree
that is reachable only through bpf_qdisc_reg() (CONFIG_NET_SCH_BPF); a
module calling the exported register_qdisc() reaches it as well.
Once the notifier is left dangling, the next netdevice event that walks
netdev_chain calls through the stale pointer:
BUG: KASAN: vmalloc-out-of-bounds in notifier_call_chain+0x650/0xb5c
Read of size 8 at addr ffff80001fc5ab08 by task ip/110
notifier_call_chain+0x650/0xb5c
raw_notifier_call_chain+0x34/0x64
call_netdevice_notifiers_info+0xa8/0x198
__dev_close_many+0xe0/0x800
...
>ffff80001fc5ab00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
The shadow row is all f8 (KASAN_VMALLOC_INVALID): the read lands in
vmalloc memory that was poisoned when the module image was freed, and the
indirect call is unguarded because the only check, func_ptr_is_kernel_text(),
is compiled out unless CONFIG_DEBUG_NOTIFIERS.
Mirror the sibling sch_cbs.c and act_mirred.c, which unwind the notifier
on this failure path.
Fixes: 7b9eba7ba0c1 ("net/sched: taprio: fix picos_per_byte miscalculation")
Signed-off-by: Dudu Lu <phx0fer@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20261021155417.66254-1-phx0fer@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
tcf_action_init() gives the skip_sw and skip_hw flags of a filter to the
actions it binds. An action that another filter created gets them too,
they then apply to every filter that uses this action. When a
skip_sw filter reuses the action of a software filter, the software
filter silently stops running it. This happens even when the filter add
fails on a later action. A skip_hw filter likewise prevents a later
filter without flags from reusing the action.
Give the flags only to the actions that the filter creates. The mismatch
check still rejects a filter that reuses an action with a flag that the
filter does not have.
Discovered by manual code inspection after the Sashiko AI review [1] of
a tunnel_key patch questioned how actions get the filter flags.
Reproduced on netdevsim without kernel changes. The egress filter below
runs in software only, since netdevsim offloads only ingress filters.
Once the skip_sw filter reuses its drop action, the last command shows
skip_sw on this action and the egress filter stops dropping packets:
ethtool -K eth0 hw-tc-offload on
tc qdisc add dev eth0 clsact
tc filter add dev eth0 egress protocol ip flower dst_ip 192.0.2.1 \
action gact drop index 1
tc filter add dev eth0 ingress protocol ip flower skip_sw \
dst_ip 192.0.2.2 action gact drop index 1
tc actions get action gact index 1
Tested with the reproducer and the tc-testing action, matchall and
flower tests.
Fixes: 34d35b4edbbe ("net/sched: act_api: deny mismatched skip_sw/skip_hw flags for actions created by classifiers")
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261009051930.3619697-1-acassen%40corp.free.fr [1]
Signed-off-by: Alexandre Cassen <acassen@corp.free.fr>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20261021193222.1318333-2-acassen@corp.free.fr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
gred_change_table_def() publishes table->DPs/def/red_flags under
sch_tree_lock(), drops the lock, and then keeps writing state the
datapath reads without it:
- gred_enable_rio_mode()/gred_disable_rio_mode()/gred_disable_wred_mode()
set/clear table->flags;
- the red_flags_changed loop writes table->tab[i]->red_flags;
- the shadowed-VQ loop frees table->tab[i] and clears the slot.
gred_enqueue() and gred_dequeue() read those same fields (test_bit on
table->flags, q->red_flags, t->tab[]/t->DPs) under the same root lock on
another CPU, so the post-unlock writes race with the enqueue path:
BUG: KCSAN: data-race in gred_change_table_def [sch_gred] / gred_enqueue [sch_gred]
read (marked) to 0xffff000007ad3b00 of 8 bytes by task 110 on cpu 0:
gred_enqueue+0x88/0xc60 [sch_gred]
dev_qdisc_enqueue+0x4c/0x19c
__dev_queue_xmit+0x10a4/0x1ea4
The comment justifying the early unlock only covers the DP-vs-DPs check,
which the shadowed-VQ free loop relies on; it does not cover the scalar
mode bits and per-VQ red_flags written afterwards. Move the unlock below
those updates so everything the datapath reads is published under the
lock that protects it.
Fixes: 6639607ed9de ("[PKT_SCHED]: GRED: Use a central table definition change procedure")
Signed-off-by: Dudu Lu <phx0fer@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261021155434.66572-1-phx0fer@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
Initialize the CRUSH choose argument weight-set array before decoding so
entries start in a defined state while the decoder fills them.
Cc: stable@vger.kernel.org
Fixes: 5cf9c4a9959b ("libceph, crush: per-pool crush_choose_arg_map for crush_do_rule()")
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Signed-off-by: Darong Lu <zzyy19904204639@163.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Alex Markuze <amarkuze@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
|