* [PATCH 5.10 00/57] 5.10.267-rc1 review
@ 2026-08-25 13:26 Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 01/57] Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept Greg Kroah-Hartman
` (62 more replies)
0 siblings, 63 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, linux-kernel, torvalds, akpm, linux,
shuah, patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
This is the start of the stable review cycle for the 5.10.267 release.
There are 57 patches in this series, all will be posted as a response
to this one. If anyone has any issues with these being applied, please
let me know.
Responses should be made by Thu, 27 Aug 2026 13:25:02 +0000.
Anything received after that time might be too late.
The whole patch series can be found in one patch at:
https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.267-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Linux 5.10.267-rc1
Michael Bommarito <michael.bommarito@gmail.com>
HID: hyperv: validate initial device info bounds
Haoxiang Li <haoxiang_li2024@163.com>
HID: sensor: custom: Fix use-after-free in enable_sensor
Jann Horn <jannh@google.com>
HID: core: fix number/pointer type confusion on long items
Oliver Hartkopp <socketcan@hartkopp.net>
can: isotp: fix timer drain order, wakeup handling and tx_gen ordering
Oliver Hartkopp <socketcan@hartkopp.net>
can: use skb hash instead of private variable in headroom
Weiming Shi <bestswngs@gmail.com>
bpf: reject negative CO-RE accessor indices in bpf_core_parse_spec()
Eric Farman <farman@linux.ibm.com>
s390/vfio_ccw: Free all memory if cp_init() fails
Joanne Koong <joannelkoong@gmail.com>
iomap: adjust read range correctly for non-block-aligned positions
Xiang Mei (Microsoft) <xmei5@asu.edu>
xfrm: fix sk_dst_cache double-free in xfrm_user_policy()
Sasha Levin <sashal@kernel.org>
Revert "Input: ims-pcu - fix race condition in reset_device sysfs callback"
Baul Lee <baul.lee@xbow.com>
HID: core: fix OOB read of field->usage in hid_set_field()
Lee Jones <lee@kernel.org>
HID: magicmouse: Prevent out-of-bounds (OOB) read during DOUBLE_REPORT_ID
Pavitra Jha <jhapavitra98@gmail.com>
libceph: fix OOB read in decode_watchers() via missing bounds check
Junjie Cao <junjie.cao@intel.com>
gpio: ml-ioh: use raw_spinlock_t for the register lock
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
nvmet-tcp: Do not WARN on remotely-controlled oversized SGL allocations
Jiang HongHui <jiang_hh2019@163.com>
nvmet-fc: fix invalid free in LS IOD error path
Luxiao Xu <rakukuip@gmail.com>
ipv6: fix use-after-free in ip6_finish_output2()
Yong Wang <edragain@163.com>
ipv4: reject undersized MTUs in ip_do_fragment()
Ibrahim Hashimov <security@auditcode.ai>
xfs: bounds-check buffer log item's dirty bitmap
Linmao Li <lilinmao@kylinos.cn>
nfc: nci: free destination parameters when closing a connection
Samuel Page <sam@bynar.io>
nfc: nci: fix out-of-bounds write in nci_target_auto_activated()
Doruk Tan Ozturk <doruk@0sec.ai>
nfc: st21nfca: validate ATR_REQ length against the received frame
Xu Rao <raoxu@uniontech.com>
nfc: pn533: purge fragmented skbs during cleanup
Doruk Tan Ozturk <doruk@0sec.ai>
nfc: llcp: reject PDUs shorter than the LLCP header
Muhammad Bilal <meatuni001@gmail.com>
nfc: llcp: fix OOB read and u8 offset wrap in TLV parsers
Doruk Tan Ozturk <doruk@0sec.ai>
nfc: llcp: bound the connect_sn TLV walk to the skb
Pengpeng Hou <pengpeng@iscas.ac.cn>
nfc: microread: validate target discovery payload lengths
Bryam Vargas <hexlabsecurity@proton.me>
nfc: fdp: bound the device-reported read length and fix an skb leak
Doruk Tan Ozturk <doruk@0sec.ai>
nfc: digital: clamp SENSF_RES length to the destination buffer
David Matlack <dmatlack@google.com>
KVM: arm64: Retry fault if vma_lookup() results become invalid
Eric Farman <farman@linux.ibm.com>
s390/vfio_ccw: Cancel existing workqueues
Pei Xiao <xiaopei01@kylinos.cn>
mmc: atmel-mci: Fix use-after-free in atmci_remove due to race condition
Long Li <leo.lilong@huawei.com>
xfs: fix ilock leak on error in xfs_dq_get_next_id
Zhiling Zou <zhilinz@nebusec.ai>
inet: frags: publish queues before arming timer
Zihan Xi <zihanx@nebusec.ai>
packet: synchronize pressure clearing with ring reconfiguration
Zijie Huang <milkory@outlook.com>
net/sched: reject overly deep qdisc hierarchies
Qihang Tang <q.h.hack.winter@gmail.com>
packet: use consistent hard_header_len in TX_RING send path
Qihang Tang <q.h.hack.winter@gmail.com>
packet: use consistent hard_header_len in non-ring send paths
Aditya Chillara <aditya.chillara@oss.qualcomm.com>
perf/core: Fix group leader use-after-free after sibling detach
Yeoreum Yun <yeoreum.yun@arm.com>
perf: Fix dangling cgroup pointer in cpuctx
Peter Zijlstra <peterz@infradead.org>
perf: Fix cgroup state vs ERROR
Fan Wu <fanwu01@zju.edu.cn>
serial: amba-pl011: synchronize DMA teardown
Koichiro Den <den@valinux.co.jp>
NTB: ntb_netdev: Preserve RX queue depth on allocation failure
Zihan Xi <zihanx@nebusec.ai>
ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops
Amit Cohen <amcohen@nvidia.com>
net: ipv4: Publish fib_nlmsg_size()
Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
misc: fastrpc: Remove buffer from list prior to unmap operation
Abel Vesa <abel.vesa@linaro.org>
misc: fastrpc: Rework fastrpc_req_munmap
Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
misc: fastrpc: separate fastrpc device from channel context
Muhammad Bilal <meatuni001@gmail.com>
staging: rtl8723bs: fix OOB read in WMM_param_handler()
Lorenzo Stoakes (ARM) <ljs@kernel.org>
mm/huge_memory: fix huge_zero_pfn race
Baul Lee <baul.lee@xbow.com>
net/x25: fix use-after-free of the socket by its timers
Hongling Zeng <zenghongling@kylinos.cn>
xfs: validate attr entry pointer before field access
Guanghui Yang <3497809730@qq.com>
ext4: clear error before retrying inode xattr space fallback
Matthias Goergens <matthias.goergens@gmail.com>
ext4: stop retrying saturated xattr cache entries
Ian Bridges <icb@fastmail.org>
ocfs2: fix missing metadata reservation for large xattrs
Griffin Kroah-Hartman <griffin@kroah.com>
rndis_host: add overflow check in rndis_rx_fixup()
Ali Ahmet Memis <ali@iusegentoo.com>
Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept
-------------
Diffstat:
Makefile | 4 +-
arch/arm64/kvm/mmu.c | 42 ++--
drivers/gpio/gpio-ml-ioh.c | 36 +--
drivers/hid/hid-core.c | 11 +-
drivers/hid/hid-hyperv.c | 27 ++-
drivers/hid/hid-magicmouse.c | 16 ++
drivers/hid/hid-sensor-custom.c | 21 +-
drivers/input/misc/ims-pcu.c | 2 -
drivers/misc/fastrpc.c | 110 ++++++---
drivers/mmc/host/atmel-mci.c | 2 +
drivers/net/can/dev/dev.c | 2 -
drivers/net/can/slcan.c | 1 -
drivers/net/ntb_netdev.c | 15 +-
drivers/net/usb/rndis_host.c | 6 +-
drivers/nfc/fdp/i2c.c | 27 +++
drivers/nfc/microread/microread.c | 31 ++-
drivers/nfc/pn533/pn533.c | 1 +
drivers/nfc/st21nfca/dep.c | 3 +
drivers/nvme/target/fc.c | 2 +-
drivers/nvme/target/tcp.c | 5 +-
drivers/s390/cio/vfio_ccw_cp.c | 22 +-
drivers/s390/cio/vfio_ccw_drv.c | 7 +
drivers/s390/cio/vfio_ccw_ops.c | 8 +
drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 3 +
drivers/tty/serial/amba-pl011.c | 8 +-
fs/ext4/xattr.c | 7 +-
fs/iomap/buffered-io.c | 19 +-
fs/ocfs2/xattr.c | 18 +-
fs/xfs/libxfs/xfs_attr_leaf.c | 14 ++
fs/xfs/xfs_buf_item_recover.c | 53 ++--
fs/xfs/xfs_dquot.c | 3 +-
include/linux/can/core.h | 1 +
include/linux/can/dev.h | 1 -
include/linux/can/skb.h | 2 -
include/linux/netdevice.h | 6 +-
include/net/sch_generic.h | 1 +
kernel/events/core.c | 104 ++++----
mm/huge_memory.c | 52 ++--
net/bluetooth/rfcomm/core.c | 24 +-
net/can/af_can.c | 14 +-
net/can/bcm.c | 2 -
net/can/isotp.c | 320 ++++++++++++++++++-------
net/can/j1939/socket.c | 1 -
net/can/j1939/transport.c | 2 -
net/can/raw.c | 7 +-
net/ceph/osd_client.c | 5 +-
net/ipv4/fib_lookup.h | 1 +
net/ipv4/fib_semantics.c | 69 ++++--
net/ipv4/inet_fragment.c | 6 +-
net/ipv4/ip_output.c | 4 +
net/ipv6/ip6_output.c | 2 +
net/nfc/digital_technology.c | 2 +
net/nfc/llcp_commands.c | 18 +-
net/nfc/llcp_core.c | 15 +-
net/nfc/nci/ntf.c | 6 +
net/nfc/nci/rsp.c | 1 +
net/packet/af_packet.c | 65 +++--
net/sched/sch_api.c | 9 +
net/x25/af_x25.c | 4 +-
net/x25/x25_timer.c | 25 +-
net/xfrm/xfrm_state.c | 4 +-
tools/lib/bpf/libbpf.c | 2 +
62 files changed, 909 insertions(+), 392 deletions(-)
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 01/57] Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 02/57] rndis_host: add overflow check in rndis_rx_fixup() Greg Kroah-Hartman
` (61 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ali Ahmet Memis,
Luiz Augusto von Dentz
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memis <ali@iusegentoo.com>
commit 43a556b2fd43f2df6dded59c2e26560a27874c24 upstream.
rfcomm_sock_recvmsg() completes a deferred setup by calling
rfcomm_dlc_accept() without holding any RFCOMM lock:
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
rfcomm_dlc_accept(d);
return 0;
}
and rfcomm_dlc_accept() dereferences the session on its first line:
struct sock *sk = d->session->sock->sk;
Every other path that touches d->session runs under rfcomm_mutex:
rfcomm_dlc_open(), rfcomm_dlc_close(), rfcomm_dlc_exists(),
rfcomm_dlc_send_rpn(), and the RFCOMM thread through
rfcomm_process_sessions(). rfcomm_connect_ind() is even documented as
"called under rfcomm_lock()". This call site is the only one that skips
it.
The RFCOMM_DEFER_SETUP bit looks like it serialises the accept against
teardown, since __rfcomm_dlc_close() returns early when it wins the
test_and_clear. But rfcomm_recv_disc() forces the state first:
d->state = BT_CLOSED;
__rfcomm_dlc_close(d, err);
and the early return only covers BT_CONNECT, BT_CONFIG, BT_OPEN and
BT_CONNECT2. With the state already BT_CLOSED that switch does not
match, the bit is never consulted, and __rfcomm_dlc_close() falls
through to rfcomm_dlc_unlink(), which sets d->session = NULL.
So a remote DISC on a deferred dlc clears the session while leaving
RFCOMM_DEFER_SETUP set. The next recvmsg() then passes the
test_and_clear and dereferences a NULL session. No timing window is
needed: once the DISC has been processed, the dereference is
unconditional.
Give rfcomm_dlc_accept() the same shape as rfcomm_dlc_open() and
rfcomm_dlc_close(): an exported wrapper that takes rfcomm_mutex and
re-checks the session, around a __rfcomm_dlc_accept() that the two
in-core callers, which already hold the mutex, keep using.
Reproduced on a KASAN + PROVE_LOCKING kernel with a BR/EDR peer emulated
over /dev/vhci: the peer brings up an ACL link, opens L2CAP on the
RFCOMM PSM, starts a session, opens a dlc on a channel bound with
BT_DEFER_SETUP, and sends DISC after the socket is accepted. recv() on
the accepted socket then hits:
Oops: general protection fault
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
RIP: 0010:rfcomm_dlc_accept+0x54/0x350
Call Trace:
rfcomm_sock_recvmsg+0x1cd/0x230
sock_recvmsg+0x166/0x1c0
__sys_recvfrom+0x20d/0x300
0x10 is the offset of sock in struct rfcomm_session. With this patch the
same run completes with recv() returning 0 and no report, and lockdep
stays quiet, confirming rfcomm_mutex is still taken before lock_sock on
this path as it is on the thread side.
Fixes: bb23c0ab8246 ("Bluetooth: Add support for deferring RFCOMM connection setup")
Cc: stable@vger.kernel.org
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bluetooth/rfcomm/core.c | 24 +++++++++++++++++++++---
1 file changed, 21 insertions(+), 3 deletions(-)
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1330,7 +1330,10 @@ static struct rfcomm_session *rfcomm_rec
return s;
}
-void rfcomm_dlc_accept(struct rfcomm_dlc *d)
+/* Must be called with rfcomm_mutex held, so that the session cannot be
+ * unlinked from under us.
+ */
+static void __rfcomm_dlc_accept(struct rfcomm_dlc *d)
{
struct sock *sk = d->session->sock->sk;
struct l2cap_conn *conn = l2cap_pi(sk)->chan->conn;
@@ -1352,6 +1355,21 @@ void rfcomm_dlc_accept(struct rfcomm_dlc
rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
}
+void rfcomm_dlc_accept(struct rfcomm_dlc *d)
+{
+ rfcomm_lock();
+
+ /* rfcomm_recv_disc() sets the dlc state to BT_CLOSED before calling
+ * __rfcomm_dlc_close(), so the RFCOMM_DEFER_SETUP handshake there is
+ * skipped and the session can already be unlinked by the time the
+ * deferred accept runs from rfcomm_sock_recvmsg().
+ */
+ if (d->session)
+ __rfcomm_dlc_accept(d);
+
+ rfcomm_unlock();
+}
+
static void rfcomm_check_accept(struct rfcomm_dlc *d)
{
if (rfcomm_check_security(d)) {
@@ -1364,7 +1382,7 @@ static void rfcomm_check_accept(struct r
d->state_change(d, 0);
rfcomm_dlc_unlock(d);
} else
- rfcomm_dlc_accept(d);
+ __rfcomm_dlc_accept(d);
} else {
set_bit(RFCOMM_AUTH_PENDING, &d->flags);
rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
@@ -1918,7 +1936,7 @@ static void rfcomm_process_dlcs(struct r
d->state_change(d, 0);
rfcomm_dlc_unlock(d);
} else
- rfcomm_dlc_accept(d);
+ __rfcomm_dlc_accept(d);
}
continue;
} else if (test_and_clear_bit(RFCOMM_AUTH_REJECT, &d->flags)) {
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 02/57] rndis_host: add overflow check in rndis_rx_fixup()
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 01/57] Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 03/57] ocfs2: fix missing metadata reservation for large xattrs Greg Kroah-Hartman
` (60 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrew Lunn, Shaoxu Liu,
Griffin Kroah-Hartman, Simon Horman, Jakub Kicinski
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Griffin Kroah-Hartman <griffin@kroah.com>
commit 965a251f23ff69cfb4486974d4532e9bb551c7fc upstream.
Add an overflow check to ensure that data_offset + data_len + 8 does not
wrap, which would enable an OOB read of the USB data buffer.
Cc: Andrew Lunn <andrew+netdev@lunn.ch>
Cc: Shaoxu Liu <shaoxul@foxmail.com>
Signed-off-by: Griffin Kroah-Hartman <griffin@kroah.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/2026070900-denim-brook-52d4@gregkh
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/usb/rndis_host.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -14,6 +14,7 @@
#include <linux/usb/cdc.h>
#include <linux/usb/usbnet.h>
#include <linux/usb/rndis_host.h>
+#include <linux/overflow.h>
/*
@@ -495,6 +496,7 @@ int rndis_rx_fixup(struct usbnet *dev, s
struct rndis_data_hdr *hdr = (void *)skb->data;
struct sk_buff *skb2;
u32 msg_type, msg_len, data_offset, data_len;
+ u32 overflow_check;
msg_type = le32_to_cpu(hdr->msg_type);
msg_len = le32_to_cpu(hdr->msg_len);
@@ -503,7 +505,9 @@ int rndis_rx_fixup(struct usbnet *dev, s
/* don't choke if we see oob, per-packet data, etc */
if (unlikely(msg_type != RNDIS_MSG_PACKET || skb->len < msg_len
- || (data_offset + data_len + 8) > msg_len)) {
+ || (data_offset + data_len + 8) > msg_len
+ || check_add_overflow(data_offset, data_len, &overflow_check)
+ || check_add_overflow(overflow_check, 8, &overflow_check))) {
dev->net->stats.rx_frame_errors++;
netdev_dbg(dev->net, "bad rndis message %d/%d/%d/%d, len %d\n",
le32_to_cpu(hdr->msg_type),
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 03/57] ocfs2: fix missing metadata reservation for large xattrs
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 01/57] Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 02/57] rndis_host: add overflow check in rndis_rx_fixup() Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 04/57] ext4: stop retrying saturated xattr cache entries Greg Kroah-Hartman
` (59 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ian Bridges,
syzbot+e538032956b1157914a3, Joseph Qi, Mark Fasheh, Joel Becker,
Junxiao Bi, Changwei Ge, Jun Piao, Heming Zhao, Andrew Morton
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Bridges <icb@fastmail.org>
commit 0cdc7dde00ec63ac714271fa8b2918d630b8da1a upstream.
[BUG]
lsetxattr() panics the kernel when setting a large xattr value on a
fragmented filesystem where the file already has an external xattr
block.
[CAUSE]
ocfs2_calc_xattr_set_need() never reserves metadata blocks for a new
xattr value's extent tree when the file already has an external xattr
block. The not_found path leaves meta_add at zero, so meta_ac is NULL
when ocfs2_xattr_extend_allocation() runs.
A new value root has room for a single extent record. On a fragmented
filesystem, the allocator cannot satisfy the xattr value in one
contiguous run, so each non-contiguous run requires its own extent
record. When the value root's extent list is full and meta_ac is NULL,
ocfs2_add_clusters_in_btree() returns RESTART_META, and
ocfs2_xattr_extend_allocation() hits BUG_ON(why == RESTART_META).
[FIX]
The case where no xattr block exists yet already calls
ocfs2_extend_meta_needed(&def_xv.xv.xr_list) to reserve value tree
metadata. Add the same reservation to the case where an xattr block
already exists, making the two cases consistent.
Replace the BUG_ON with a -ENOSPC return so that if RESTART_META is
returned despite the reservation, the error propagates to userspace
instead of panicking the kernel.
Link: https://lore.kernel.org/amLwn3i9tET8yhG7@dev
Fixes: a78f9f466894 ("ocfs2: make xattr extension work with new local alloc reservation.")
Signed-off-by: Ian Bridges <icb@fastmail.org>
Reported-by: syzbot+e538032956b1157914a3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e538032956b1157914a3
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ocfs2/xattr.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -742,12 +742,10 @@ static int ocfs2_xattr_extend_allocation
prev_clusters;
if (why != RESTART_NONE && clusters_to_add) {
- /*
- * We can only fail in case the alloc file doesn't give
- * up enough clusters.
- */
- BUG_ON(why == RESTART_META);
-
+ if (why == RESTART_META) {
+ status = -ENOSPC;
+ break;
+ }
credits = ocfs2_calc_extend_credits(inode->i_sb,
&vb->vb_xv->xr_list);
status = ocfs2_extend_trans(handle, credits);
@@ -3217,6 +3215,14 @@ meta_guess:
credits += OCFS2_SUBALLOC_ALLOC + 1;
/*
+ * Reserve metadata for the new xattr's value extent tree.
+ * The not_found path above adds credits for this tree but
+ * omits meta_add, leaving meta_ac NULL for large values.
+ */
+ if (xi->xi_value_len > OCFS2_XATTR_INLINE_SIZE)
+ meta_add += ocfs2_extend_meta_needed(&def_xv.xv.xr_list);
+
+ /*
* This cluster will be used either for new bucket or for
* new xattr block.
* If the cluster size is the same as the bucket size, one
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 04/57] ext4: stop retrying saturated xattr cache entries
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (2 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 03/57] ocfs2: fix missing metadata reservation for large xattrs Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 05/57] ext4: clear error before retrying inode xattr space fallback Greg Kroah-Hartman
` (58 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthias Goergens, Jan Kara,
syzbot+e68dbebd9617a9250e8d, Theodore Tso
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthias Goergens <matthias.goergens@gmail.com>
commit 54b6bd40898de7906acb2bccc9a96d1b8e6b4323 upstream.
ext4_xattr_block_set() retries when a cache entry selected for reuse
has a saturated reference count after taking the buffer lock. The retry
returns to the mbcache lookup without making that entry ineligible, so
it can select the same unusable entry indefinitely. A task spinning
there can hold the parent directory's i_rwsem and leave concurrent
rmdir callers blocked.
Normally a reusable entry has a reference count below
EXT4_XATTR_REFCOUNT_MAX because the count and MBE_REUSABLE_B are
updated under the same buffer lock. A corrupted filesystem can violate
that invariant. The syzbot reproducer reports allocator and xattr
corruption before triggering this retry loop.
Check the untrusted on-disk count before incrementing it, avoiding
overflow, and clear MBE_REUSABLE_B when it is already saturated. The
next lookup then skips the entry that was just proven unusable. This
mirrors the normal transition at EXT4_XATTR_REFCOUNT_MAX; the release
path marks the entry reusable again on the exact 1024-to-1023
transition.
Using the same QEMU harness and guest parameters, current unpatched
Linux hung in 6 of 8 420-second trials with the do_rmdir signature;
representative NMI backtraces caught the owner spinning in
ext4_xattr_block_set(). The patched kernel completed 28 of 28 trials
without a hung-task report; the final twelve trials exercised the
reviewed overflow-safe form of the change. syzbot's patch testing also
completed without reproducing the hang.
Reported-and-tested-by: syzbot+e68dbebd9617a9250e8d@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=e68dbebd9617a9250e8d
Fixes: 65f8b80053a1 ("ext4: fix race when reusing xattr blocks")
Cc: stable@vger.kernel.org
Signed-off-by: Matthias Goergens <matthias.goergens@gmail.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Reported-by: syzbot+e68dbebd9617a9250e8d@syzkaller.appspotmail.com
Tested-by: syzbot+e68dbebd9617a9250e8d@syzkaller.appspotmail.com
Link: https://patch.msgid.link/20260802065941.1726052-1-matthias.goergens@gmail.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ext4/xattr.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -2041,12 +2041,13 @@ inserted:
* stable so we can check the additional
* reference fits.
*/
- ref = le32_to_cpu(BHDR(new_bh)->h_refcount) + 1;
- if (ref > EXT4_XATTR_REFCOUNT_MAX) {
+ ref = le32_to_cpu(BHDR(new_bh)->h_refcount);
+ if (ref >= EXT4_XATTR_REFCOUNT_MAX) {
/*
* Undo everything and check mbcache
* again.
*/
+ clear_bit(MBE_REUSABLE_B, &ce->e_flags);
unlock_buffer(new_bh);
dquot_free_block(inode,
EXT4_C2B(EXT4_SB(sb),
@@ -2057,6 +2058,7 @@ inserted:
new_bh = NULL;
goto inserted;
}
+ ref++;
BHDR(new_bh)->h_refcount = cpu_to_le32(ref);
if (ref == EXT4_XATTR_REFCOUNT_MAX)
clear_bit(MBE_REUSABLE_B, &ce->e_flags);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 05/57] ext4: clear error before retrying inode xattr space fallback
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (3 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 04/57] ext4: stop retrying saturated xattr cache entries Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 06/57] xfs: validate attr entry pointer before field access Greg Kroah-Hartman
` (57 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guanghui Yang, Jan Kara,
Theodore Tso
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guanghui Yang <3497809730@qq.com>
commit 409a7f12a0933ff2c617fa814c76cef0bd1d457a upstream.
When ext4_xattr_make_inode_space() returns -ENOSPC,
ext4_expand_extra_isize_ea() can retry the expansion with
s_min_extra_isize. If that retry succeeds by finding enough ibody free
space, control jumps directly to the shift label.
The previous -ENOSPC is still stored in error in that path, so the
function can update i_extra_isize but still return -ENOSPC to the
caller. Clear error before retrying so a successful fallback expansion
returns success.
Reproduced with an ext4 image using 1 KiB blocks, project quota support,
256-byte inodes, and min_extra_isize/want_extra_isize set to 32.
FS_IOC_FSSETXATTR failures dropped from 802 to 86 after the fix.
Fixes: 69f3a3039b0d ("ext4: introduce ITAIL helper")
Cc: stable@vger.kernel.org
Signed-off-by: Guanghui Yang <3497809730@qq.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/tencent_192F8A699EFD21126E02101131C9546F3C08@qq.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ext4/xattr.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -2780,6 +2780,7 @@ retry:
s_min_extra_isize) {
tried_min_extra_isize++;
new_extra_isize = s_min_extra_isize;
+ error = 0;
goto retry;
}
goto cleanup;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 06/57] xfs: validate attr entry pointer before field access
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (4 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 05/57] ext4: clear error before retrying inode xattr space fallback Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 07/57] net/x25: fix use-after-free of the socket by its timers Greg Kroah-Hartman
` (56 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hongling Zeng, Darrick J. Wong,
Carlos Maiolino
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hongling Zeng <zenghongling@kylinos.cn>
commit b7eea80be25f3334f131d52982b3131aba77b97d upstream.
xfs_attr3_leaf_verify_entry() accesses lentry/rentry fields (namelen,
valuelen) before checking if the entry pointer itself is within bounds.
If nameidx is crafted to point near the end of the buffer, these field
accesses can read out-of-bounds before the bounds check at
name_end > buf_end is performed.
Add explicit bounds checks for entry pointers before accessing their
fields. Use offsetof() to check that the start of the flexible array
member (nameval/name) is within bounds, which ensures all preceding
fields are safe to access.
Fixes: c84760659dcf2 ("xfs: check attribute leaf block structure")
Cc: <stable@vger.kernel.org> # v5.5
Signed-off-by: Hongling Zeng <zenghongling@kylinos.cn>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_attr_leaf.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -265,6 +265,13 @@ xfs_attr3_leaf_verify_entry(
*/
if (ent->flags & XFS_ATTR_LOCAL) {
lentry = xfs_attr3_leaf_name_local(leaf, idx);
+
+ /* Validate lentry pointer is within bounds before field access */
+ if ((char *)lentry >= buf_end)
+ return __this_address;
+ if ((char *)lentry + offsetof(struct xfs_attr_leaf_name_local, nameval) > buf_end)
+ return __this_address;
+
namesize = xfs_attr_leaf_entsize_local(lentry->namelen,
be16_to_cpu(lentry->valuelen));
name_end = (char *)lentry + namesize;
@@ -272,6 +279,13 @@ xfs_attr3_leaf_verify_entry(
return __this_address;
} else {
rentry = xfs_attr3_leaf_name_remote(leaf, idx);
+
+ /* Validate rentry pointer is within bounds before field access */
+ if ((char *)rentry >= buf_end)
+ return __this_address;
+ if ((char *)rentry + offsetof(struct xfs_attr_leaf_name_remote, name) > buf_end)
+ return __this_address;
+
namesize = xfs_attr_leaf_entsize_remote(rentry->namelen);
name_end = (char *)rentry + namesize;
if (rentry->namelen == 0)
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 07/57] net/x25: fix use-after-free of the socket by its timers
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (5 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 06/57] xfs: validate attr entry pointer before field access Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 08/57] mm/huge_memory: fix huge_zero_pfn race Greg Kroah-Hartman
` (55 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Baul Lee, Jakub Kicinski,
Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baul Lee <baul.lee@xbow.com>
[ Upstream commit 2195424c3da2ef1829a63b807e3a900a90e57d85 ]
The x25 timers are armed with mod_timer() and cancelled with
timer_delete(), so a pending timer holds no reference on the socket and a
cancel does not wait for a callback already running on another CPU.
x25_heartbeat_expiry() also rearms unconditionally, so it can reinstall
sk->sk_timer after __x25_destroy_socket() has passed its cancel point.
The following __sock_put() frees the socket while the timer is still
queued, and the next expiry uses freed memory. KASAN reports a
slab-use-after-free on the kmalloc-2k object freed by close().
timer_delete_sync() cannot be used here: x25_heartbeat_expiry() and
x25_timer_expiry() both reach the cancels from inside the timer they
would wait on, through __x25_destroy_socket() and x25_disconnect().
Arm the timers with sk_reset_timer() and cancel them with sk_stop_timer()
so that an armed timer owns a reference, and release it in both expiry
handlers. Rearm the heartbeat only while sk_hashed(sk) is still true,
since __x25_destroy_socket() unlinks the socket before dropping it. Arm
the deferred destroy timer the same way and drop its reference in
x25_destroy_timer().
Reproduced on net with KASAN, with the heartbeat period shortened so the
window recurs. With this patch the reproducer no longer triggers a
report and /proc/net/x25 drains.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Baul Lee <baul.lee@xbow.com>
Link: https://patch.msgid.link/20260726220342.47245-1-baul.lee@xbow.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ adjusted context due to `del_timer()` not yet renamed to `timer_delete()` ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/x25/af_x25.c | 4 ++--
net/x25/x25_timer.c | 25 ++++++++++++++++---------
2 files changed, 18 insertions(+), 11 deletions(-)
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -372,6 +372,7 @@ static void x25_destroy_timer(struct tim
struct sock *sk = from_timer(sk, t, sk_timer);
x25_destroy_socket_from_timer(sk);
+ sock_put(sk);
}
/*
@@ -407,9 +408,8 @@ static void __x25_destroy_socket(struct
if (sk_has_allocations(sk)) {
/* Defer: outstanding buffers */
- sk->sk_timer.expires = jiffies + 10 * HZ;
sk->sk_timer.function = x25_destroy_timer;
- add_timer(&sk->sk_timer);
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + 10 * HZ);
} else {
/* drop last reference so sock_put will free */
__sock_put(sk);
--- a/net/x25/x25_timer.c
+++ b/net/x25/x25_timer.c
@@ -36,45 +36,45 @@ void x25_init_timers(struct sock *sk)
void x25_start_heartbeat(struct sock *sk)
{
- mod_timer(&sk->sk_timer, jiffies + 5 * HZ);
+ sk_reset_timer(sk, &sk->sk_timer, jiffies + 5 * HZ);
}
void x25_stop_heartbeat(struct sock *sk)
{
- del_timer(&sk->sk_timer);
+ sk_stop_timer(sk, &sk->sk_timer);
}
void x25_start_t2timer(struct sock *sk)
{
struct x25_sock *x25 = x25_sk(sk);
- mod_timer(&x25->timer, jiffies + x25->t2);
+ sk_reset_timer(sk, &x25->timer, jiffies + x25->t2);
}
void x25_start_t21timer(struct sock *sk)
{
struct x25_sock *x25 = x25_sk(sk);
- mod_timer(&x25->timer, jiffies + x25->t21);
+ sk_reset_timer(sk, &x25->timer, jiffies + x25->t21);
}
void x25_start_t22timer(struct sock *sk)
{
struct x25_sock *x25 = x25_sk(sk);
- mod_timer(&x25->timer, jiffies + x25->t22);
+ sk_reset_timer(sk, &x25->timer, jiffies + x25->t22);
}
void x25_start_t23timer(struct sock *sk)
{
struct x25_sock *x25 = x25_sk(sk);
- mod_timer(&x25->timer, jiffies + x25->t23);
+ sk_reset_timer(sk, &x25->timer, jiffies + x25->t23);
}
void x25_stop_timer(struct sock *sk)
{
- del_timer(&x25_sk(sk)->timer);
+ sk_stop_timer(sk, &x25_sk(sk)->timer);
}
unsigned long x25_display_timer(struct sock *sk)
@@ -108,7 +108,7 @@ static void x25_heartbeat_expiry(struct
sock_flag(sk, SOCK_DEAD))) {
bh_unlock_sock(sk);
x25_destroy_socket_from_timer(sk);
- return;
+ goto out;
}
break;
@@ -120,8 +120,14 @@ static void x25_heartbeat_expiry(struct
break;
}
restart_heartbeat:
- x25_start_heartbeat(sk);
+ /* Do not rearm once __x25_destroy_socket() has unlinked the socket:
+ * it is past its cancel point and owns the teardown from there on.
+ */
+ if (sk_hashed(sk))
+ x25_start_heartbeat(sk);
bh_unlock_sock(sk);
+out:
+ sock_put(sk);
}
/*
@@ -166,4 +172,5 @@ static void x25_timer_expiry(struct time
} else
x25_do_timer_expiry(sk);
bh_unlock_sock(sk);
+ sock_put(sk);
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 08/57] mm/huge_memory: fix huge_zero_pfn race
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (6 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 07/57] net/x25: fix use-after-free of the socket by its timers Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 09/57] staging: rtl8723bs: fix OOB read in WMM_param_handler() Greg Kroah-Hartman
` (54 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Hengbin Zhang,
David Hildenbrand (Arm), Baolin Wang, Barry Song, Dev Jain,
Hannes Reinecke, Hugh Dickins, Kiryl Shutsemau, Lance Yang,
Liam R. Howlett, Nico Pache, Pankaj Raghav, Ryan Roberts,
Yang Shi, Zi Yan, Andrew Morton, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
[ Upstream commit 33192a26cddea7a7e4ca66e5c3eebd36fa8be2bb ]
Patch series "mm/huge_memory: fix huge_zero_pfn race", v2.
There is a subtle race in the reference-counted huge_zero_folio
implementation.
The fast path atomic logic fails to account for the fact that the shrinker
(which drops the final huge_zero_refcount pin) can overwrite huge_zero_pfn
with the ~0UL sentinel value in shrink_huge_zero_folio_scan() after a
racing get_huge_zero_folio() installed a valid value there.
This results in huge_zero_folio being correctly set but huge_zero_pfn
being set incorrectly and thus is_huge_zero_pfn() and consequently
is_huge_zero_pmd() will misidentify the huge zero folio as being an
ordinary THP folio.
This can result in the huge zero folio being split and otherwise treated
incorrectly.
The solution to this is very subtle as there is an atomic fast path, and
thus ordering in weakly ordered architectures has to be treated very
carefully.
The first commit fixes the issue by introducing a spinlock around
huge_zero_[pfn, folio, refcount] write, with careful consideration paid to
load/store ordering in the fast path. It is placed first and kept as
small as possible so that it can be backported on its own.
The second commit is a pure cleanup which reworks the
CONFIG_PERSISTENT_HUGE_ZERO_FOLIO logic to better separate the persistent
logic from the dynamically allocated one.
This patch (of 2):
If !CONFIG_PERSISTENT_HUGE_ZERO_FOLIO, the huge_zero_folio is refcounted
by huge_zero_refcount and returned by mm_get_huge_zero_folio().
When the caller is done with the huge zero page, its reference count is
decremented. Only a shrinker can set the reference count to zero.
A race can unfortunately occur between a shrinker decrementing the
reference count to zero and a concurrent page fault.
This is because shrink_huge_zero_folio_scan() might, if very unlucky, be
preempted between setting huge_zero_refcount to zero and writing an
invalid value.
During this time get_huge_zero_folio() could write to huge_zero_pfn before
shrink_huge_zero_folio_scan() resumes.
In this event the huge zero folio will be persistently misidentified
causing the THP code path to be entered inappropriately for the huge zero
folio:
CPU 0 CPU 1
=======================================|=================================
shrink_huge_zero_folio_scan() |
atomic_cmpxchg() sets refcount to 0 |
xchg() sets huge_zero_folio to NULL | get_huge_zero_folio()
| | atomic_inc_not_zero() -> zero
preempted for a long time | Allocate new huge zero folio
| | Write valid huge_zero_folio
v | Write valid huge_zero_pfn
Overwrite huge_zero_pfn with ~0UL <--- Invalid overwrite!
This results in is_huge_zero_pfn() and is_huge_zero_pmd() incorrectly
returning false for a huge zero page which could result in issues like the
huge zero folio being incorrectly split.
Note that the issue is with huge_zero_pfn not huge_zero_folio, as
get_huge_zero_folio() uses cmpxchg() gated on huge_zero_folio being NULL
with a retry loop and shrink_huge_zero_folio_scan() uses xchg() to set
huge_zero_folio.
Fix the issue by introducing a spinlock, huge_zero_lock, to prevent
concurrent write of huge_zero_folio, huge_zero_pfn and huge_zero_refcount.
There needs to be significant care taken here to ensure correctness:
The fast path in get_huge_zero_folio() uses atomic_inc_not_zero(), which
is outside of the critical section, and means huge zero allocation is
gated on zero huge_zero_refcount.
The fast path doesn't use huge_zero_lock, so the critical section is
irrelevant to it.
So invariants are required - huge_zero_refcount MUST:
* Only be set in the huge_zero_lock critical section to ensure
serialisation of huge_zero_pfn, huge_zero_folio and huge_zero_refcount
writes.
* Be set non-zero only AFTER huge_zero_[pfn, folio] are set to valid values
so installation of the huge zero folio on read page fault ensures
concurrent is_huge_zero_*() calls correctly identify the huge zero folio.
* Be set zero only BEFORE huge_zero_[pfn, folio] are set to NULL and ~0UL
respectively, and atomically.
Establish these by:
* Only setting huge_zero_refcount to zero or an absolute value in the
huge_zero_lock critical section in get_huge_zero_folio() and
shrink_huge_zero_folio_scan(), and always updating atomically there
and elsewhere.
* Using atomic_set_release(&huge_zero_refcount) in get_huge_zero_folio()
after huge_zero_[pfn, folio] are set. This is paired with
atomic_inc_not_zero() to ensure atomic_inc_not_zero() only observes a
non-zero value if huge_zero_[pfn, folio] are set.
* Using atomic_cmpxchg() in shrink_huge_zero_folio_scan() (as before) to
ensure that it is set zero only when equal to 1 and set atomically.
* atomic_cmpxchg() being fully ordered ensures this is done prior to
huge_zero_[folio, pfn] being set to NULL and ~0UL respectively.
Eliminate the retry loop in get_huge_zero_folio() as the atomic_cmpxchg()
in shrink_huge_zero_folio_scan() is now performed under the lock, and
replace with an equally locked atomic_inc() to set the reference count
should the caller be raced on huge zero folio installation.
folio_put() naturally implies a full memory barrier so its ordering is
maintained correctly.
The huge zero folio also cannot be released except when the shrinker does
so as it is non-LRU and non-rmappable.
Note that only the huge zero shrinker (via shrink_huge_zero_folio_scan())
can actually set huge_zero_refcount to zero, which is the count of mm's
which have at least one huge zero folio installed plus one shrinker pin.
Additionally convert a BUG_ON() to a VM_WARN_ON_ONCE().
Link: https://lore.kernel.org/20260730-fix-refcounted-huge-zero-v2-0-c5d8a41b317f@kernel.org
Link: https://lore.kernel.org/20260730-fix-refcounted-huge-zero-v2-1-c5d8a41b317f@kernel.org
Fixes: 3b77e8c8cde5 ("mm/thp: make is_huge_zero_pmd() safe and quicker")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reported-by: Hengbin Zhang <uqbarz@gmail.com>
Closes: https://lore.kernel.org/linux-mm/20260727154001.4102341-1-uqbarz@gmail.com/
Suggested-by: David Hildenbrand (Arm) <david@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Hugh Dickins <hughd@google.com>
Cc: Kiryl Shutsemau <kas@kernel.org>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Nico Pache <npache@redhat.com>
Cc: Pankaj Raghav <p.raghav@samsung.com>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Yang Shi <shy828301@gmail.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
[ replaced scoped_guard() with explicit spin_lock()/spin_unlock() and returned the page pointer instead of bool due to 5.10's gnu89 and older get_huge_zero_page() signature ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
mm/huge_memory.c | 46 +++++++++++++++++++++++++++++++---------------
1 file changed, 31 insertions(+), 15 deletions(-)
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -60,6 +60,7 @@ unsigned long transparent_hugepage_flags
static struct shrinker deferred_split_shrinker;
static atomic_t huge_zero_refcount;
+static DEFINE_SPINLOCK(huge_zero_lock);
struct page *huge_zero_page __read_mostly;
unsigned long huge_zero_pfn __read_mostly = ~0UL;
@@ -90,7 +91,8 @@ bool transparent_hugepage_active(struct
static struct page *get_huge_zero_page(void)
{
struct page *zero_page;
-retry:
+
+ /* Paired with atomic_set_release(). */
if (likely(atomic_inc_not_zero(&huge_zero_refcount)))
return READ_ONCE(huge_zero_page);
@@ -101,17 +103,22 @@ retry:
return NULL;
}
count_vm_event(THP_ZERO_PAGE_ALLOC);
- preempt_disable();
- if (cmpxchg(&huge_zero_page, NULL, zero_page)) {
- preempt_enable();
+
+ /* Paired with critical section in shrink_huge_zero_page_scan(). */
+ spin_lock(&huge_zero_lock);
+ if (huge_zero_page) {
+ /* Somebody else already installed it. */
+ atomic_inc(&huge_zero_refcount);
+ spin_unlock(&huge_zero_lock);
__free_pages(zero_page, compound_order(zero_page));
- goto retry;
+ return READ_ONCE(huge_zero_page);
}
+ WRITE_ONCE(huge_zero_page, zero_page);
WRITE_ONCE(huge_zero_pfn, page_to_pfn(zero_page));
+ /* Paired with atomic_inc_not_zero(). +1 for shrinker pin. */
+ atomic_set_release(&huge_zero_refcount, 2);
+ spin_unlock(&huge_zero_lock);
- /* We take additional reference here. It will be put back by shrinker */
- atomic_set(&huge_zero_refcount, 2);
- preempt_enable();
return READ_ONCE(huge_zero_page);
}
@@ -154,15 +161,24 @@ static unsigned long shrink_huge_zero_pa
static unsigned long shrink_huge_zero_page_scan(struct shrinker *shrink,
struct shrink_control *sc)
{
- if (atomic_cmpxchg(&huge_zero_refcount, 1, 0) == 1) {
- struct page *zero_page = xchg(&huge_zero_page, NULL);
- BUG_ON(zero_page == NULL);
- WRITE_ONCE(huge_zero_pfn, ~0UL);
- __free_pages(zero_page, compound_order(zero_page));
- return HPAGE_PMD_NR;
+ struct page *zero_page;
+
+ /* Paired with critical section in get_huge_zero_page(). */
+ spin_lock(&huge_zero_lock);
+ /* Paired with atomic_inc_not_zero() in get_huge_zero_page(). */
+ if (atomic_cmpxchg(&huge_zero_refcount, 1, 0) != 1) {
+ spin_unlock(&huge_zero_lock);
+ return 0;
}
- return 0;
+ zero_page = huge_zero_page;
+ VM_WARN_ON_ONCE(!zero_page);
+ WRITE_ONCE(huge_zero_page, NULL);
+ WRITE_ONCE(huge_zero_pfn, ~0UL);
+ spin_unlock(&huge_zero_lock);
+
+ __free_pages(zero_page, compound_order(zero_page));
+ return HPAGE_PMD_NR;
}
static struct shrinker huge_zero_page_shrinker = {
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 09/57] staging: rtl8723bs: fix OOB read in WMM_param_handler()
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (7 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 08/57] mm/huge_memory: fix huge_zero_pfn race Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 10/57] misc: fastrpc: separate fastrpc device from channel context Greg Kroah-Hartman
` (53 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Muhammad Bilal, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Bilal <meatuni001@gmail.com>
[ Upstream commit ae21407350151bddfd4fea7aa39bd0643c0ca9d3 ]
WMM_param_handler() copies a fixed-size WMM parameter element out of a
received information element without checking that the element is long
enough, causing an out-of-bounds read for a short WMM IE.
The handler reads sizeof(struct WMM_para_element) (18) bytes at
pIE->data + 6, so it requires pIE->length to be at least 24
(WLAN_WMM_LEN), but it never validates the length. Two of its three
callers reach it after matching only the WMM OUI: OnAssocRsp() in
rtw_mlme_ext.c matches a 6-byte OUI, and join_cmd_hdl() matches a
4-byte OUI, before calling the handler. A vendor-specific IE carrying
the WMM OUI but a length between 6 and 23, placed in an association
response or in the IE blob handed to join_cmd_hdl(), passes the OUI
check and then makes the memcmp() and memcpy() at pIE->data + 6 read
past the end of the element. OnAssocRsp() parses a frame received from
the AP, so this is reachable from a remote peer.
The remaining caller in rtw_wlan_util.c already guards the handler with
"pIE->length == WLAN_WMM_LEN". Move the equivalent check into the
handler itself so every caller is covered; the sibling IE handlers in
the same parsing loop (HT_caps_handler(), HT_info_handler(),
ERP_IE_handler()) likewise bound their accesses by pIE->length.
Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Link: https://patch.msgid.link/20260719041509.97894-1-meatuni001@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ changed `pIE->length` to `pIE->Length` due to pre-5.15 CamelCase field name in `struct ndis_80211_var_ie` ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/staging/rtl8723bs/core/rtw_wlan_util.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8723bs/core/rtw_wlan_util.c
@@ -771,6 +771,9 @@ int WMM_param_handler(struct adapter *pa
return false;
}
+ if (pIE->Length != WLAN_WMM_LEN)
+ return false;
+
if (!memcmp(&(pmlmeinfo->WMM_param), (pIE->data + 6), sizeof(struct WMM_para_element)))
return false;
else
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 10/57] misc: fastrpc: separate fastrpc device from channel context
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (8 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 09/57] staging: rtl8723bs: fix OOB read in WMM_param_handler() Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 11/57] misc: fastrpc: Rework fastrpc_req_munmap Greg Kroah-Hartman
` (52 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Srinivas Kandagatla, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
[ Upstream commit 965602eabb57d086466ad749e81941e3dd66b595 ]
Currently fastrpc misc device instance is within channel context struct
with a kref. So we have 2 structs with refcount, both of them managing the
same channel context structure.
Separate fastrpc device from channel context and by adding a dedicated
fastrpc_device structure, this should clean the structures a bit and also help
when adding secure device node support.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20220214161002.6831-2-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 6102ceb4eab8 ("misc: fastrpc: Remove buffer from list prior to unmap operation")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/misc/fastrpc.c | 46 +++++++++++++++++++++++++++++++++++++---------
1 file changed, 37 insertions(+), 9 deletions(-)
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -78,7 +78,7 @@
#define USER_PD (1)
#define SENSORS_PD (2)
-#define miscdev_to_cctx(d) container_of(d, struct fastrpc_channel_ctx, miscdev)
+#define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev)
static const char *domains[FASTRPC_DEV_MAX] = { "adsp", "mdsp",
"sdsp", "cdsp"};
@@ -212,9 +212,14 @@ struct fastrpc_channel_ctx {
spinlock_t lock;
struct idr ctx_idr;
struct list_head users;
- struct miscdevice miscdev;
struct kref refcount;
u64 dma_mask;
+ struct fastrpc_device *fdevice;
+};
+
+struct fastrpc_device {
+ struct fastrpc_channel_ctx *cctx;
+ struct miscdevice miscdev;
};
struct fastrpc_user {
@@ -1248,10 +1253,14 @@ static int fastrpc_device_release(struct
static int fastrpc_device_open(struct inode *inode, struct file *filp)
{
- struct fastrpc_channel_ctx *cctx = miscdev_to_cctx(filp->private_data);
+ struct fastrpc_channel_ctx *cctx;
+ struct fastrpc_device *fdevice;
struct fastrpc_user *fl = NULL;
unsigned long flags;
+ fdevice = miscdev_to_fdevice(filp->private_data);
+ cctx = fdevice->cctx;
+
fl = kzalloc(sizeof(*fl), GFP_KERNEL);
if (!fl)
return -ENOMEM;
@@ -1649,6 +1658,27 @@ static struct platform_driver fastrpc_cb
},
};
+static int fastrpc_device_register(struct device *dev, struct fastrpc_channel_ctx *cctx,
+ const char *domain)
+{
+ struct fastrpc_device *fdev;
+ int err;
+
+ fdev = devm_kzalloc(dev, sizeof(*fdev), GFP_KERNEL);
+ if (!fdev)
+ return -ENOMEM;
+
+ fdev->cctx = cctx;
+ fdev->miscdev.minor = MISC_DYNAMIC_MINOR;
+ fdev->miscdev.fops = &fastrpc_fops;
+ fdev->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "fastrpc-%s", domain);
+ err = misc_register(&fdev->miscdev);
+ if (!err)
+ cctx->fdevice = fdev;
+
+ return err;
+}
+
static int fastrpc_rpmsg_probe(struct rpmsg_device *rpdev)
{
struct device *rdev = &rpdev->dev;
@@ -1678,11 +1708,7 @@ static int fastrpc_rpmsg_probe(struct rp
if (!data)
return -ENOMEM;
- data->miscdev.minor = MISC_DYNAMIC_MINOR;
- data->miscdev.name = devm_kasprintf(rdev, GFP_KERNEL, "fastrpc-%s",
- domains[domain_id]);
- data->miscdev.fops = &fastrpc_fops;
- err = misc_register(&data->miscdev);
+ err = fastrpc_device_register(rdev, data, domains[domain_id]);
if (err) {
kfree(data);
return err;
@@ -1727,7 +1753,9 @@ static void fastrpc_rpmsg_remove(struct
fastrpc_notify_users(user);
spin_unlock_irqrestore(&cctx->lock, flags);
- misc_deregister(&cctx->miscdev);
+ if (cctx->fdevice)
+ misc_deregister(&cctx->fdevice->miscdev);
+
of_platform_depopulate(&rpdev->dev);
fastrpc_channel_ctx_put(cctx);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 11/57] misc: fastrpc: Rework fastrpc_req_munmap
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (9 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 10/57] misc: fastrpc: separate fastrpc device from channel context Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 12/57] misc: fastrpc: Remove buffer from list prior to unmap operation Greg Kroah-Hartman
` (51 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Abel Vesa, Srinivas Kandagatla,
Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abel Vesa <abel.vesa@linaro.org>
[ Upstream commit 72fa6f7820c4cf96c5f7aabc4e54bdf52d1e2ac2 ]
Move the lookup of the munmap request to the fastrpc_req_munmap and pass
on only the buf to the lower level fastrpc_req_munmap_impl. That way
we can use the lower level fastrpc_req_munmap_impl on error path in
fastrpc_req_mmap to free the buf without searching for the munmap
request it belongs to.
Co-developed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20221125071405.148786-7-srinivas.kandagatla@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 6102ceb4eab8 ("misc: fastrpc: Remove buffer from list prior to unmap operation")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/misc/fastrpc.c | 52 +++++++++++++++++++++++--------------------------
1 file changed, 25 insertions(+), 27 deletions(-)
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1387,30 +1387,14 @@ static int fastrpc_invoke(struct fastrpc
return err;
}
-static int fastrpc_req_munmap_impl(struct fastrpc_user *fl,
- struct fastrpc_req_munmap *req)
+static int fastrpc_req_munmap_impl(struct fastrpc_user *fl, struct fastrpc_buf *buf)
{
struct fastrpc_invoke_args args[1] = { [0] = { 0 } };
- struct fastrpc_buf *buf = NULL, *iter, *b;
struct fastrpc_munmap_req_msg req_msg;
struct device *dev = fl->sctx->dev;
int err;
u32 sc;
- spin_lock(&fl->lock);
- list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
- if ((iter->raddr == req->vaddrout) && (iter->size == req->size)) {
- buf = iter;
- break;
- }
- }
- spin_unlock(&fl->lock);
-
- if (!buf) {
- dev_err(dev, "mmap not in list\n");
- return -EINVAL;
- }
-
req_msg.pgid = fl->tgid;
req_msg.size = buf->size;
req_msg.vaddr = buf->raddr;
@@ -1436,12 +1420,29 @@ static int fastrpc_req_munmap_impl(struc
static int fastrpc_req_munmap(struct fastrpc_user *fl, char __user *argp)
{
+ struct fastrpc_buf *buf = NULL, *iter, *b;
struct fastrpc_req_munmap req;
+ struct device *dev = fl->sctx->dev;
if (copy_from_user(&req, argp, sizeof(req)))
return -EFAULT;
- return fastrpc_req_munmap_impl(fl, &req);
+ spin_lock(&fl->lock);
+ list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
+ if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
+ buf = iter;
+ break;
+ }
+ }
+ spin_unlock(&fl->lock);
+
+ if (!buf) {
+ dev_err(dev, "mmap\t\tpt 0x%09llx [len 0x%08llx] not in list\n",
+ req.vaddrout, req.size);
+ return -EINVAL;
+ }
+
+ return fastrpc_req_munmap_impl(fl, buf);
}
static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
@@ -1450,7 +1451,6 @@ static int fastrpc_req_mmap(struct fastr
struct fastrpc_buf *buf = NULL;
struct fastrpc_mmap_req_msg req_msg;
struct fastrpc_mmap_rsp_msg rsp_msg;
- struct fastrpc_req_munmap req_unmap;
struct fastrpc_phy_page pages;
struct fastrpc_req_mmap req;
struct device *dev = fl->sctx->dev;
@@ -1498,7 +1498,8 @@ static int fastrpc_req_mmap(struct fastr
&args[0]);
if (err) {
dev_err(dev, "mmap error (len 0x%08llx)\n", buf->size);
- goto err_invoke;
+ fastrpc_buf_free(buf);
+ return err;
}
/* update the buffer to be able to deallocate the memory on the DSP */
@@ -1512,11 +1513,8 @@ static int fastrpc_req_mmap(struct fastr
spin_unlock(&fl->lock);
if (copy_to_user((void __user *)argp, &req, sizeof(req))) {
- /* unmap the memory and release the buffer */
- req_unmap.vaddrout = buf->raddr;
- req_unmap.size = buf->size;
- fastrpc_req_munmap_impl(fl, &req_unmap);
- return -EFAULT;
+ err = -EFAULT;
+ goto err_assign;
}
dev_dbg(dev, "mmap\t\tpt 0x%09lx OK [len 0x%08llx]\n",
@@ -1524,8 +1522,8 @@ static int fastrpc_req_mmap(struct fastr
return 0;
-err_invoke:
- fastrpc_buf_free(buf);
+err_assign:
+ fastrpc_req_munmap_impl(fl, buf);
return err;
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 12/57] misc: fastrpc: Remove buffer from list prior to unmap operation
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (10 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 11/57] misc: fastrpc: Rework fastrpc_req_munmap Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 13/57] net: ipv4: Publish fib_nlmsg_size() Greg Kroah-Hartman
` (50 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Dmitry Baryshkov,
Ekansh Gupta, Jianping Li, Srinivas Kandagatla, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
[ Upstream commit 6102ceb4eab845743ee57acd3863fbd06e93c927 ]
fastrpc_req_munmap_impl() is called to unmap any buffer. The buffer is
getting removed from the list after it is unmapped from DSP. This can
create potential race conditions if multiple threads invoke unmap
concurrently, where one thread may remove the entry from the list while
another thread's unmap operation is still ongoing.
Fix this by removing the buffer entry from the list before calling the
unmap operation. If the unmap fails, the entry is re-added to the list
so that userspace can retry the unmap, or alternatively, the buffer
will be cleaned up during device release when the DSP process is torn
down and all DSP-side mappings are freed along with remaining buffers
in the list.
Fixes: 2419e55e532de ("misc: fastrpc: add mmap/unmap support")
Cc: stable@kernel.org
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Jianping Li <jianping.li@oss.qualcomm.com>
Signed-off-by: Srinivas Kandagatla <srini@kernel.org>
Link: https://patch.msgid.link/20260724223342.629168-3-srini@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/misc/fastrpc.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -1407,9 +1407,6 @@ static int fastrpc_req_munmap_impl(struc
&args[0]);
if (!err) {
dev_dbg(dev, "unmmap\tpt 0x%09lx OK\n", buf->raddr);
- spin_lock(&fl->lock);
- list_del(&buf->node);
- spin_unlock(&fl->lock);
fastrpc_buf_free(buf);
} else {
dev_err(dev, "unmmap\tpt 0x%09lx ERROR\n", buf->raddr);
@@ -1423,6 +1420,7 @@ static int fastrpc_req_munmap(struct fas
struct fastrpc_buf *buf = NULL, *iter, *b;
struct fastrpc_req_munmap req;
struct device *dev = fl->sctx->dev;
+ int err;
if (copy_from_user(&req, argp, sizeof(req)))
return -EFAULT;
@@ -1430,6 +1428,7 @@ static int fastrpc_req_munmap(struct fas
spin_lock(&fl->lock);
list_for_each_entry_safe(iter, b, &fl->mmaps, node) {
if ((iter->raddr == req.vaddrout) && (iter->size == req.size)) {
+ list_del(&iter->node);
buf = iter;
break;
}
@@ -1442,7 +1441,14 @@ static int fastrpc_req_munmap(struct fas
return -EINVAL;
}
- return fastrpc_req_munmap_impl(fl, buf);
+ err = fastrpc_req_munmap_impl(fl, buf);
+ if (err) {
+ spin_lock(&fl->lock);
+ list_add_tail(&buf->node, &fl->mmaps);
+ spin_unlock(&fl->lock);
+ }
+
+ return err;
}
static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 13/57] net: ipv4: Publish fib_nlmsg_size()
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (11 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 12/57] misc: fastrpc: Remove buffer from list prior to unmap operation Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 14/57] ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops Greg Kroah-Hartman
` (49 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amit Cohen, Ido Schimmel,
David Ahern, Jakub Kicinski, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Cohen <amcohen@nvidia.com>
[ Upstream commit 1e7bdec6bbc7816cdc6a093374f4bf4e732c3d44 ]
Publish fib_nlmsg_size() to allow it to be used later on from
fib_alias_hw_flags_set().
Remove the inline keyword since it shouldn't be used inside C files.
Signed-off-by: Amit Cohen <amcohen@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 4ff9548d8494 ("ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/fib_lookup.h | 1 +
net/ipv4/fib_semantics.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -44,6 +44,7 @@ int fib_dump_info(struct sk_buff *skb, u
struct fib_rt_info *fri, unsigned int flags);
void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, int dst_len,
u32 tb_id, const struct nl_info *info, unsigned int nlm_flags);
+size_t fib_nlmsg_size(struct fib_info *fi);
static inline void fib_result_assign(struct fib_result *res,
struct fib_info *fi)
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -460,7 +460,7 @@ int ip_fib_check_default(__be32 gw, stru
return -1;
}
-static inline size_t fib_nlmsg_size(struct fib_info *fi)
+size_t fib_nlmsg_size(struct fib_info *fi)
{
size_t payload = NLMSG_ALIGN(sizeof(struct rtmsg))
+ nla_total_size(4) /* RTA_TABLE */
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 14/57] ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (12 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 13/57] net: ipv4: Publish fib_nlmsg_size() Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 15/57] NTB: ntb_netdev: Preserve RX queue depth on allocation failure Greg Kroah-Hartman
` (48 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zihan Xi, Ido Schimmel,
Jakub Kicinski, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
[ Upstream commit 4ff9548d84945d2cbf9e4c207288063a200ea397 ]
fib_nlmsg_size() still estimates nexthop space as if every gateway is
encoded as an IPv4 RTA_GATEWAY attribute. IPv4 routes can also carry an
IPv6 gateway, which fib_nexthop_info() dumps as RTA_VIA.
As a result, route notifications can allocate an skb that is too small.
fib_dump_info() then fails with -EMSGSIZE and rtmsg_fib() hits the
WARN_ON() that marks such failures as a fib_nlmsg_size() bug. With
panic_on_warn set, this becomes a kernel panic.
Mirror the actual nexthop dump layout in fib_nlmsg_size(): account for
IPv6 nexthop gateways dumped as RTA_VIA, for the no-header rtnexthop
layout used inside RTA_MULTIPATH, and for RTA_FLOW only when it is
actually present.
Fixes: d15662682db2 ("ipv4: Allow ipv6 gateway with ipv4 routes")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/6f53fa797fcaeb26966432ed7ae9bb87c4961f37.1785411220.git.zihanx@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/fib_semantics.c | 67 ++++++++++++++++++++++++++++++++++-------------
1 file changed, 49 insertions(+), 18 deletions(-)
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -460,6 +460,34 @@ int ip_fib_check_default(__be32 gw, stru
return -1;
}
+static size_t fib_nexthop_nlmsg_size(const struct fib_nh_common *nhc,
+ bool skip_oif)
+{
+ size_t nhsize = 0;
+
+ switch (nhc->nhc_gw_family) {
+ case AF_INET:
+ nhsize += nla_total_size(4); /* RTA_GATEWAY */
+ break;
+ case AF_INET6:
+ nhsize += nla_total_size(sizeof(struct rtvia) +
+ sizeof(struct in6_addr));
+ break;
+ }
+
+ if (!skip_oif && nhc->nhc_dev)
+ nhsize += nla_total_size(4); /* RTA_OIF */
+
+ if (nhc->nhc_lwtstate) {
+ /* RTA_ENCAP */
+ nhsize += lwtunnel_get_encap_size(nhc->nhc_lwtstate);
+ /* RTA_ENCAP_TYPE */
+ nhsize += nla_total_size(2);
+ }
+
+ return nhsize;
+}
+
size_t fib_nlmsg_size(struct fib_info *fi)
{
size_t payload = NLMSG_ALIGN(sizeof(struct rtmsg))
@@ -477,32 +505,35 @@ size_t fib_nlmsg_size(struct fib_info *f
payload += nla_total_size(4); /* RTA_NH_ID */
if (nhs) {
- size_t nh_encapsize = 0;
- /* Also handles the special case nhs == 1 */
-
- /* each nexthop is packed in an attribute */
- size_t nhsize = nla_total_size(sizeof(struct rtnexthop));
+ size_t mpsize = 0;
unsigned int i;
- /* may contain flow and gateway attribute */
- nhsize += 2 * nla_total_size(4);
-
- /* grab encap info */
for (i = 0; i < fib_info_num_path(fi); i++) {
struct fib_nh_common *nhc = fib_info_nhc(fi, i);
+ size_t nhsize;
+
+ nhsize = fib_nexthop_nlmsg_size(nhc, nhs != 1);
- if (nhc->nhc_lwtstate) {
- /* RTA_ENCAP_TYPE */
- nh_encapsize += lwtunnel_get_encap_size(
- nhc->nhc_lwtstate);
- /* RTA_ENCAP */
- nh_encapsize += nla_total_size(2);
+ if (nhs != 1)
+ nhsize += NLA_ALIGN(sizeof(struct rtnexthop));
+
+#ifdef CONFIG_IP_ROUTE_CLASSID
+ if (nhc->nhc_family == AF_INET) {
+ struct fib_nh *nh;
+
+ nh = container_of(nhc, struct fib_nh, nh_common);
+ if (nh->nh_tclassid)
+ nhsize += nla_total_size(4);
}
+#endif
+ if (nhs == 1)
+ payload += nhsize;
+ else
+ mpsize += nhsize;
}
- /* all nexthops are packed in a nested attribute */
- payload += nla_total_size((nhs * nhsize) + nh_encapsize);
-
+ if (nhs != 1)
+ payload += nla_total_size(mpsize);
}
return payload;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 15/57] NTB: ntb_netdev: Preserve RX queue depth on allocation failure
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (13 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 14/57] ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 16/57] serial: amba-pl011: synchronize DMA teardown Greg Kroah-Hartman
` (47 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Koichiro Den, Dave Jiang,
Paolo Abeni, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Koichiro Den <den@valinux.co.jp>
[ Upstream commit d2121faf133ac3bf9531b53a7e21273649a08517 ]
ntb_netdev_rx_handler() hands the received skb to the network stack
before allocating its replacement. If the allocation fails, nothing is
reposted. Every failure therefore takes one buffer out of the RX queue
while the interface remains up, and enough failures eventually stall
reception.
A retry path could refill the queue later, but ntb_netdev has none.
Allocate the replacement first instead. If that fails, drop the packet
and repost the same skb. This keeps the queue full and lets packet
delivery resume as soon as memory is available again.
Fixes: 548c237c0a99 ("net: Add support for NTB virtual ethernet device")
Cc: stable@vger.kernel.org
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://patch.msgid.link/20260806032537.3526498-1-den@valinux.co.jp
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
[ kept HEAD's `struct net_device *ndev = qp_data;` declaration instead of the per-queue context variables, adding only `new_skb` to the existing `skb` declaration ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ntb_netdev.c | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
--- a/drivers/net/ntb_netdev.c
+++ b/drivers/net/ntb_netdev.c
@@ -100,7 +100,7 @@ static void ntb_netdev_rx_handler(struct
void *data, int len)
{
struct net_device *ndev = qp_data;
- struct sk_buff *skb;
+ struct sk_buff *skb, *new_skb;
int rc;
skb = data;
@@ -115,6 +115,12 @@ static void ntb_netdev_rx_handler(struct
goto enqueue_again;
}
+ new_skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN);
+ if (!new_skb) {
+ ndev->stats.rx_dropped++;
+ goto enqueue_again;
+ }
+
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, ndev);
skb->ip_summed = CHECKSUM_NONE;
@@ -127,12 +133,7 @@ static void ntb_netdev_rx_handler(struct
ndev->stats.rx_bytes += len;
}
- skb = netdev_alloc_skb(ndev, ndev->mtu + ETH_HLEN);
- if (!skb) {
- ndev->stats.rx_errors++;
- ndev->stats.rx_frame_errors++;
- return;
- }
+ skb = new_skb;
enqueue_again:
rc = ntb_transport_rx_enqueue(qp, skb, skb->data, ndev->mtu + ETH_HLEN);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 16/57] serial: amba-pl011: synchronize DMA teardown
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (14 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 15/57] NTB: ntb_netdev: Preserve RX queue depth on allocation failure Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 17/57] perf: Fix cgroup state vs ERROR Greg Kroah-Hartman
` (46 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Fan Wu, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit 440915499231e9db1c361aa45bb702e8fd3b4a32 ]
dmaengine_terminate_all() does not wait for a running callback, so the TX
callback can still touch the TX buffer after it is freed. The RX poll
timer reads the RX buffers without the port lock.
Switch to dmaengine_terminate_sync() and delete the RX timer before
freeing the buffers.
Fixes: ead76f329f77 ("ARM: 6763/1: pl011: add optional RX DMA to PL011 v2")
Cc: stable <stable@kernel.org>
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260731085915.326775-4-fanwu01@zju.edu.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ changed upstream's `timer_delete_sync()` deletion to match this tree's `del_timer_sync()` spelling at the old call site ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/tty/serial/amba-pl011.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -1196,7 +1196,7 @@ static void pl011_dma_shutdown(struct ua
if (uap->using_tx_dma) {
/* In theory, this should already be done by pl011_dma_flush_buffer */
- dmaengine_terminate_all(uap->dmatx.chan);
+ dmaengine_terminate_sync(uap->dmatx.chan);
if (uap->dmatx.queued) {
dma_unmap_single(uap->dmatx.chan->device->dev,
uap->dmatx.dma, uap->dmatx.len,
@@ -1209,12 +1209,12 @@ static void pl011_dma_shutdown(struct ua
}
if (uap->using_rx_dma) {
- dmaengine_terminate_all(uap->dmarx.chan);
+ if (uap->dmarx.poll_rate)
+ timer_delete_sync(&uap->dmarx.timer);
+ dmaengine_terminate_sync(uap->dmarx.chan);
/* Clean up the RX DMA */
pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_a, DMA_FROM_DEVICE);
pl011_dmabuf_free(uap->dmarx.chan, &uap->dmarx.dbuf_b, DMA_FROM_DEVICE);
- if (uap->dmarx.poll_rate)
- del_timer_sync(&uap->dmarx.timer);
uap->using_rx_dma = false;
}
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 17/57] perf: Fix cgroup state vs ERROR
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (15 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 16/57] serial: amba-pl011: synchronize DMA teardown Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 18/57] perf: Fix dangling cgroup pointer in cpuctx Greg Kroah-Hartman
` (45 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Leo Yan, Peter Zijlstra (Intel),
Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <peterz@infradead.org>
[ Upstream commit 61988e36dc5457cdff7ae7927e8d9ad1419ee998 ]
While chasing down a missing perf_cgroup_event_disable() elsewhere,
Leo Yan found that both perf_put_aux_event() and
perf_remove_sibling_event() were also missing one.
Specifically, the rule is that events that switch to OFF,ERROR need to
call perf_cgroup_event_disable().
Unify the disable paths to ensure this.
Fixes: ab43762ef010 ("perf: Allow normal events to output AUX data")
Fixes: 9f0c4fa111dc ("perf/core: Add a new PERF_EV_CAP_SIBLING event capability")
Reported-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20250605123343.GD35970@noisy.programming.kicks-ass.net
Stable-dep-of: 42c5ca1f0a28 ("perf/core: Fix group leader use-after-free after sibling detach")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/events/core.c | 56 +++++++++++++++++++++++++++------------------------
1 file changed, 30 insertions(+), 26 deletions(-)
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -2145,14 +2145,13 @@ perf_aux_output_match(struct perf_event
}
static void put_event(struct perf_event *event);
-static void event_sched_out(struct perf_event *event,
- struct perf_cpu_context *cpuctx,
- struct perf_event_context *ctx);
+static void __event_disable(struct perf_event *event,
+ struct perf_event_context *ctx,
+ enum perf_event_state state);
static void perf_put_aux_event(struct perf_event *event)
{
struct perf_event_context *ctx = event->ctx;
- struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
struct perf_event *iter;
/*
@@ -2181,8 +2180,7 @@ static void perf_put_aux_event(struct pe
* state so that we don't try to schedule it again. Note
* that perf_event_enable() will clear the ERROR status.
*/
- event_sched_out(iter, cpuctx, ctx);
- perf_event_set_state(event, PERF_EVENT_STATE_ERROR);
+ __event_disable(iter, ctx, PERF_EVENT_STATE_ERROR);
}
}
@@ -2236,21 +2234,6 @@ static inline struct list_head *get_even
return event->attr.pinned ? &ctx->pinned_active : &ctx->flexible_active;
}
-/*
- * Events that have PERF_EV_CAP_SIBLING require being part of a group and
- * cannot exist on their own, schedule them out and move them into the ERROR
- * state. Also see _perf_event_enable(), it will not be able to recover
- * this ERROR state.
- */
-static inline void perf_remove_sibling_event(struct perf_event *event)
-{
- struct perf_event_context *ctx = event->ctx;
- struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
-
- event_sched_out(event, cpuctx, ctx);
- perf_event_set_state(event, PERF_EVENT_STATE_ERROR);
-}
-
static void perf_group_detach(struct perf_event *event)
{
struct perf_event *leader = event->group_leader;
@@ -2286,8 +2269,15 @@ static void perf_group_detach(struct per
*/
list_for_each_entry_safe(sibling, tmp, &event->sibling_list, sibling_list) {
+ /*
+ * Events that have PERF_EV_CAP_SIBLING require being part of
+ * a group and cannot exist on their own, schedule them out
+ * and move them into the ERROR state. Also see
+ * _perf_event_enable(), it will not be able to recover this
+ * ERROR state.
+ */
if (sibling->event_caps & PERF_EV_CAP_SIBLING)
- perf_remove_sibling_event(sibling);
+ __event_disable(sibling, ctx, PERF_EVENT_STATE_ERROR);
sibling->group_leader = sibling;
list_del_init(&sibling->sibling_list);
@@ -2494,6 +2484,15 @@ static void perf_remove_from_context(str
}
}
+static void __event_disable(struct perf_event *event,
+ struct perf_event_context *ctx,
+ enum perf_event_state state)
+{
+ event_sched_out(event, __get_cpu_context(ctx), ctx);
+ perf_cgroup_event_disable(event, ctx);
+ perf_event_set_state(event, state);
+}
+
/*
* Cross CPU call to disable a performance event
*/
@@ -2510,13 +2509,18 @@ static void __perf_event_disable(struct
update_cgrp_time_from_event(event);
}
+ /*
+ * When disabling a group leader, the whole group becomes ineligible
+ * to run, so schedule out the full group.
+ */
if (event == event->group_leader)
group_sched_out(event, cpuctx, ctx);
- else
- event_sched_out(event, cpuctx, ctx);
- perf_event_set_state(event, PERF_EVENT_STATE_OFF);
- perf_cgroup_event_disable(event, ctx);
+ /*
+ * But only mark the leader OFF; the siblings will remain
+ * INACTIVE.
+ */
+ __event_disable(event, ctx, PERF_EVENT_STATE_OFF);
}
/*
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 18/57] perf: Fix dangling cgroup pointer in cpuctx
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (16 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 17/57] perf: Fix cgroup state vs ERROR Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 19/57] perf/core: Fix group leader use-after-free after sibling detach Greg Kroah-Hartman
` (44 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yeoreum Yun, Peter Zijlstra (Intel),
David Wang, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yeoreum Yun <yeoreum.yun@arm.com>
[ Upstream commit 3b7a34aebbdf2a4b7295205bf0c654294283ec82 ]
Commit a3c3c6667("perf/core: Fix child_total_time_enabled accounting
bug at task exit") moves the event->state update to before
list_del_event(). This makes the event->state test in list_del_event()
always false; never calling perf_cgroup_event_disable().
As a result, cpuctx->cgrp won't be cleared properly; causing havoc.
Fixes: a3c3c6667("perf/core: Fix child_total_time_enabled accounting bug at task exit")
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Tested-by: David Wang <00107082@163.com>
Link: https://lore.kernel.org/all/aD2TspKH%2F7yvfYoO@e129823.arm.com/
Stable-dep-of: 42c5ca1f0a28 ("perf/core: Fix group leader use-after-free after sibling detach")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/events/core.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -2117,18 +2117,6 @@ list_del_event(struct perf_event *event,
if (event->group_leader == event)
del_event_from_groups(event, ctx);
- /*
- * If event was in error state, then keep it
- * that way, otherwise bogus counts will be
- * returned on read(). The only way to get out
- * of error state is by explicit re-enabling
- * of the event
- */
- if (event->state > PERF_EVENT_STATE_OFF) {
- perf_cgroup_event_disable(event, ctx);
- perf_event_set_state(event, PERF_EVENT_STATE_OFF);
- }
-
ctx->generation++;
}
@@ -2422,6 +2410,7 @@ __perf_remove_from_context(struct perf_e
struct perf_event_context *ctx,
void *info)
{
+ enum perf_event_state state = PERF_EVENT_STATE_OFF;
unsigned long flags = (unsigned long)info;
if (ctx->is_active & EVENT_TIME) {
@@ -2430,6 +2419,12 @@ __perf_remove_from_context(struct perf_e
}
event_sched_out(event, cpuctx, ctx);
+
+ if (event->state > PERF_EVENT_STATE_OFF)
+ perf_cgroup_event_disable(event, ctx);
+
+ perf_event_set_state(event, min(event->state, state));
+
if (flags & DETACH_GROUP)
perf_group_detach(event);
list_del_event(event, ctx);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 19/57] perf/core: Fix group leader use-after-free after sibling detach
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (17 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 18/57] perf: Fix dangling cgroup pointer in cpuctx Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 20/57] packet: use consistent hard_header_len in non-ring send paths Greg Kroah-Hartman
` (43 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aditya Chillara,
Peter Zijlstra (Intel), Dapeng Mi, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aditya Chillara <aditya.chillara@oss.qualcomm.com>
[ Upstream commit 42c5ca1f0a288a52878bd72a5595b08261057438 ]
perf_group_detach() handles leader and sibling detach differently. When the
group leader is detached, all siblings are promoted to singleton events and
their group_leader pointer is reset to themselves. When a sibling is
detached, it is removed from the leader's sibling_list, but its
group_leader pointer is left pointing at the old leader.
That is harmless when the sibling is being closed and freed immediately, as
in the DETACH_DEAD path. It is not safe when the sibling is detached but
kept alive, such as during CPU hotplug with DETACH_GROUP. In that case the
sibling is removed from the context, while its file descriptor can still
keep it alive.
A typical failing sequence is:
- A group contains leader L and sibling S.
- CPU hot-unplug detaches S with DETACH_GROUP, removing it from
L->sibling_list but leaving S->group_leader == L.
- L is later closed and freed.
- A PERF_IOC_FLAG_GROUP ioctl on S follows S->group_leader and
dereferences the freed leader.
This was reproduced by running the perf event fuzzer, CPU hotplug, and a
stress workload concurrently:
Unable to handle kernel paging request at virtual address 006b6b6b6b6b6cdb
CPU: 2 PID: 12489 Comm: perf_fuzzer 6.18.7 PREEMPT
pc : perf_ioctl+0x34c/0xc68
x20: ffffff89a3fa2c70 x8 : 6b6b6b6b6b6b6b6b
Code: 943c4a0e 340047a0 f9404a94 f9411e88 (f940b908)
Call trace:
perf_ioctl+0x34c/0xc68 (P)
__arm64_sys_ioctl+0xa0/0xf4
invoke_syscall+0x58/0xe4
el0_svc_common+0xa8/0xdc
do_el0_svc+0x1c/0x28
el0_svc+0x40/0xc0
el0t_64_sync_handler+0x68/0xdc
el0t_64_sync+0x1c4/0x1c8
The fault happened in perf_ioctl(), where perf_event_for_each() follows
the stale group_leader pointer and perf_event_for_each_child() then
dereferences the freed leader's context.
Fix the use-after-free by promoting the detached sibling to a singleton.
Also fix __event_disable() cgroup accounting and event state change.
Fixes: 8a49542c0554 ("perf_events: Fix races in group composition")
Assisted-by: PatchWise:gpt-5.5
Signed-off-by: Aditya Chillara <aditya.chillara@oss.qualcomm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260807-fix-group-leader-uaf-v3-1-b0c2310c9a0d@oss.qualcomm.com
[ Adjusted context for 5.10's older APIs, keeping `event_sched_out()`'s 3-arg form and dropping the DETACH_EXIT/REVOKE/DEAD handling that doesn't exist there. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/events/core.c | 67 ++++++++++++++++++++++++++++-----------------------
1 file changed, 37 insertions(+), 30 deletions(-)
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -2222,6 +2222,34 @@ static inline struct list_head *get_even
return event->attr.pinned ? &ctx->pinned_active : &ctx->flexible_active;
}
+/* @sibling must already be unlinked from its old leader's sibling_list. */
+static void perf_promote_sibling_to_leader(struct perf_event *sibling,
+ struct perf_event_context *ctx,
+ int group_caps)
+{
+ /*
+ * Events that have PERF_EV_CAP_SIBLING require being part of
+ * a group and cannot exist on their own, schedule them out
+ * and move them into the ERROR state. Also see
+ * _perf_event_enable(), it will not be able to recover this
+ * ERROR state.
+ */
+ if (sibling->event_caps & PERF_EV_CAP_SIBLING)
+ __event_disable(sibling, ctx, PERF_EVENT_STATE_ERROR);
+
+ sibling->group_leader = sibling;
+ sibling->group_caps = group_caps;
+
+ if (sibling->attach_state & PERF_ATTACH_CONTEXT) {
+ add_event_to_groups(sibling, ctx);
+
+ if (sibling->state == PERF_EVENT_STATE_ACTIVE)
+ list_add_tail(&sibling->active_list, get_event_list(sibling));
+ }
+
+ perf_event__header_size(sibling);
+}
+
static void perf_group_detach(struct perf_event *event)
{
struct perf_event *leader = event->group_leader;
@@ -2245,8 +2273,9 @@ static void perf_group_detach(struct per
*/
if (leader != event) {
list_del_init(&event->sibling_list);
- event->group_leader->nr_siblings--;
- event->group_leader->group_generation++;
+ leader->nr_siblings--;
+ leader->group_generation++;
+ perf_promote_sibling_to_leader(event, ctx, event->event_caps);
goto out;
}
@@ -2256,32 +2285,14 @@ static void perf_group_detach(struct per
* to whatever list we are on.
*/
list_for_each_entry_safe(sibling, tmp, &event->sibling_list, sibling_list) {
-
- /*
- * Events that have PERF_EV_CAP_SIBLING require being part of
- * a group and cannot exist on their own, schedule them out
- * and move them into the ERROR state. Also see
- * _perf_event_enable(), it will not be able to recover this
- * ERROR state.
- */
- if (sibling->event_caps & PERF_EV_CAP_SIBLING)
- __event_disable(sibling, ctx, PERF_EVENT_STATE_ERROR);
-
- sibling->group_leader = sibling;
list_del_init(&sibling->sibling_list);
/* Inherit group flags from the previous leader */
- sibling->group_caps = event->group_caps;
-
- if (!RB_EMPTY_NODE(&event->group_node)) {
- add_event_to_groups(sibling, event->ctx);
-
- if (sibling->state == PERF_EVENT_STATE_ACTIVE)
- list_add_tail(&sibling->active_list, get_event_list(sibling));
- }
+ perf_promote_sibling_to_leader(sibling, ctx, event->group_caps);
WARN_ON_ONCE(sibling->ctx != event->ctx);
}
+ event->nr_siblings = 0;
out:
for_each_sibling_event(tmp, leader)
@@ -2418,12 +2429,7 @@ __perf_remove_from_context(struct perf_e
update_cgrp_time_from_cpuctx(cpuctx, false);
}
- event_sched_out(event, cpuctx, ctx);
-
- if (event->state > PERF_EVENT_STATE_OFF)
- perf_cgroup_event_disable(event, ctx);
-
- perf_event_set_state(event, min(event->state, state));
+ __event_disable(event, ctx, state);
if (flags & DETACH_GROUP)
perf_group_detach(event);
@@ -2484,8 +2490,9 @@ static void __event_disable(struct perf_
enum perf_event_state state)
{
event_sched_out(event, __get_cpu_context(ctx), ctx);
- perf_cgroup_event_disable(event, ctx);
- perf_event_set_state(event, state);
+ if (event->state > PERF_EVENT_STATE_OFF)
+ perf_cgroup_event_disable(event, ctx);
+ perf_event_set_state(event, min(event->state, state));
}
/*
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 20/57] packet: use consistent hard_header_len in non-ring send paths
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (18 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 19/57] perf/core: Fix group leader use-after-free after sibling detach Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 21/57] packet: use consistent hard_header_len in TX_RING send path Greg Kroah-Hartman
` (42 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qihang Tang, Willem de Bruijn,
Jakub Kicinski, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qihang Tang <q.h.hack.winter@gmail.com>
[ Upstream commit 03390aa32e669cc4ecd7d34108e2e1afc13d689d ]
packet_snd() reads dev->hard_header_len multiple times while allocating
and constructing an skb. Device reconfiguration can change this value
concurrently, for example through bonding device type changes.
For SOCK_RAW, packet_snd() can save a larger value in reserve and later
allocate headroom using a smaller value. Moving skb->data back by reserve
then places it before skb->head, and the following copy from userspace can
attempt an out-of-bounds write.
packet_sendmsg_spkt() has the same issue because it calculates its
reservation and header offset from separate reads before dropping the RCU
read lock to allocate the skb.
Add LL_RESERVED_SPACE_EX() for callers that already saved a header length.
Read hard_header_len once in packet_snd() and use it for allocation and
construction. In packet_sendmsg_spkt(), preserve the allocation-time value
through the device lookup retry.
The separate SOCK_DGRAM consistency problem between hard_header_len and
header_ops->create is not addressed here.
Fixes: b84bbaf7a6c8 ("packet: in packet_snd start writing at link layer allocation")
Cc: stable@vger.kernel.org
Signed-off-by: Qihang Tang <q.h.hack.winter@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260805125729.19220-3-q.h.hack.winter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 21b5953e7494 ("packet: use consistent hard_header_len in TX_RING send path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/netdevice.h | 6 ++++--
net/packet/af_packet.c | 26 ++++++++++++++++----------
2 files changed, 20 insertions(+), 12 deletions(-)
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -269,9 +269,11 @@ struct hh_cache {
* We could use other alignment values, but we must maintain the
* relationship HH alignment <= LL alignment.
*/
-#define LL_RESERVED_SPACE(dev) \
- ((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom)) \
+#define LL_RESERVED_SPACE_EX(dev, hlen) \
+ ((((hlen) + READ_ONCE((dev)->needed_headroom)) \
& ~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
+#define LL_RESERVED_SPACE(dev) \
+ LL_RESERVED_SPACE_EX(dev, (dev)->hard_header_len)
#define LL_RESERVED_SPACE_EXTRA(dev,extra) \
((((dev)->hard_header_len + READ_ONCE((dev)->needed_headroom) + (extra)) \
& ~(HH_DATA_MOD - 1)) + HH_DATA_MOD)
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1968,8 +1968,9 @@ static int packet_sendmsg_spkt(struct so
struct net_device *dev;
struct sockcm_cookie sockc;
__be16 proto = 0;
- int err;
+ int hard_header_len;
int extra_len = 0;
+ int err;
/*
* Get and verify the address.
@@ -2012,14 +2013,18 @@ retry:
extra_len = 4; /* We're doing our own CRC */
}
+ /* Keep the allocation-time header length across retry. */
+ if (!skb)
+ hard_header_len = READ_ONCE(dev->hard_header_len);
+
err = -EMSGSIZE;
- if (len > dev->mtu + dev->hard_header_len + VLAN_HLEN + extra_len)
+ if (len > dev->mtu + hard_header_len + VLAN_HLEN + extra_len)
goto out_unlock;
if (!skb) {
- size_t reserved = LL_RESERVED_SPACE(dev);
+ size_t reserved = LL_RESERVED_SPACE_EX(dev, hard_header_len);
int tlen = dev->needed_tailroom;
- unsigned int hhlen = dev->header_ops ? dev->hard_header_len : 0;
+ unsigned int hhlen = dev->header_ops ? hard_header_len : 0;
rcu_read_unlock();
skb = sock_wmalloc(sk, len + reserved + tlen, 0, GFP_KERNEL);
@@ -2049,7 +2054,7 @@ retry:
err = -EINVAL;
goto out_unlock;
}
- if (len > (dev->mtu + dev->hard_header_len + extra_len) &&
+ if (len > (dev->mtu + hard_header_len + extra_len) &&
!packet_extra_vlan_len_allowed(dev, skb)) {
err = -EMSGSIZE;
goto out_unlock;
@@ -2965,7 +2970,7 @@ static int packet_snd(struct socket *soc
int offset = 0;
struct packet_sock *po = pkt_sk(sk);
bool has_vnet_hdr = false;
- int hlen, tlen, linear;
+ int hard_header_len, hlen, tlen, linear;
int extra_len = 0;
/*
@@ -3006,8 +3011,9 @@ static int packet_snd(struct socket *soc
goto out_unlock;
}
+ hard_header_len = READ_ONCE(dev->hard_header_len);
if (sock->type == SOCK_RAW)
- reserve = dev->hard_header_len;
+ reserve = hard_header_len;
if (po->has_vnet_hdr) {
err = packet_snd_vnet_parse(msg, &len, &vnet_hdr);
if (err)
@@ -3029,10 +3035,10 @@ static int packet_snd(struct socket *soc
goto out_unlock;
err = -ENOBUFS;
- hlen = LL_RESERVED_SPACE(dev);
+ hlen = LL_RESERVED_SPACE_EX(dev, hard_header_len);
tlen = dev->needed_tailroom;
linear = __virtio16_to_cpu(vio_le(), vnet_hdr.hdr_len);
- linear = max(linear, min_t(int, len, dev->hard_header_len));
+ linear = max(linear, min_t(int, len, hard_header_len));
skb = packet_alloc_skb(sk, hlen + tlen, hlen, len, linear,
msg->msg_flags & MSG_DONTWAIT, &err);
if (skb == NULL)
@@ -3048,7 +3054,7 @@ static int packet_snd(struct socket *soc
} else if (reserve) {
skb_reserve(skb, -reserve);
if (len < reserve + sizeof(struct ipv6hdr) &&
- dev->min_header_len != dev->hard_header_len)
+ dev->min_header_len != hard_header_len)
skb_reset_network_header(skb);
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 21/57] packet: use consistent hard_header_len in TX_RING send path
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (19 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 20/57] packet: use consistent hard_header_len in non-ring send paths Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 22/57] net/sched: reject overly deep qdisc hierarchies Greg Kroah-Hartman
` (41 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qihang Tang, Willem de Bruijn,
Jakub Kicinski, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qihang Tang <q.h.hack.winter@gmail.com>
[ Upstream commit 21b5953e7494c16a42e6cd8cf110e18d13ae4a6b ]
tpacket_snd() reads dev->hard_header_len independently for skb
allocation and header construction in tpacket_fill_skb(). Concurrent
netdevice reconfiguration can therefore make the reserved headroom
smaller than the amount later pushed, or make copylen - hard_header_len
negative.
Snapshot hard_header_len once before processing ring frames and use it
for the frame limit, headroom allocation, copy length, and skb
construction. Pass the snapshot to tpacket_fill_skb().
The separate SOCK_DGRAM consistency problem between hard_header_len and
header_ops->create is not addressed here.
Fixes: 69e3c75f4d54 ("net: TX_RING and packet mmap")
Cc: stable@vger.kernel.org
Signed-off-by: Qihang Tang <q.h.hack.winter@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260805125729.19220-4-q.h.hack.winter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Applied cleanly after amending the prerequisite that adds `LL_RESERVED_SPACE_EX()`; no target-side adaptation was needed. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/packet/af_packet.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2582,6 +2582,7 @@ static int packet_snd_vnet_parse(struct
static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb,
void *frame, struct net_device *dev, void *data, int tp_len,
__be16 proto, unsigned char *addr, int hlen, int copylen,
+ int hard_header_len,
const struct sockcm_cookie *sockc)
{
union tpacket_uhdr ph;
@@ -2613,8 +2614,8 @@ static int tpacket_fill_skb(struct packe
} else if (copylen) {
int hdrlen = min_t(int, copylen, tp_len);
- skb_push(skb, dev->hard_header_len);
- skb_put(skb, copylen - dev->hard_header_len);
+ skb_push(skb, hard_header_len);
+ skb_put(skb, copylen - hard_header_len);
err = skb_store_bits(skb, 0, data, hdrlen);
if (unlikely(err))
return err;
@@ -2747,7 +2748,7 @@ static int tpacket_snd(struct packet_soc
void *data;
int len_sum = 0;
int status = TP_STATUS_AVAILABLE;
- int hlen, tlen, copylen = 0;
+ int hard_header_len, hlen, tlen, copylen = 0;
long timeo;
mutex_lock(&po->pg_vec_lock);
@@ -2794,8 +2795,9 @@ static int tpacket_snd(struct packet_soc
goto out_put;
}
+ hard_header_len = READ_ONCE(dev->hard_header_len);
if (po->sk.sk_socket->type == SOCK_RAW)
- reserve = dev->hard_header_len;
+ reserve = hard_header_len;
size_max = po->tx_ring.frame_size
- (po->tp_hdrlen - sizeof(struct sockaddr_ll));
@@ -2832,7 +2834,7 @@ static int tpacket_snd(struct packet_soc
goto tpacket_error;
status = TP_STATUS_SEND_REQUEST;
- hlen = LL_RESERVED_SPACE(dev);
+ hlen = LL_RESERVED_SPACE_EX(dev, hard_header_len);
tlen = dev->needed_tailroom;
if (po->has_vnet_hdr) {
data += sizeof(vnet_hdr);
@@ -2850,10 +2852,10 @@ static int tpacket_snd(struct packet_soc
vnet_hdr.hdr_len);
has_vnet_hdr = true;
}
- copylen = max_t(int, copylen, dev->hard_header_len);
+ copylen = max_t(int, copylen, hard_header_len);
skb = sock_alloc_send_skb(&po->sk,
hlen + tlen + sizeof(struct sockaddr_ll) +
- (copylen - dev->hard_header_len),
+ (copylen - hard_header_len),
!need_wait, &err);
if (unlikely(skb == NULL)) {
@@ -2863,7 +2865,8 @@ static int tpacket_snd(struct packet_soc
goto out_status;
}
tp_len = tpacket_fill_skb(po, skb, ph, dev, data, tp_len, proto,
- addr, hlen, copylen, &sockc);
+ addr, hlen, copylen, hard_header_len,
+ &sockc);
if (likely(tp_len >= 0) &&
tp_len > dev->mtu + reserve &&
!po->has_vnet_hdr &&
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 22/57] net/sched: reject overly deep qdisc hierarchies
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (20 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 21/57] packet: use consistent hard_header_len in TX_RING send path Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 23/57] packet: synchronize pressure clearing with ring reconfiguration Greg Kroah-Hartman
` (40 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jamal Hadi Salim, Vega, Zijie Huang,
Ren Wei, Victor Nogueira, Paolo Abeni, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijie Huang <milkory@outlook.com>
[ Upstream commit dedd34b0f2310e28c5f6d4875cfbf4b7ed821c01 ]
Deep qdisc hierarchies can lead to excessive recursion in qdisc tree
walkers and exhaust the kernel stack. The existing loop check does not
cover the create-and-graft path, so a hierarchy can still be extended by
creating a new child qdisc below an already deep parent.
Store the hierarchy depth in struct Qdisc and update it when qdiscs are
grafted. Reject new child qdiscs once the parent is already at the maximum
allowed depth.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Suggested-by: Jamal Hadi Salim <jhs@mojatatu.com>
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: Codex:gpt-5.4
Signed-off-by: Zijie Huang <milkory@outlook.com>
Signed-off-by: Ren Wei <enjou1224z@gmail.com>
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Link: https://patch.msgid.link/1e9ab39597423fd5d13cfaaf52279b8ee3d9fc3c.1785434373.git.milkory@outlook.com
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
[ Dropped the `extack` argument from the `notify_and_destroy()` context line to match 5.15's 6-parameter version. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/net/sch_generic.h | 1 +
net/sched/sch_api.c | 9 +++++++++
2 files changed, 10 insertions(+)
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -86,6 +86,7 @@ struct Qdisc {
struct hlist_node hash;
u32 handle;
u32 parent;
+ int depth;
struct netdev_queue *dev_queue;
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1045,6 +1045,9 @@ static int qdisc_graft(struct net_device
unsigned int i, num_q, ingress;
struct netdev_queue *dev_queue;
+ if (new)
+ new->depth = 0;
+
ingress = 0;
num_q = dev->num_tx_queues;
if ((q && q->flags & TCQ_F_INGRESS) ||
@@ -1124,9 +1127,15 @@ skip:
NL_SET_ERR_MSG(extack, "STAB not supported on a non root");
return -EINVAL;
}
+ if (new && parent->depth >= 7) {
+ NL_SET_ERR_MSG(extack, "Qdisc hierarchy is too deep");
+ return -E2BIG;
+ }
err = cops->graft(parent, cl, new, &old, extack);
if (err)
return err;
+ if (new)
+ new->depth = parent->depth + 1;
notify_and_destroy(net, skb, n, classid, old, new);
}
return 0;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 23/57] packet: synchronize pressure clearing with ring reconfiguration
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (21 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 22/57] net/sched: reject overly deep qdisc hierarchies Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 24/57] inet: frags: publish queues before arming timer Greg Kroah-Hartman
` (39 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zihan Xi, Paolo Abeni,
Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
[ Upstream commit 1a35da325cac4d5bcad76a2aa943408a6f1d9000 ]
packet_set_ring() updates the RX ring state under sk_receive_queue.lock,
but used to publish the tpacket receive mode through po->prot_hook.func
after releasing that lock. packet_poll() and packet_recvmsg() can then
run the pressure clearing path after the ring has been cleared while
still seeing tpacket_rcv, causing __packet_rcv_has_room() to dereference
stale or NULL ring storage.
Move the existing receive hook assignment into the same
sk_receive_queue.lock section as the ring state update. Keep the
assignment otherwise unchanged, including on TX ring reconfiguration, to
avoid adding behavior changes that are not required for the fix.
Serialize packet_recvmsg() pressure clearing with the same queue lock
only after PACKET_SOCK_PRESSURE has been observed. If the flag is clear
and the socket has moved away from tpacket_rcv, packet_set_ring() has
already detached the socket and waited for synchronize_net(), so no new
packet input can set the flag again.
packet_poll() already holds sk_receive_queue.lock, so it uses the new
unlocked helper directly.
Fixes: 2ccdbaa6d55b ("packet: rollover lock contention avoidance")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: Codex:gpt-5.4
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Link: https://patch.msgid.link/f90b5688311fa278d1361ea8c6be0bf25967d591.1785247446.git.zihanx@nebusec.ai
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
[ Replaced `packet_sock_flag(po, PACKET_SOCK_PRESSURE)` with `READ_ONCE(po->pressure)` since the flag conversion isn't in this tree. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/packet/af_packet.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1330,13 +1330,25 @@ static int packet_rcv_has_room(struct pa
return ret;
}
-static void packet_rcv_try_clear_pressure(struct packet_sock *po)
+static void __packet_rcv_try_clear_pressure(struct packet_sock *po)
{
if (READ_ONCE(po->pressure) &&
__packet_rcv_has_room(po, NULL) == ROOM_NORMAL)
WRITE_ONCE(po->pressure, 0);
}
+static void packet_rcv_try_clear_pressure(struct packet_sock *po)
+{
+ struct sock *sk = &po->sk;
+
+ if (!READ_ONCE(po->pressure))
+ return;
+
+ spin_lock_bh(&sk->sk_receive_queue.lock);
+ __packet_rcv_try_clear_pressure(po);
+ spin_unlock_bh(&sk->sk_receive_queue.lock);
+}
+
static void packet_sock_destruct(struct sock *sk)
{
skb_queue_purge(&sk->sk_error_queue);
@@ -4307,7 +4319,7 @@ static __poll_t packet_poll(struct file
TP_STATUS_KERNEL))
mask |= EPOLLIN | EPOLLRDNORM;
}
- packet_rcv_try_clear_pressure(po);
+ __packet_rcv_try_clear_pressure(po);
spin_unlock_bh(&sk->sk_receive_queue.lock);
spin_lock_bh(&sk->sk_write_queue.lock);
if (po->tx_ring.pg_vec) {
@@ -4547,14 +4559,14 @@ static int packet_set_ring(struct sock *
rb->frame_max = (req->tp_frame_nr - 1);
rb->head = 0;
rb->frame_size = req->tp_frame_size;
+ po->prot_hook.func = (po->rx_ring.pg_vec) ?
+ tpacket_rcv : packet_rcv;
spin_unlock_bh(&rb_queue->lock);
swap(rb->pg_vec_order, order);
swap(rb->pg_vec_len, req->tp_block_nr);
rb->pg_vec_pages = req->tp_block_size/PAGE_SIZE;
- po->prot_hook.func = (po->rx_ring.pg_vec) ?
- tpacket_rcv : packet_rcv;
skb_queue_purge(rb_queue);
if (atomic_long_read(&po->mapped))
pr_err("packet_mmap: vma is busy: %ld\n",
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 24/57] inet: frags: publish queues before arming timer
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (22 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 23/57] packet: synchronize pressure clearing with ring reconfiguration Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 25/57] xfs: fix ilock leak on error in xfs_dq_get_next_id Greg Kroah-Hartman
` (38 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Ren Wei,
Jakub Kicinski, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
[ Upstream commit 653d7ddf6cba867777a3d14c4f83ace008c5ad13 ]
inet_frag_create() arms the fragment queue timer before inserting the
queue into the fqdir rhashtable. If the namespace fragment timeout is
zero or negative, the timer can run before the queue is published.
The timer callback then marks the queue complete, tries to remove a node
that is not in the hash table yet, and drops the anticipated hash
reference. Creation can subsequently publish the completed queue without
restoring that reference, leaving a stale hash node after the caller drops
the remaining reference.
Publish the queue first and arm the timer while holding the queue lock.
This makes timer expiry wait until the queue is visible in the hash table,
so inet_frag_kill() can remove the node and balance the hash reference.
Fixes: 648700f76b03 ("inet: frags: use rhashtables for reassembly units")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Signed-off-by: Ren Wei <enjou1224z@gmail.com>
Link: https://patch.msgid.link/bf66785e7c0c139d7a1900e2f01faeeab344b960.1784948849.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/inet_fragment.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -308,16 +308,18 @@ static struct inet_frag_queue *inet_frag
*prev = ERR_PTR(-ENOMEM);
return NULL;
}
- mod_timer(&q->timer, jiffies + fqdir->timeout);
+ spin_lock_bh(&q->lock);
*prev = rhashtable_lookup_get_insert_key(&fqdir->rhashtable, &q->key,
&q->node, f->rhash_params);
if (*prev) {
q->flags |= INET_FRAG_COMPLETE;
- inet_frag_kill(q);
+ spin_unlock_bh(&q->lock);
inet_frag_destroy(q);
return NULL;
}
+ mod_timer(&q->timer, jiffies + fqdir->timeout);
+ spin_unlock_bh(&q->lock);
return q;
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 25/57] xfs: fix ilock leak on error in xfs_dq_get_next_id
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (23 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 24/57] inet: frags: publish queues before arming timer Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 26/57] mmc: atmel-mci: Fix use-after-free in atmci_remove due to race condition Greg Kroah-Hartman
` (37 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Long Li, Christoph Hellwig,
Darrick J. Wong, Carlos Maiolino, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <leo.lilong@huawei.com>
[ Upstream commit 63320a0f70f66f311f4bccff3af0719c2119f46c ]
xfs_dq_get_next_id() takes the quota inode ILOCK before calling
xfs_iread_extents(). If xfs_iread_extents() fails, the function returns
immediately without releasing the lock, leaking the quota inode ILOCK.
This can leave the quota inode locked and cause subsequent quota
operations to hang.
Fix this by jumping to a common unlock path on error instead of returning
directly.
Fixes: bda250dbaf39f ("xfs: rewrite xfs_dq_get_next_id using xfs_iext_lookup_extent")
Cc: stable@vger.kernel.org # v4.12
Signed-off-by: Long Li <leo.lilong@huawei.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_dquot.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -745,7 +745,7 @@ xfs_dq_get_next_id(
if (!(quotip->i_df.if_flags & XFS_IFEXTENTS)) {
error = xfs_iread_extents(NULL, quotip, XFS_DATA_FORK);
if (error)
- return error;
+ goto out_unlock;
}
if (xfs_iext_lookup_extent(quotip, "ip->i_df, start, &cur, &got)) {
@@ -757,6 +757,7 @@ xfs_dq_get_next_id(
error = -ENOENT;
}
+out_unlock:
xfs_iunlock(quotip, lock_flags);
return error;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 26/57] mmc: atmel-mci: Fix use-after-free in atmci_remove due to race condition
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (24 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 25/57] xfs: fix ilock leak on error in xfs_dq_get_next_id Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 27/57] s390/vfio_ccw: Cancel existing workqueues Greg Kroah-Hartman
` (36 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pei Xiao, Ulf Hansson, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pei Xiao <xiaopei01@kylinos.cn>
[ Upstream commit c125ee35a49a0518521b52b27631eef061b8719a ]
In atmci_probe, &host->bh_work is bound with atmci_work_func, and
atmci_interrupt, atmci_timeout_timer and atmci_dma_complete can all
queue this work on system_bh_wq.
If we remove the module, atmci_remove makes cleanup and the memory
allocated for host with devm_kzalloc() is released after the remove
callback returns, while the work mentioned above may still be pending
or running. The sequence of operations that may lead to a UAF bug is
as follows:
CPU0 CPU1
| atmci_interrupt
| queue_work(system_bh_wq,
| &host->bh_work)
atmci_remove |
atmci_cleanup_slot(...) |
atmci_writel(host, ATMCI_IDR, ~0UL) |
timer_delete_sync(&host->timer) |
dma_release_channel(host->dma.chan) |
free_irq(platform_get_irq(pdev, 0), host) |
| atmci_work_func
| // use host
// devm resources released after |
// remove returns, host is freed |
| // use host (use-after-free)
Fix it by canceling the work after all the sources that can schedule
it (IRQ handler, timeout timer and DMA completion callback) have been
stopped, and before proceeding with the remaining cleanup in
atmci_remove.
Fixes: 7d2be0749a59 ("atmel-mci: Driver for Atmel on-chip MMC controllers")
Assisted-by: Codex:deepseek-v4-flash
Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
Cc: stable@vger.kernel.org
Signed-off-by: Ulf Hansson <ulfh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/mmc/host/atmel-mci.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -2629,6 +2629,8 @@ static int atmci_remove(struct platform_
free_irq(platform_get_irq(pdev, 0), host);
+ tasklet_kill(&host->tasklet);
+
clk_disable_unprepare(host->mck);
pm_runtime_disable(&pdev->dev);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 27/57] s390/vfio_ccw: Cancel existing workqueues
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (25 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 26/57] mmc: atmel-mci: Fix use-after-free in atmci_remove due to race condition Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 28/57] KVM: arm64: Retry fault if vma_lookup() results become invalid Greg Kroah-Hartman
` (35 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthew Rosato, Eric Farman,
Christian Borntraeger, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Farman <farman@linux.ibm.com>
[ Upstream commit 79c60b2c61105368dcc8444eb45847e21734f7c4 ]
The initialization of the io_work and crw_work workqueues begs the
question of whether they should be un-initialized. Add the corresponding
cleanup tags in _release_dev to ensure work isn't dispatched after
the private struct is free'd.
Suggested-by: Matthew Rosato <mjrosato@linux.ibm.com>
Fixes: e5f84dbaea59 ("vfio: ccw: return I/O results asynchronously")
Fixes: 3f02cb2fd9d2 ("vfio-ccw: Wire up the CRW irq and CRW region")
Cc: stable@vger.kernel.org
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/s390/cio/vfio_ccw_drv.c | 7 +++++++
drivers/s390/cio/vfio_ccw_ops.c | 8 ++++++++
2 files changed, 15 insertions(+)
--- a/drivers/s390/cio/vfio_ccw_drv.c
+++ b/drivers/s390/cio/vfio_ccw_drv.c
@@ -241,6 +241,13 @@ static int vfio_ccw_sch_remove(struct su
vfio_ccw_sch_quiesce(sch);
+ /*
+ * Ensure these work items are fully drained, so none can
+ * fire after being released.
+ */
+ cancel_work_sync(&private->io_work);
+ cancel_work_sync(&private->crw_work);
+
list_for_each_entry_safe(crw, temp, &private->crw, next) {
list_del(&crw->next);
kfree(crw);
--- a/drivers/s390/cio/vfio_ccw_ops.c
+++ b/drivers/s390/cio/vfio_ccw_ops.c
@@ -204,6 +204,14 @@ static void vfio_ccw_mdev_release(struct
}
cp_free(&private->cp);
+
+ /*
+ * Ensure these work items are drained, in the event the
+ * device is re-opened instead of released.
+ */
+ cancel_work_sync(&private->io_work);
+ cancel_work_sync(&private->crw_work);
+
vfio_ccw_unregister_dev_regions(private);
vfio_unregister_notifier(mdev_dev(mdev), VFIO_IOMMU_NOTIFY,
&private->nb);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 28/57] KVM: arm64: Retry fault if vma_lookup() results become invalid
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (26 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 27/57] s390/vfio_ccw: Cancel existing workqueues Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 29/57] nfc: digital: clamp SENSF_RES length to the destination buffer Greg Kroah-Hartman
` (34 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Christopherson, David Matlack,
Marc Zyngier, Oliver Upton, Bjoern Doebel
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Matlack <dmatlack@google.com>
commit 13ec9308a85702af7c31f3638a2720863848a7f2 upstream.
Read mmu_invalidate_seq before dropping the mmap_lock so that KVM can
detect if the results of vma_lookup() (e.g. vma_shift) become stale
before it acquires kvm->mmu_lock. This fixes a theoretical bug where a
VMA could be changed by userspace after vma_lookup() and before KVM
reads the mmu_invalidate_seq, causing KVM to install page table entries
based on a (possibly) no-longer-valid vma_shift.
Re-order the MMU cache top-up to earlier in user_mem_abort() so that it
is not done after KVM has read mmu_invalidate_seq (i.e. so as to avoid
inducing spurious fault retries).
This bug has existed since KVM/ARM's inception. It's unlikely that any
sane userspace currently modifies VMAs in such a way as to trigger this
race. And even with directed testing I was unable to reproduce it. But a
sufficiently motivated host userspace might be able to exploit this
race.
Fixes: 94f8e6418d39 ("KVM: ARM: Handle guest faults in KVM")
Cc: stable@vger.kernel.org
Reported-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: David Matlack <dmatlack@google.com>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230313235454.2964067-1-dmatlack@google.com
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
[doebel: adjust to contextual and naming differences in 5.10]
Signed-off-by: Bjoern Doebel <doebel@amazon.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/arm64/kvm/mmu.c | 42 ++++++++++++++++++++----------------------
1 file changed, 20 insertions(+), 22 deletions(-)
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -769,6 +769,19 @@ static int user_mem_abort(struct kvm_vcp
return -EFAULT;
}
+ /*
+ * Permission faults just need to update the existing leaf entry,
+ * and so normally don't require allocations from the memcache. The
+ * only exception to this is when dirty logging is enabled at runtime
+ * and a write fault needs to collapse a block entry into a table.
+ */
+ if (fault_status != FSC_PERM || (logging_active && write_fault)) {
+ ret = kvm_mmu_topup_memory_cache(memcache,
+ kvm_mmu_cache_min_pages(kvm));
+ if (ret)
+ return ret;
+ }
+
/* Let's check if we will get back a huge page backed by hugetlbfs */
mmap_read_lock(current->mm);
vma = find_vma_intersection(current->mm, hva, hva + 1);
@@ -818,32 +831,17 @@ static int user_mem_abort(struct kvm_vcp
fault_ipa &= ~(vma_pagesize - 1);
gfn = fault_ipa >> PAGE_SHIFT;
- mmap_read_unlock(current->mm);
/*
- * Permission faults just need to update the existing leaf entry,
- * and so normally don't require allocations from the memcache. The
- * only exception to this is when dirty logging is enabled at runtime
- * and a write fault needs to collapse a block entry into a table.
+ * Read mmu_notifier_seq so that KVM can detect if the results of
+ * find_vma_intersection() or gfn_to_pfn_prot() become stale prior to
+ * acquiring kvm->mmu_lock.
+ *
+ * Rely on mmap_read_unlock() for an implicit smp_rmb(), which pairs
+ * with the smp_wmb() in kvm_mmu_notifier_invalidate_range_end().
*/
- if (fault_status != FSC_PERM || (logging_active && write_fault)) {
- ret = kvm_mmu_topup_memory_cache(memcache,
- kvm_mmu_cache_min_pages(kvm));
- if (ret)
- return ret;
- }
-
mmu_seq = vcpu->kvm->mmu_notifier_seq;
- /*
- * Ensure the read of mmu_notifier_seq happens before we call
- * gfn_to_pfn_prot (which calls get_user_pages), so that we don't risk
- * the page we just got a reference to gets unmapped before we have a
- * chance to grab the mmu_lock, which ensure that if the page gets
- * unmapped afterwards, the call to kvm_unmap_hva will take it away
- * from us again properly. This smp_rmb() interacts with the smp_wmb()
- * in kvm_mmu_notifier_invalidate_<page|range_end>.
- */
- smp_rmb();
+ mmap_read_unlock(current->mm);
pfn = gfn_to_pfn_prot(kvm, gfn, write_fault, &writable);
if (pfn == KVM_PFN_ERR_HWPOISON) {
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 29/57] nfc: digital: clamp SENSF_RES length to the destination buffer
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (27 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 28/57] KVM: arm64: Retry fault if vma_lookup() results become invalid Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 30/57] nfc: fdp: bound the device-reported read length and fix an skb leak Greg Kroah-Hartman
` (33 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Doruk Tan Ozturk, Alexander Lobakin,
David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <doruk@0sec.ai>
commit 344a56d7c8e0f3cbaff0bcb1bcd95a1a1db24b16 upstream.
digital_in_recv_sensf_res() memcpy()s resp->len bytes from a remote
NFC-F device response into the NFC_SENSF_RES_MAXSIZE-byte target.sensf_res
field without an upper-bound check. A nearby malicious NFC-F device can
send an oversized SENSF_RES response to overflow the stack-local struct
nfc_target.
Clamp resp->len to NFC_SENSF_RES_MAXSIZE before the copy.
Found by 0sec automated security-research tooling (https://0sec.ai).
Fixes: 8c0695e4998d ("NFC Digital: Add NFC-F technology support")
Cc: stable@vger.kernel.org
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Link: https://patch.msgid.link/20260603141355.68156-1-doruk@0sec.ai
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/nfc/digital_technology.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/nfc/digital_technology.c
+++ b/net/nfc/digital_technology.c
@@ -778,6 +778,8 @@ static void digital_in_recv_sensf_res(st
sensf_res = (struct digital_sensf_res *)resp->data;
+ resp->len = min_t(unsigned int, resp->len, NFC_SENSF_RES_MAXSIZE);
+
memcpy(target.sensf_res, sensf_res, resp->len);
target.sensf_res_len = resp->len;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 30/57] nfc: fdp: bound the device-reported read length and fix an skb leak
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (28 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 29/57] nfc: digital: clamp SENSF_RES length to the destination buffer Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 31/57] nfc: microread: validate target discovery payload lengths Greg Kroah-Hartman
` (32 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Simon Horman, Bryam Vargas,
David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bryam Vargas <hexlabsecurity@proton.me>
commit 7ad21dcfeb5181af0c3ee2608808c0c0a5283aa1 upstream.
fdp_nci_i2c_read() takes the next packet length from two device-supplied
bytes and never validates it. The value is a u16 used as the
i2c_master_recv() count into a 261-byte on-stack buffer: a malicious,
counterfeit or malfunctioning controller (or an i2c bus interposer) can
drive it far past the buffer for a stack out-of-bounds write that
clobbers the canary and return address, or below the minimum frame size
(directly, or by truncating the computed sum) so the header/LRC strip
and the next length read run past a short receive. Reject a length
outside [FDP_NCI_I2C_MIN_PAYLOAD, FDP_NCI_I2C_MAX_PAYLOAD], as a
corrupted packet already is, and force resynchronization.
The same loop allocates one data skb per iteration and assumes a length
packet followed by a data packet; a device that sends two data packets
in one call leaks the first skb when the second allocation overwrites
it. Free a previously allocated skb before allocating the next.
Fixes: a06347c04c13 ("NFC: Add Intel Fields Peak NFC solution driver")
Cc: stable@vger.kernel.org
Suggested-by: Simon Horman <horms@kernel.org>
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20260616-b4-disp-b1f8ab4c-v2-1-2d1fe5955325@proton.me
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nfc/fdp/i2c.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
--- a/drivers/nfc/fdp/i2c.c
+++ b/drivers/nfc/fdp/i2c.c
@@ -166,9 +166,36 @@ static int fdp_nci_i2c_read(struct fdp_i
/* Packet that contains a length */
if (tmp[0] == 0 && tmp[1] == 0) {
phy->next_read_size = (tmp[2] << 8) + tmp[3] + 3;
+
+ /*
+ * next_read_size is taken from the device and is used
+ * as the i2c_master_recv() count for the next packet
+ * and as the data skb size. A value above the receive
+ * buffer overflows tmp[]; one below the minimum frame
+ * size runs the header/LRC strip and the length-field
+ * read past a short receive. Either way the packet is
+ * corrupt: drop it and force resynchronization.
+ */
+ if (phy->next_read_size < FDP_NCI_I2C_MIN_PAYLOAD ||
+ phy->next_read_size > FDP_NCI_I2C_MAX_PAYLOAD) {
+ dev_dbg(&client->dev, "%s: corrupted packet\n",
+ __func__);
+ phy->next_read_size = FDP_NCI_I2C_MIN_PAYLOAD;
+ goto flush;
+ }
} else {
phy->next_read_size = FDP_NCI_I2C_MIN_PAYLOAD;
+ /*
+ * Only one data packet is delivered per call; if the
+ * device sends another, do not overwrite and leak the
+ * skb allocated for the previous one.
+ */
+ if (*skb) {
+ kfree_skb(*skb);
+ *skb = NULL;
+ }
+
*skb = alloc_skb(len, GFP_KERNEL);
if (*skb == NULL) {
r = -ENOMEM;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 31/57] nfc: microread: validate target discovery payload lengths
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (29 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 30/57] nfc: fdp: bound the device-reported read length and fix an skb leak Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 32/57] nfc: llcp: bound the connect_sn TLV walk to the skb Greg Kroah-Hartman
` (31 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
commit 25519469972ef57c3edb1805dabd6c5612b90211 upstream.
microread_target_discovered() parses target discovery payloads from
skb->data according to the HCI gate. The fixed field offsets and UID
copies were checked only against the destination nfc_target buffers, not
against the actual skb length.
Validate that each gate-specific payload contains the fixed fields and
UID bytes before reading or copying them.
Fixes: cfad1ba87150 ("NFC: Initial support for Inside Secure microread")
Cc: stable@vger.kernel.org
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260723103508.1-microread-v2-pengpeng@iscas.ac.cn
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nfc/microread/microread.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
--- a/drivers/nfc/microread/microread.c
+++ b/drivers/nfc/microread/microread.c
@@ -485,13 +485,19 @@ static void microread_target_discovered(
switch (gate) {
case MICROREAD_GATE_ID_MREAD_ISO_A:
+ if (skb->len <= MICROREAD_EMCF_A_LEN) {
+ r = -EINVAL;
+ goto exit_free;
+ }
+
targets->supported_protocols =
nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A_SAK]);
targets->sens_res =
be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A_ATQA]);
targets->sel_res = skb->data[MICROREAD_EMCF_A_SAK];
targets->nfcid1_len = skb->data[MICROREAD_EMCF_A_LEN];
- if (targets->nfcid1_len > sizeof(targets->nfcid1)) {
+ if (targets->nfcid1_len > sizeof(targets->nfcid1) ||
+ targets->nfcid1_len > skb->len - MICROREAD_EMCF_A_UID) {
r = -EINVAL;
goto exit_free;
}
@@ -499,13 +505,19 @@ static void microread_target_discovered(
targets->nfcid1_len);
break;
case MICROREAD_GATE_ID_MREAD_ISO_A_3:
+ if (skb->len <= MICROREAD_EMCF_A3_LEN) {
+ r = -EINVAL;
+ goto exit_free;
+ }
+
targets->supported_protocols =
nfc_hci_sak_to_protocol(skb->data[MICROREAD_EMCF_A3_SAK]);
targets->sens_res =
be16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_A3_ATQA]);
targets->sel_res = skb->data[MICROREAD_EMCF_A3_SAK];
targets->nfcid1_len = skb->data[MICROREAD_EMCF_A3_LEN];
- if (targets->nfcid1_len > sizeof(targets->nfcid1)) {
+ if (targets->nfcid1_len > sizeof(targets->nfcid1) ||
+ targets->nfcid1_len > skb->len - MICROREAD_EMCF_A3_UID) {
r = -EINVAL;
goto exit_free;
}
@@ -513,11 +525,21 @@ static void microread_target_discovered(
targets->nfcid1_len);
break;
case MICROREAD_GATE_ID_MREAD_ISO_B:
+ if (skb->len < MICROREAD_EMCF_B_UID + 4) {
+ r = -EINVAL;
+ goto exit_free;
+ }
+
targets->supported_protocols = NFC_PROTO_ISO14443_B_MASK;
memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_B_UID], 4);
targets->nfcid1_len = 4;
break;
case MICROREAD_GATE_ID_MREAD_NFC_T1:
+ if (skb->len < MICROREAD_EMCF_T1_UID + 4) {
+ r = -EINVAL;
+ goto exit_free;
+ }
+
targets->supported_protocols = NFC_PROTO_JEWEL_MASK;
targets->sens_res =
le16_to_cpu(*(u16 *)&skb->data[MICROREAD_EMCF_T1_ATQA]);
@@ -525,6 +547,11 @@ static void microread_target_discovered(
targets->nfcid1_len = 4;
break;
case MICROREAD_GATE_ID_MREAD_NFC_T3:
+ if (skb->len < MICROREAD_EMCF_T3_UID + 8) {
+ r = -EINVAL;
+ goto exit_free;
+ }
+
targets->supported_protocols = NFC_PROTO_FELICA_MASK;
memcpy(targets->nfcid1, &skb->data[MICROREAD_EMCF_T3_UID], 8);
targets->nfcid1_len = 8;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 32/57] nfc: llcp: bound the connect_sn TLV walk to the skb
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (30 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 31/57] nfc: microread: validate target discovery payload lengths Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 33/57] nfc: llcp: fix OOB read and u8 offset wrap in TLV parsers Greg Kroah-Hartman
` (30 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Doruk Tan Ozturk, Simon Horman,
David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <doruk@0sec.ai>
commit 55c68ac93e7dacc0f5f608b9c39dd4ff48cf28e8 upstream.
Commit 27256cdb290e ("nfc: llcp: bound SNL TLV parsing to the skb and
add length checks") fixed the unbounded TLV walk in nfc_llcp_recv_snl(),
and commit d8bd2dedbde5 ("nfc: llcp: fix OOB read and u8 offset wrap in
TLV parsers") subsequently bounded nfc_llcp_parse_gb_tlv() and
nfc_llcp_parse_connection_tlv(). One sibling parser sharing the same
pattern remains unbounded: nfc_llcp_connect_sn().
nfc_llcp_connect_sn() walks a TLV list, reading a two-byte header
(type, length) followed by length bytes of value, without checking that
the two header bytes or the declared length stay within the buffer. It
returns a pointer to a service name of up to 255 bytes that may point
past the end of the skb; it is subsequently consumed by memcmp() in
nfc_llcp_sock_from_sn(). In addition tlv_array_len was computed as
"skb->len - LLCP_HEADER_SIZE" in size_t, so a CONNECT/CC frame shorter
than the LLCP header underflows to a huge length and the walk runs far
past the buffer.
nfc_llcp_connect_sn() is reachable from nfc_llcp_recv_connect() and
nfc_llcp_recv_cc(), i.e. from received CONNECT and CC PDUs. A nearby
NFC device can reach this without authentication; LLCP link activation
happens automatically after NFC-DEP, and the nfc_llcp_rx_skb()
dispatcher applies no minimum-length guard.
Walk the TLV list by pointer, bounded by skb_tail_pointer(skb), and
validate each declared length before use, matching the approach already
used for nfc_llcp_recv_snl(). Starting the walk at
&skb->data[LLCP_HEADER_SIZE] against the tail pointer also removes the
size_t underflow for short frames.
Found by 0sec automated security-research tooling (https://0sec.ai).
Fixes: d646960f7986 ("NFC: Initial LLCP support")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260709131229.44477-1-doruk@0sec.ai
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/nfc/llcp_core.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -856,13 +856,16 @@ static struct nfc_llcp_sock *nfc_llcp_so
static const u8 *nfc_llcp_connect_sn(const struct sk_buff *skb, size_t *sn_len)
{
u8 type, length;
- const u8 *tlv = &skb->data[2];
- size_t tlv_array_len = skb->len - LLCP_HEADER_SIZE, offset = 0;
+ const u8 *tlv = &skb->data[LLCP_HEADER_SIZE];
+ const u8 *tlv_end = skb_tail_pointer(skb);
- while (offset < tlv_array_len) {
+ while (tlv + 2 < tlv_end) {
type = tlv[0];
length = tlv[1];
+ if (tlv + 2 + length > tlv_end)
+ break;
+
pr_debug("type 0x%x length %d\n", type, length);
if (type == LLCP_TLV_SN) {
@@ -870,7 +873,6 @@ static const u8 *nfc_llcp_connect_sn(con
return &tlv[2];
}
- offset += length + 2;
tlv += length + 2;
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 33/57] nfc: llcp: fix OOB read and u8 offset wrap in TLV parsers
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (31 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 32/57] nfc: llcp: bound the connect_sn TLV walk to the skb Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 34/57] nfc: llcp: reject PDUs shorter than the LLCP header Greg Kroah-Hartman
` (29 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Muhammad Bilal, Simon Horman,
David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muhammad Bilal <meatuni001@gmail.com>
commit 78b20c8eeacd2e44a2d8a4cb5316d3c521d90911 upstream.
nfc_llcp_parse_gb_tlv() and nfc_llcp_parse_connection_tlv() contain
three related bugs in their TLV parsing loops:
1. 'offset' is declared u8 but tlv_array_len is u16. When TLV data
advances offset past 255 it silently wraps to zero, causing
infinite loops or double-processing of buffer data.
2. Before reading tlv[0] (type) and tlv[1] (length) there is no
check that offset+2 <= tlv_array_len. A truncated TLV causes
an OOB read of one byte past the buffer end.
3. After reading the length field, the value bytes are accessed
without checking offset+2+length <= tlv_array_len. A crafted
length=0xFF on a short buffer causes up to 255 bytes of OOB
read past the buffer end.
Both functions are reachable without authentication via
nfc_llcp_set_remote_gb() which feeds remote LLCP general bytes
directly into nfc_llcp_parse_gb_tlv() with no additional
validation.
Fix all three issues by widening offset from u8 to u16 and adding
bounds checks for both the TLV header and value field before each
access.
Fixes: 3df40eb3a2ea ("nfc: constify several pointers to u8, char and sk_buff")
Cc: stable@vger.kernel.org
Signed-off-by: Muhammad Bilal <meatuni001@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260622131802.239035-1-meatuni001@gmail.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/nfc/llcp_commands.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -193,7 +193,8 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llc
const u8 *tlv_array, u16 tlv_array_len)
{
const u8 *tlv = tlv_array;
- u8 type, length, offset = 0;
+ u8 type, length;
+ u16 offset = 0;
pr_debug("TLV array length %d\n", tlv_array_len);
@@ -201,9 +202,15 @@ int nfc_llcp_parse_gb_tlv(struct nfc_llc
return -ENODEV;
while (offset < tlv_array_len) {
+ if (offset + 2 > tlv_array_len)
+ return -EINVAL;
+
type = tlv[0];
length = tlv[1];
+ if (offset + 2 + length > tlv_array_len)
+ return -EINVAL;
+
pr_debug("type 0x%x length %d\n", type, length);
switch (type) {
@@ -243,7 +250,8 @@ int nfc_llcp_parse_connection_tlv(struct
const u8 *tlv_array, u16 tlv_array_len)
{
const u8 *tlv = tlv_array;
- u8 type, length, offset = 0;
+ u8 type, length;
+ u16 offset = 0;
pr_debug("TLV array length %d\n", tlv_array_len);
@@ -251,9 +259,15 @@ int nfc_llcp_parse_connection_tlv(struct
return -ENOTCONN;
while (offset < tlv_array_len) {
+ if (offset + 2 > tlv_array_len)
+ return -EINVAL;
+
type = tlv[0];
length = tlv[1];
+ if (offset + 2 + length > tlv_array_len)
+ return -EINVAL;
+
pr_debug("type 0x%x length %d\n", type, length);
switch (type) {
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 34/57] nfc: llcp: reject PDUs shorter than the LLCP header
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (32 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 33/57] nfc: llcp: fix OOB read and u8 offset wrap in TLV parsers Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 35/57] nfc: pn533: purge fragmented skbs during cleanup Greg Kroah-Hartman
` (28 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Laight, Doruk Tan Ozturk,
Vadim Fedorenko, David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <doruk@0sec.ai>
commit 95674f506c6376d6722a23144c9acd26609771ed upstream.
Every LLCP PDU begins with a two-byte header (DSAP/SSAP + PTYPE), but the
receive path never checked that a frame is at least LLCP_HEADER_SIZE bytes
before parsing it.
nfc_llcp_rx_skb() reads the header via nfc_llcp_ptype()/nfc_llcp_dsap()/
nfc_llcp_ssap(), which dereference pdu->data[0] and pdu->data[1], and a
CONNECT or CC PDU then computes
tlv_array_len = skb->len - LLCP_HEADER_SIZE;
as a size_t and hands it to the TLV walk. When the frame is shorter than
the header the subtraction wraps to a huge value and the walk runs far
past the buffer, an out-of-bounds read.
A nearby NFC device can reach this without authentication; LLCP link
activation happens automatically after NFC-DEP.
Guard the common receive choke point __nfc_llcp_recv(), shared by both the
target (nfc_llcp_data_received()) and initiator (nfc_llcp_recv()) paths, so
a short skb is dropped before the rx_work worker parses it. Use
pskb_may_pull() rather than a skb->len test so the two header bytes are
guaranteed to sit in the skb linear area even for a non-linear skb,
matching how the sibling NCI and HCI receive paths validate their headers.
Reproduced with a KFENCE out-of-bounds read via /dev/virtual_nci on
linux-next.
Found by 0sec automated security-research tooling (https://0sec.ai).
Fixes: d646960f7986 ("NFC: Initial LLCP support")
Cc: stable@vger.kernel.org
Suggested-by: David Laight <david.laight.linux@gmail.com>
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Link: https://patch.msgid.link/20260714164631.75068-1-doruk@0sec.ai
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/nfc/llcp_core.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/net/nfc/llcp_core.c
+++ b/net/nfc/llcp_core.c
@@ -1561,6 +1561,11 @@ static void nfc_llcp_rx_work(struct work
static void __nfc_llcp_recv(struct nfc_llcp_local *local, struct sk_buff *skb)
{
+ if (!pskb_may_pull(skb, LLCP_HEADER_SIZE)) {
+ kfree_skb(skb);
+ return;
+ }
+
local->rx_pending = skb;
del_timer(&local->link_timer);
schedule_work(&local->rx_work);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 35/57] nfc: pn533: purge fragmented skbs during cleanup
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (33 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 34/57] nfc: llcp: reject PDUs shorter than the LLCP header Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 36/57] nfc: st21nfca: validate ATR_REQ length against the received frame Greg Kroah-Hartman
` (27 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xu Rao, David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Rao <raoxu@uniontech.com>
commit 5718fc62198c38c2de5316020a90506f9e75e0bb upstream.
pn53x_common_clean() purges resp_q before freeing the common PN533 state,
but it leaves fragment_skb untouched. The fragmentation helpers queue
transmit fragments there while sending large initiator or target-mode
frames, and those skbs remain owned by the driver until they are sent or
discarded.
If the device is removed while fragments are still queued, the common
cleanup path frees the PN533 state without releasing the queued fragment
skbs, leaking them.
Purge fragment_skb during cleanup alongside resp_q.
Fixes: 963a82e07d4e ("NFC: pn533: Split large Tx frames in chunks")
Cc: stable@vger.kernel.org
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Link: https://patch.msgid.link/2D896607CAE4408E+20260720021444.3362044-1-raoxu@uniontech.com
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nfc/pn533/pn533.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/nfc/pn533/pn533.c
+++ b/drivers/nfc/pn533/pn533.c
@@ -2860,6 +2860,7 @@ void pn53x_common_clean(struct pn533 *pr
destroy_workqueue(priv->wq);
skb_queue_purge(&priv->resp_q);
+ skb_queue_purge(&priv->fragment_skb);
list_for_each_entry_safe(cmd, n, &priv->cmd_queue, queue) {
list_del(&cmd->queue);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 36/57] nfc: st21nfca: validate ATR_REQ length against the received frame
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (34 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 35/57] nfc: pn533: purge fragmented skbs during cleanup Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 37/57] nfc: nci: fix out-of-bounds write in nci_target_auto_activated() Greg Kroah-Hartman
` (26 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Doruk Tan Ozturk, Simon Horman,
David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Doruk Tan Ozturk <doruk@0sec.ai>
commit 5cdcca5d62a66eda6b774110a44cba67bc1a8d1d upstream.
st21nfca_tm_recv_atr_req() checks that the received ATR_REQ frame is at
least ST21NFCA_ATR_REQ_MIN_SIZE and that the self-declared atr_req->length
is at least sizeof(struct st21nfca_atr_req), but never checks that
atr_req->length does not exceed the actual received length (skb->len).
st21nfca_tm_send_atr_res() then trusts the declared length:
gb_len = atr_req->length - sizeof(struct st21nfca_atr_req);
...
memcpy(atr_res->gbi, atr_req->gbi, gb_len);
so an RF peer that sends a short frame but sets atr_req->length larger
than the frame makes gb_len exceed the general bytes actually present,
and the memcpy reads out of bounds past the received skb. Those bytes are
placed in the ATR_RES and sent back to the peer (kernel-memory disclosure
to a proximity attacker); a larger declared length is an out-of-bounds
read (DoS).
Reject frames whose declared length exceeds the received length. The
adjacent nfc_tm_activated() path in the same function already derives its
general-bytes length from skb->len rather than the declared field.
Found by 0sec (https://0sec.ai) using automated source analysis; the
missing bound is evident from source. Compile-tested.
Fixes: 1892bf844ea0 ("NFC: st21nfca: Adding P2P support to st21nfca in Initiator & Target mode")
Cc: stable@vger.kernel.org
Assisted-by: 0sec:claude-opus-4-8
Signed-off-by: Doruk Tan Ozturk <doruk@0sec.ai>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260711071301.58071-1-doruk@0sec.ai
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nfc/st21nfca/dep.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/nfc/st21nfca/dep.c
+++ b/drivers/nfc/st21nfca/dep.c
@@ -213,6 +213,9 @@ static int st21nfca_tm_recv_atr_req(stru
goto exit;
}
+ if (atr_req->length > skb->len)
+ return -EPROTO;
+
r = st21nfca_tm_send_atr_res(hdev, atr_req);
if (r)
goto exit;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 37/57] nfc: nci: fix out-of-bounds write in nci_target_auto_activated()
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (35 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 36/57] nfc: st21nfca: validate ATR_REQ length against the received frame Greg Kroah-Hartman
@ 2026-08-25 13:26 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 38/57] nfc: nci: free destination parameters when closing a connection Greg Kroah-Hartman
` (25 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:26 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Samuel Page, Simon Horman,
David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samuel Page <sam@bynar.io>
commit ac200079db50af81e6b04d058b33ec92901d8edd upstream.
nci_target_auto_activated() appends a target to the fixed-size array
ndev->targets[NCI_MAX_DISCOVERED_TARGETS] and increments ndev->n_targets
without first checking the array is full; unlike its sibling
nci_add_new_target(), which bails out when n_targets already equals
NCI_MAX_DISCOVERED_TARGETS.
ndev->n_targets is only cleared by nci_clear_target_list(), so an NFCC
that repeatedly re-runs discovery (RF_DISCOVER_RSP, which re-enters
NCI_DISCOVERY without clearing the target list) and reports an
auto-activated target (RF_INTF_ACTIVATED_NTF) drives n_targets past the
limit. The append then writes a struct nfc_target past the end of the
array (a slab out-of-bounds write), and nfc_targets_found() goes on to
walk the array with the inflated count:
BUG: KASAN: slab-out-of-bounds in nci_add_new_protocol+0x94/0x2ac [nci]
Write of size 2 at addr ffff0000c7299a18 by task kworker/u8:0/12
Workqueue: nfc0_nci_rx_wq nci_rx_work [nci]
Call trace:
nci_add_new_protocol+0x94/0x2ac [nci]
nci_ntf_packet+0xddc/0x11a0 [nci]
nci_rx_work+0x15c/0x1e0 [nci]
process_one_work+0x2dc/0x500
worker_thread+0x240/0x460
kthread+0x1c0/0x1d0
ret_from_fork+0x10/0x20
The buggy address belongs to the cache kmalloc-2k of size 2048
The buggy address is located 1024 bytes to the right of
allocated 1560-byte region [ffff0000c7299000, ffff0000c7299618)
Guard nci_target_auto_activated() with the same check used by
nci_add_new_target().
Fixes: 019c4fbaa790 ("NFC: Add NCI multiple targets support")
Cc: stable@vger.kernel.org
Assisted-by: Bynario AI
Signed-off-by: Samuel Page <sam@bynar.io>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260622145243.3167276-1-sam@bynar.io
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/nfc/nci/ntf.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/net/nfc/nci/ntf.c
+++ b/net/nfc/nci/ntf.c
@@ -448,6 +448,12 @@ static void nci_target_auto_activated(st
struct nfc_target *target;
int rc;
+ /* This is a new target, check if we've enough room */
+ if (ndev->n_targets == NCI_MAX_DISCOVERED_TARGETS) {
+ pr_debug("not enough room, ignoring new target...\n");
+ return;
+ }
+
target = &ndev->targets[ndev->n_targets];
rc = nci_add_new_protocol(ndev, target, ntf->rf_protocol,
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 38/57] nfc: nci: free destination parameters when closing a connection
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (36 preceding siblings ...)
2026-08-25 13:26 ` [PATCH 5.10 37/57] nfc: nci: fix out-of-bounds write in nci_target_auto_activated() Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 39/57] xfs: bounds-check buffer log items dirty bitmap Greg Kroah-Hartman
` (24 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Linmao Li, Vadim Fedorenko,
David Heidelberg
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linmao Li <lilinmao@kylinos.cn>
commit 2e65bafdfd3a8bba972b3d17b6a57816557530fc upstream.
When a connection is closed, nci_core_conn_close_rsp_packet() frees
conn_info but not conn_info->dest_params, which is a separate devm
allocation. Each connect/close cycle leaks one dest_params until the
NFC device is removed. Free dest_params along with conn_info.
Fixes: 9b8d1a4cf2aa ("nfc: nci: Add an additional parameter to identify a connection id")
Cc: stable@vger.kernel.org
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Link: https://patch.msgid.link/20260721023518.1697625-1-lilinmao@kylinos.cn
Signed-off-by: David Heidelberg <david@ixit.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/nfc/nci/rsp.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/nfc/nci/rsp.c
+++ b/net/nfc/nci/rsp.c
@@ -279,6 +279,7 @@ static void nci_core_conn_close_rsp_pack
list_del(&conn_info->list);
if (conn_info == ndev->rf_conn_info)
ndev->rf_conn_info = NULL;
+ devm_kfree(&ndev->nfc_dev->dev, conn_info->dest_params);
devm_kfree(&ndev->nfc_dev->dev, conn_info);
}
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 39/57] xfs: bounds-check buffer log items dirty bitmap
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (37 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 38/57] nfc: nci: free destination parameters when closing a connection Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 40/57] ipv4: reject undersized MTUs in ip_do_fragment() Greg Kroah-Hartman
` (23 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ibrahim Hashimov, Darrick J. Wong,
Brian Foster, Carlos Maiolino, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ibrahim Hashimov <security@auditcode.ai>
commit 813f8136a2ce1fee266d02a7df73db6e8a541604 upstream.
xlog_recover_do_reg_buffer() replays each dirty region described by a
buffer log item's bitmap into the buffer read for that item:
memcpy(xfs_buf_offset(bp, (uint)bit << XFS_BLF_SHIFT),
item->ri_buf[i].iov_base,
nbits << XFS_BLF_SHIFT);
The destination offset (bit/nbits, from the logged dirty bitmap) and the
buffer size (from the logged blf_len) are both attacker-controlled and
otherwise unrelated, yet the only thing bounding the copy is an ASSERT(),
which compiles away on production kernels. A crafted image logging a
small blf_len together with a bitmap bit past the end of that buffer
drives the memcpy() past the buffer's allocation, corrupting adjacent
kernel heap during mount-time log recovery. This is reachable by anyone
who can get a crafted image mounted -- the malicious-filesystem threat
model XFS already guards against elsewhere.
Turn the ASSERT() into a real XFS_IS_CORRUPT() check that aborts recovery
of the buffer with -EFSCORRUPTED, consistent with the validate-and-fail
idiom already used in xlog_recover_do_inode_buffer() and
xfs_dquot_item_recover.c. xlog_recover_do_reg_buffer() therefore becomes
STATIC int and its three callers propagate the error.
Found and confirmed with KASAN on a CONFIG_XFS_DEBUG=n build: the crafted
image trips a slab-out-of-bounds write before this change and fails
recovery cleanly with -EFSCORRUPTED after it.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_buf_item_recover.c | 53 ++++++++++++++++++++++++++++++------------
1 file changed, 38 insertions(+), 15 deletions(-)
--- a/fs/xfs/xfs_buf_item_recover.c
+++ b/fs/xfs/xfs_buf_item_recover.c
@@ -432,7 +432,7 @@ xlog_recover_validate_buf_type(
* given buffer. The bitmap in the buf log format structure indicates
* where to place the logged data.
*/
-STATIC void
+STATIC int
xlog_recover_do_reg_buffer(
struct xfs_mount *mp,
struct xlog_recover_item *item,
@@ -460,8 +460,24 @@ xlog_recover_do_reg_buffer(
ASSERT(nbits > 0);
ASSERT(item->ri_buf[i].i_addr != NULL);
ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0);
- ASSERT(BBTOB(bp->b_length) >=
- ((uint)bit << XFS_BLF_SHIFT) + (nbits << XFS_BLF_SHIFT));
+ /*
+ * The bitmap is only trustworthy to the extent that it
+ * describes a region that actually fits inside the buffer we
+ * read in based on the (attacker-controlled) blf_len. Do not
+ * rely on an ASSERT() for this -- it compiles away entirely on
+ * non-DEBUG kernels, which is exactly where this matters, so
+ * validate it for real and abort recovery of this buffer rather
+ * than copying past the end of it.
+ */
+ if (XFS_IS_CORRUPT(mp, BBTOB(bp->b_length) <
+ ((uint)bit << XFS_BLF_SHIFT) +
+ (nbits << XFS_BLF_SHIFT))) {
+ xfs_alert(mp,
+ "Bad buffer log item dirty bitmap (bit %d, nbits %d) for %d-byte buffer at daddr 0x%llx.",
+ bit, nbits, BBTOB(bp->b_length),
+ bp->b_bn);
+ return -EFSCORRUPTED;
+ }
/*
* The dirty regions logged in the buffer, even though
@@ -515,6 +531,7 @@ xlog_recover_do_reg_buffer(
ASSERT(i == item->ri_total);
xlog_recover_validate_buf_type(mp, bp, buf_f, current_lsn);
+ return 0;
}
/*
@@ -523,10 +540,10 @@ xlog_recover_do_reg_buffer(
* (ie. USR or GRP), then just toss this buffer away; don't recover it.
* Else, treat it as a regular buffer and do recovery.
*
- * Return false if the buffer was tossed and true if we recovered the buffer to
- * indicate to the caller if the buffer needs writing.
+ * Return 0 if the buffer was not recovered (tossed), 1 if it was recovered and
+ * needs writing, or a negative errno if recovery of the buffer failed.
*/
-STATIC bool
+STATIC int
xlog_recover_do_dquot_buffer(
struct xfs_mount *mp,
struct xlog *log,
@@ -535,6 +552,7 @@ xlog_recover_do_dquot_buffer(
struct xfs_buf_log_format *buf_f)
{
uint type;
+ int error;
trace_xfs_log_recover_buf_dquot_buf(log, buf_f);
@@ -542,7 +560,7 @@ xlog_recover_do_dquot_buffer(
* Filesystems are required to send in quota flags at mount time.
*/
if (!mp->m_qflags)
- return false;
+ return 0;
type = 0;
if (buf_f->blf_flags & XFS_BLF_UDQUOT_BUF)
@@ -555,10 +573,12 @@ xlog_recover_do_dquot_buffer(
* This type of quotas was turned off, so ignore this buffer
*/
if (log->l_quotaoffs_flag & type)
- return false;
+ return 0;
- xlog_recover_do_reg_buffer(mp, item, bp, buf_f, NULLCOMMITLSN);
- return true;
+ error = xlog_recover_do_reg_buffer(mp, item, bp, buf_f, NULLCOMMITLSN);
+ if (error)
+ return error;
+ return 1;
}
/*
@@ -943,13 +963,16 @@ xlog_recover_buf_commit_pass2(
goto out_release;
} else if (buf_f->blf_flags &
(XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) {
- bool dirty;
-
- dirty = xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
- if (!dirty)
+ error = xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f);
+ if (error <= 0)
goto out_release;
+ /* write dirty buffer */
+ error = 0;
} else {
- xlog_recover_do_reg_buffer(mp, item, bp, buf_f, current_lsn);
+ error = xlog_recover_do_reg_buffer(mp, item, bp, buf_f,
+ current_lsn);
+ if (error)
+ goto out_release;
}
/*
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 40/57] ipv4: reject undersized MTUs in ip_do_fragment()
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (38 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 39/57] xfs: bounds-check buffer log items dirty bitmap Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 41/57] ipv6: fix use-after-free in ip6_finish_output2() Greg Kroah-Hartman
` (22 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Yong Wang, Ren Wei,
Ido Schimmel, Jakub Kicinski
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yong Wang <edragain@163.com>
commit c0726f0caf8c6b3208552949e17d23634a2f3129 upstream.
ip_do_fragment() subtracts the IPv4 header length from the effective
MTU and passes the resulting payload MTU to ip_frag_next().
If the effective MTU is smaller than hlen + 8, ip_frag_next() rounds
the fragment payload length down to zero. The fragmentation state then
never makes forward progress: state->left, state->ptr and state->offset
stay unchanged while ip_do_fragment() keeps allocating and transmitting
header-only fragments until the softlockup detector fires.
This is reproducible with a route installed using "mtu lock 20", but it
is also reproducible without route MTU lock, for example by forwarding a
packet to a device whose MTU is 20.
Fix it in ip_do_fragment() by rejecting mtu < hlen + 8 with -EMSGSIZE,
matching the existing IPv6 fragmentation check.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Yong Wang <edragain@163.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/8809ef6314b98913681b0b370a05a85c2b6cd579.1786599079.git.edragain@163.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/ip_output.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -798,6 +798,10 @@ int ip_do_fragment(struct net *net, stru
*/
hlen = iph->ihl * 4;
+ if (mtu < hlen + 8) {
+ err = -EMSGSIZE;
+ goto fail;
+ }
mtu = mtu - hlen; /* Size of data space */
IPCB(skb)->flags |= IPSKB_FRAG_COMPLETE;
ll_rs = LL_RESERVED_SPACE(rt->dst.dev);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 41/57] ipv6: fix use-after-free in ip6_finish_output2()
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (39 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 40/57] ipv4: reject undersized MTUs in ip_do_fragment() Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 42/57] nvmet-fc: fix invalid free in LS IOD error path Greg Kroah-Hartman
` (21 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxiao Xu, Ren Wei,
Vadim Fedorenko, Ido Schimmel, Jakub Kicinski
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luxiao Xu <rakukuip@gmail.com>
commit d0d48d999b0eee6bb176ef4e39d9be868fa80f7e upstream.
ip6_finish_output2() caches a pointer to the IPv6 destination
address (daddr) before invoking lwtunnel_xmit(). The LWT-BPF
transmit path or other encapsulation operations within
lwtunnel_xmit() can reallocate the skb head, freeing the memory
that daddr points to. When lwtunnel_xmit() returns
LWTUNNEL_XMIT_CONTINUE, the function continues to use the stale
daddr pointer to compute the nexthop and to look up or create the
neighbour entry. This results in a use-after-free read, which can
leak sensitive kernel data, pollute the neighbour table with
arbitrary values, misdirect traffic, or crash the system.
Fix this by re-fetching the IPv6 header and the destination
address pointer after lwtunnel_xmit() returns
LWTUNNEL_XMIT_CONTINUE, ensuring that the subsequent nexthop
computation and neighbour lookup operate on valid memory.
Fixes: e415ed3a4b8b ("ipv6: use skb_expand_head in ip6_finish_output2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Luxiao Xu <rakukuip@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/4aa3f53bc44e79572c6dd2340ec7b68ef1a3d87d.1786516730.git.rakukuip@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/ip6_output.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -118,6 +118,8 @@ static int ip6_finish_output2(struct net
if (res != LWTUNNEL_XMIT_CONTINUE)
return res;
+ hdr = ipv6_hdr(skb);
+ daddr = &hdr->daddr;
}
rcu_read_lock_bh();
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 42/57] nvmet-fc: fix invalid free in LS IOD error path
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (40 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 41/57] ipv6: fix use-after-free in ip6_finish_output2() Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 43/57] nvmet-tcp: Do not WARN on remotely-controlled oversized SGL allocations Greg Kroah-Hartman
` (20 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maurizio Lombardi, Jiang HongHui,
Keith Busch
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiang HongHui <jiang_hh2019@163.com>
commit ba98d6796d12258e837ece065d2ecb59d76ce4ff upstream.
nvmet_fc_alloc_ls_iodlist() advances iod while initializing the LS IOD
array. If an rqstbuf allocation or response buffer DMA mapping fails,
the unwind loop decrements iod past the start of the array. The final
kfree(iod) therefore frees an address before the allocated object.
This can be reproduced with nvme-fcloop and failslab by setting
fail-nth to 6 before creating a target port. KASAN reports:
BUG: KASAN: invalid-free in nvmet_fc_register_targetport
Free of addr ffff88816cf8ff48 by task nvmet_fail_nth/9552
Free the original allocation base stored in tgtport->iod instead. With
this fix applied, the same sysfs write with fail-nth=6 returns -ENOMEM
without any KASAN report.
Fixes: c53432030d86 ("nvme-fabrics: Add target support for FC transport")
Cc: stable@vger.kernel.org
Reviewed-by: Maurizio Lombardi <mlombard@redhat.com>
Assisted-by: Codex:gpt-5
Signed-off-by: Jiang HongHui <jiang_hh2019@163.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvme/target/fc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/nvme/target/fc.c
+++ b/drivers/nvme/target/fc.c
@@ -560,7 +560,7 @@ out_fail:
list_del(&iod->ls_rcv_list);
}
- kfree(iod);
+ kfree(tgtport->iod);
return -EFAULT;
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 43/57] nvmet-tcp: Do not WARN on remotely-controlled oversized SGL allocations
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (41 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 42/57] nvmet-fc: fix invalid free in LS IOD error path Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 44/57] gpio: ml-ioh: use raw_spinlock_t for the register lock Greg Kroah-Hartman
` (19 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Keith Busch
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
commit 737a3b535247226f6e1a7988fd9d6e63e7d6fc71 upstream.
When fuzzing the nvme target code, I tripped a kernel warning in
nvmet_tcp_map_data() because the length passed into the allocator is
controlled by the remote initiator.
A remote initiator that sends a command with an SGL claiming a huge
number, can create a scatterlist and iovec allocation of over 1 million
entries, which causes the backing kmalloc call to exceed MAX_PAGE_ORDER
and then the page allocator will trip on a WARN_ON_ONCE_GFP() message:
WARNING: mm/page_alloc.c:5280 __alloc_frozen_pages_noprof
Workqueue: nvmet_tcp_wq nvmet_tcp_io_work
...
sgl_alloc_order
nvmet_tcp_map_data
nvmet_tcp_try_recv_pdu
As it's never good to trip a kernel warning remotely due to many systems
having panic-on-warn enabled, let's silence it by just add GFP_NOWARN to
the allocation flags.
Assisted-by: gkh_clanker_2000
Cc: stable <stable@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/nvme/target/tcp.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -393,14 +393,15 @@ static int nvmet_tcp_map_data(struct nvm
}
cmd->req.transfer_len += len;
- cmd->req.sg = sgl_alloc(len, GFP_KERNEL, &cmd->req.sg_cnt);
+ cmd->req.sg = sgl_alloc(len, GFP_KERNEL | __GFP_NOWARN,
+ &cmd->req.sg_cnt);
if (!cmd->req.sg)
return NVME_SC_INTERNAL;
cmd->cur_sg = cmd->req.sg;
if (nvmet_tcp_has_data_in(cmd)) {
cmd->iov = kmalloc_array(cmd->req.sg_cnt,
- sizeof(*cmd->iov), GFP_KERNEL);
+ sizeof(*cmd->iov), GFP_KERNEL | __GFP_NOWARN);
if (!cmd->iov)
goto err;
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 44/57] gpio: ml-ioh: use raw_spinlock_t for the register lock
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (42 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 43/57] nvmet-tcp: Do not WARN on remotely-controlled oversized SGL allocations Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 45/57] libceph: fix OOB read in decode_watchers() via missing bounds check Greg Kroah-Hartman
` (18 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Junjie Cao,
Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junjie Cao <junjie.cao@intel.com>
[ Upstream commit 600411ea1f2443fdf5b1af9b6480f616d7aff9d0 ]
ioh_irq_type() is registered as the irq_chip .irq_set_type callback and
takes chip->spinlock with spin_lock_irqsave(). This callback is reached
from __setup_irq() -> __irq_set_trigger() -> chip->irq_set_type() while
the caller holds desc->lock, a raw_spinlock_t, with hardirqs disabled.
That context is not sleepable, but on PREEMPT_RT a regular spinlock_t is
an rtmutex-backed sleeping lock, so acquiring it there is invalid.
ioh_irq_enable() and ioh_irq_disable() take the same lock from the
.irq_enable/.irq_disable callbacks, which are likewise invoked with
desc->lock held.
Convert the register lock to raw_spinlock_t. The same lock also
serializes the GPIO direction/value callbacks and the suspend/resume
register save/restore, and those critical sections only perform short
sequences of MMIO register accesses (ioread32()/iowrite32()); the
.irq_set_type callback additionally emits a dev_warn() on an unsupported
type. None of these are sleepable operations, so keeping this register
lock non-sleeping is appropriate for the irqchip callbacks and does not
change the GPIO-side locking contract.
This is the same fix as commit a02b8950d619 ("gpio: pch: use
raw_spinlock_t for the register lock"); this driver shares the same
structure as gpio-pch.
Fixes: 54be566317b6 ("gpio-ml-ioh: Support interrupt function")
Cc: stable@vger.kernel.org
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260731032747.2987292-1-junjie.cao@intel.com
Signed-off-by: Junjie Cao <junjie.cao@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpio/gpio-ml-ioh.c | 36 ++++++++++++++++++------------------
1 file changed, 18 insertions(+), 18 deletions(-)
--- a/drivers/gpio/gpio-ml-ioh.c
+++ b/drivers/gpio/gpio-ml-ioh.c
@@ -84,7 +84,7 @@ struct ioh_gpio {
u32 gpio_use_sel;
int ch;
int irq_base;
- spinlock_t spinlock;
+ raw_spinlock_t spinlock;
};
static const int num_ports[] = {6, 12, 16, 16, 15, 16, 16, 12};
@@ -95,7 +95,7 @@ static void ioh_gpio_set(struct gpio_chi
struct ioh_gpio *chip = gpiochip_get_data(gpio);
unsigned long flags;
- spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&chip->spinlock, flags);
reg_val = ioread32(&chip->reg->regs[chip->ch].po);
if (val)
reg_val |= (1 << nr);
@@ -103,7 +103,7 @@ static void ioh_gpio_set(struct gpio_chi
reg_val &= ~(1 << nr);
iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
- spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(&chip->spinlock, flags);
}
static int ioh_gpio_get(struct gpio_chip *gpio, unsigned nr)
@@ -121,7 +121,7 @@ static int ioh_gpio_direction_output(str
u32 reg_val;
unsigned long flags;
- spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&chip->spinlock, flags);
pm = ioread32(&chip->reg->regs[chip->ch].pm) &
((1 << num_ports[chip->ch]) - 1);
pm |= (1 << nr);
@@ -134,7 +134,7 @@ static int ioh_gpio_direction_output(str
reg_val &= ~(1 << nr);
iowrite32(reg_val, &chip->reg->regs[chip->ch].po);
- spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(&chip->spinlock, flags);
return 0;
}
@@ -145,12 +145,12 @@ static int ioh_gpio_direction_input(stru
u32 pm;
unsigned long flags;
- spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&chip->spinlock, flags);
pm = ioread32(&chip->reg->regs[chip->ch].pm) &
((1 << num_ports[chip->ch]) - 1);
pm &= ~(1 << nr);
iowrite32(pm, &chip->reg->regs[chip->ch].pm);
- spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(&chip->spinlock, flags);
return 0;
}
@@ -256,7 +256,7 @@ static int ioh_irq_type(struct irq_data
dev_dbg(chip->dev, "%s:irq=%d type=%d ch=%d pos=%d type=%d\n",
__func__, irq, type, ch, im_pos, type);
- spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&chip->spinlock, flags);
switch (type) {
case IRQ_TYPE_EDGE_RISING:
@@ -296,7 +296,7 @@ static int ioh_irq_type(struct irq_data
ien = ioread32(&chip->reg->regs[chip->ch].ien);
iowrite32(ien | BIT(ch), &chip->reg->regs[chip->ch].ien);
end:
- spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(&chip->spinlock, flags);
return 0;
}
@@ -326,11 +326,11 @@ static void ioh_irq_disable(struct irq_d
unsigned long flags;
u32 ien;
- spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&chip->spinlock, flags);
ien = ioread32(&chip->reg->regs[chip->ch].ien);
ien &= ~(1 << (d->irq - chip->irq_base));
iowrite32(ien, &chip->reg->regs[chip->ch].ien);
- spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(&chip->spinlock, flags);
}
static void ioh_irq_enable(struct irq_data *d)
@@ -340,11 +340,11 @@ static void ioh_irq_enable(struct irq_da
unsigned long flags;
u32 ien;
- spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&chip->spinlock, flags);
ien = ioread32(&chip->reg->regs[chip->ch].ien);
ien |= 1 << (d->irq - chip->irq_base);
iowrite32(ien, &chip->reg->regs[chip->ch].ien);
- spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(&chip->spinlock, flags);
}
static irqreturn_t ioh_gpio_handler(int irq, void *dev_id)
@@ -441,7 +441,7 @@ static int ioh_gpio_probe(struct pci_dev
chip->base = base;
chip->reg = chip->base;
chip->ch = i;
- spin_lock_init(&chip->spinlock);
+ raw_spin_lock_init(&chip->spinlock);
ioh_gpio_setup(chip, num_ports[i]);
ret = gpiochip_add_data(&chip->gpio, chip);
if (ret) {
@@ -529,9 +529,9 @@ static int ioh_gpio_suspend(struct pci_d
struct ioh_gpio *chip = pci_get_drvdata(pdev);
unsigned long flags;
- spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&chip->spinlock, flags);
ioh_gpio_save_reg_conf(chip);
- spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(&chip->spinlock, flags);
ret = pci_save_state(pdev);
if (ret) {
@@ -563,11 +563,11 @@ static int ioh_gpio_resume(struct pci_de
}
pci_restore_state(pdev);
- spin_lock_irqsave(&chip->spinlock, flags);
+ raw_spin_lock_irqsave(&chip->spinlock, flags);
iowrite32(0x01, &chip->reg->srst);
iowrite32(0x00, &chip->reg->srst);
ioh_gpio_restore_reg_conf(chip);
- spin_unlock_irqrestore(&chip->spinlock, flags);
+ raw_spin_unlock_irqrestore(&chip->spinlock, flags);
return 0;
}
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 45/57] libceph: fix OOB read in decode_watchers() via missing bounds check
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (43 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 44/57] gpio: ml-ioh: use raw_spinlock_t for the register lock Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 46/57] HID: magicmouse: Prevent out-of-bounds (OOB) read during DOUBLE_REPORT_ID Greg Kroah-Hartman
` (17 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pavitra Jha, Viacheslav Dubeyko,
Ilya Dryomov, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavitra Jha <jhapavitra98@gmail.com>
[ Upstream commit 00ead17c7de137a692edee59f2772e6af687e8eb ]
ceph_start_decoding() validates that struct_len bytes remain in the
buffer after the encoding header, but accepts struct_len=0 as valid:
ceph_decode_need(p, end, 0, bad) always passes. When a malicious or
compromised OSD sends an obj_list_watch_response_t reply with
struct_len=0, ceph_start_decoding() returns success with p == end,
leaving zero bytes guaranteed for subsequent reads.
The immediately following ceph_decode_32(p) in decode_watchers() has
no preceding bounds check. With p == end this is a 4-byte read past
the validated buffer boundary. The garbage value is then passed
directly to kzalloc_objs() as the watcher count.
The sibling function decode_watcher() already uses the safe variants
(ceph_decode_copy_safe, ceph_decode_64_safe, ceph_decode_skip_32)
after its own ceph_start_decoding() call. decode_watchers() is the
only site that uses the bare variant, confirming an oversight.
Fix by replacing ceph_decode_32(p) with ceph_decode_32_safe(p, end,
*num_watchers, bad), consistent with the established pattern.
Attacker model: a malicious or compromised OSD in a multi-tenant Ceph
deployment (e.g. cloud) can trigger this against any kernel client
that calls CEPH_OSD_OP_LIST_WATCHERS, without any further privileges
beyond OSD session establishment.
[ idryomov: trim changelog ]
Cc: stable@vger.kernel.org
Fixes: a4ed38d7a180 ("libceph: support for CEPH_OSD_OP_LIST_WATCHERS")
Signed-off-by: Pavitra Jha <jhapavitra98@gmail.com>
Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ceph/osd_client.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -4993,7 +4993,7 @@ static int decode_watchers(void **p, voi
if (ret)
return ret;
- *num_watchers = ceph_decode_32(p);
+ ceph_decode_32_safe(p, end, *num_watchers, bad);
*watchers = kcalloc(*num_watchers, sizeof(**watchers), GFP_NOIO);
if (!*watchers)
return -ENOMEM;
@@ -5007,6 +5007,9 @@ static int decode_watchers(void **p, voi
}
return 0;
+
+bad:
+ return -EINVAL;
}
/*
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 46/57] HID: magicmouse: Prevent out-of-bounds (OOB) read during DOUBLE_REPORT_ID
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (44 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 45/57] libceph: fix OOB read in decode_watchers() via missing bounds check Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 47/57] HID: core: fix OOB read of field->usage in hid_set_field() Greg Kroah-Hartman
` (16 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lee Jones, Günther Noack,
Jiri Kosina
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lee Jones <lee@kernel.org>
commit d93ba918a185aca2594da63e92fdc5495b559c0f upstream.
It is currently possible for a malicious or misconfigured USB device to
cause an out-of-bounds (OOB) read when submitting reports using
DOUBLE_REPORT_ID by specifying a large report length and providing a
smaller one.
Let's prevent that by comparing the specified report length with the
actual size of the data read in from userspace. If the actual data
length ends up being smaller than specified, we'll politely warn the
user and prevent any further processing.
Signed-off-by: Lee Jones <lee@kernel.org>
Reviewed-by: Günther Noack <gnoack@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-magicmouse.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -312,6 +312,10 @@ static int magicmouse_raw_event(struct h
struct input_dev *input = msc->input;
int x = 0, y = 0, ii, clicks = 0, npoints;
+ /* Protect against zero sized recursive calls from DOUBLE_REPORT_ID */
+ if (size < 1)
+ return 0;
+
switch (data[0]) {
case TRACKPAD_REPORT_ID:
case TRACKPAD2_BT_REPORT_ID:
@@ -384,6 +388,18 @@ static int magicmouse_raw_event(struct h
/* Sometimes the trackpad sends two touch reports in one
* packet.
*/
+
+ /* Ensure that we have at least 2 elements (report type and size) */
+ if (size < 2)
+ return 0;
+
+ if (size < data[1] + 2) {
+ hid_warn(hdev,
+ "received report length (%d) was smaller than specified (%d)",
+ size, data[1] + 2);
+ return 0;
+ }
+
magicmouse_raw_event(hdev, report, data + 2, data[1]);
magicmouse_raw_event(hdev, report, data + 2 + data[1],
size - 2 - data[1]);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 47/57] HID: core: fix OOB read of field->usage in hid_set_field()
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (45 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 46/57] HID: magicmouse: Prevent out-of-bounds (OOB) read during DOUBLE_REPORT_ID Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 48/57] Revert "Input: ims-pcu - fix race condition in reset_device sysfs callback" Greg Kroah-Hartman
` (15 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Federico Kirschbaum, Baul Lee,
Jiri Kosina
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baul Lee <baul.lee@xbow.com>
commit a13cdb19fcb223ed41bdab3bab42b98dba87e90b upstream.
hid_set_field() hands field->usage + offset to hid_dump_input() before
the guard that bounds offset:
hid_dump_input(field->report->device, field->usage + offset, value);
if (offset >= field->report_count) {
hid_err(...);
return -1;
}
Under CONFIG_DEBUG_FS hid_dump_input() dereferences that pointer, with
buf = hid_resolv_usage(usage->hid, NULL). The usage[] array is
allocated inline with the hid_field in hid_register_field() and holds
field->maxusage entries, so an offset past it reads off the end of the
kvzalloc()ed allocation and into a neighbouring object. Had the guard
run first, offset < report_count <= maxusage would already have confined
the pointer to the array.
A caller supplies such an offset today. picolcd_fb_send_tile()
validates only report->maxfield before issuing
hid_set_field(report->field[0], 11 + i, ...) for i = 0..31, so its
offsets are fixed at 11..42 and are never checked against the bound
field. When the device registers that field with fewer usages, the
framebuffer deferred-io work drives the read on every tile. KASAN
reports a 4-byte slab-out-of-bounds read in hid_dump_input() below
hid_set_field(), and the same boot logs "offset (1) exceeds
report_count (1)" from the guard that runs only afterwards.
Move the hid_dump_input() call below the guard. Because
field->maxusage >= field->report_count, the guard then establishes that
field->usage + offset lies inside the array before it is dereferenced,
for every caller and without changing behaviour on the valid path.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Federico Kirschbaum <federico.kirschbaum@xbow.com>
Reported-by: Baul Lee <baul.lee@xbow.com>
Cc: stable@vger.kernel.org
Signed-off-by: Baul Lee <baul.lee@xbow.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-core.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1696,13 +1696,14 @@ int hid_set_field(struct hid_field *fiel
size = field->report_size;
- hid_dump_input(field->report->device, field->usage + offset, value);
-
if (offset >= field->report_count) {
hid_err(field->report->device, "offset (%d) exceeds report_count (%d)\n",
offset, field->report_count);
return -1;
}
+
+ hid_dump_input(field->report->device, field->usage + offset, value);
+
if (field->logical_minimum < 0) {
if (value != snto32(s32ton(value, size), size)) {
hid_err(field->report->device, "value %d is out of range\n", value);
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 48/57] Revert "Input: ims-pcu - fix race condition in reset_device sysfs callback"
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (46 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 47/57] HID: core: fix OOB read of field->usage in hid_set_field() Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 49/57] xfrm: fix sk_dst_cache double-free in xfrm_user_policy() Greg Kroah-Hartman
` (14 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit 8b9ff928aa71a2ff6f559da45821b64fa4886a75.
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/input/misc/ims-pcu.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
index 1df5e773a1f34..5d2d1797ee209 100644
--- a/drivers/input/misc/ims-pcu.c
+++ b/drivers/input/misc/ims-pcu.c
@@ -1192,8 +1192,6 @@ static ssize_t ims_pcu_reset_device(struct device *dev,
dev_info(pcu->dev, "Attempting to reset device\n");
- guard(mutex)(&pcu->cmd_mutex);
-
error = ims_pcu_execute_command(pcu, PCU_RESET, &reset_byte, 1);
if (error) {
dev_info(pcu->dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 5.10 49/57] xfrm: fix sk_dst_cache double-free in xfrm_user_policy()
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (47 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 48/57] Revert "Input: ims-pcu - fix race condition in reset_device sysfs callback" Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 50/57] iomap: adjust read range correctly for non-block-aligned positions Greg Kroah-Hartman
` (13 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, AutonomousCodeSecurity,
Xiang Mei (Microsoft), Steffen Klassert, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiang Mei (Microsoft) <xmei5@asu.edu>
[ Upstream commit c283e9ada7fcb7dd4b10592623086b2e6d2f9925 ]
xfrm_user_policy() clears the socket dst cache with __sk_dst_reset(),
i.e. the non-atomic __sk_dst_set(sk, NULL): it reads sk_dst_cache with
rcu_dereference_protected(), stores NULL and dst_release()s the old dst.
That is only safe if no other thread modifies sk_dst_cache concurrently.
For a connected UDP socket that does not hold: the transmit fast path
(udp_sendmsg -> sk_dst_check -> sk_dst_reset) resets the cache locklessly
with an atomic xchg(). A per-socket policy change racing a send can make
both sides observe the same old dst and each dst_release() it, dropping
the socket's single reference twice and freeing the xfrm_dst bundle while
it is still referenced:
BUG: KASAN: slab-use-after-free in dst_release
Write of size 4 at addr ffff88801897b6c0 by task exploit/155
Call Trace:
...
dst_release (... ./include/linux/rcuref.h:109)
xfrm_user_policy (./include/net/sock.h:2239 ./include/net/sock.h:2256 net/xfrm/xfrm_state.c:3053)
do_ip_setsockopt (net/ipv4/ip_sockglue.c:1347)
ip_setsockopt (net/ipv4/ip_sockglue.c:1417)
do_sock_setsockopt (net/socket.c:2368)
__sys_setsockopt (net/socket.c:2393)
__x64_sys_setsockopt (net/socket.c:2396)
do_syscall_64 (arch/x86/entry/syscall_64.c:94)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
Reachable by an unprivileged user via a user+network namespace.
Use the atomic sk_dst_reset() so the cache is cleared and released with a
single xchg(): whichever side wins releases the dst once, the other sees
NULL and does nothing. Behaviour is otherwise unchanged.
Fixes: 2b06cdf3e688 ("xfrm: Clear sk_dst_cache when applying per-socket policy.")
Fixes: be8f8284cd89 ("net: xfrm: allow clearing socket xfrm policies.")
Reported-by: AutonomousCodeSecurity@microsoft.com
Signed-off-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/xfrm/xfrm_state.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 10f974d5ebee6..c5412f2e3b208 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2399,7 +2399,7 @@ int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval, int optlen)
if (sockptr_is_null(optval) && !optlen) {
xfrm_sk_policy_insert(sk, XFRM_POLICY_IN, NULL);
xfrm_sk_policy_insert(sk, XFRM_POLICY_OUT, NULL);
- __sk_dst_reset(sk);
+ sk_dst_reset(sk);
return 0;
}
@@ -2439,7 +2439,7 @@ int xfrm_user_policy(struct sock *sk, int optname, sockptr_t optval, int optlen)
if (err >= 0) {
xfrm_sk_policy_insert(sk, err, pol);
xfrm_pol_put(pol);
- __sk_dst_reset(sk);
+ sk_dst_reset(sk);
err = 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 5.10 50/57] iomap: adjust read range correctly for non-block-aligned positions
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (48 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 49/57] xfrm: fix sk_dst_cache double-free in xfrm_user_policy() Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 51/57] s390/vfio_ccw: Free all memory if cp_init() fails Greg Kroah-Hartman
` (12 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joanne Koong, syzbot, Brian Foster,
Christoph Hellwig, Christian Brauner, Sasha Levin,
Miguel Gazquez (Schneider Electric)
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joanne Koong <joannelkoong@gmail.com>
[ Upstream commit 7aa6bc3e8766990824f66ca76c19596ce10daf3e ]
iomap_adjust_read_range() assumes that the position and length passed in
are block-aligned. This is not always the case however, as shown in the
syzbot generated case for erofs. This causes too many bytes to be
skipped for uptodate blocks, which results in returning the incorrect
position and length to read in. If all the blocks are uptodate, this
underflows length and returns a position beyond the folio.
Fix the calculation to also take into account the block offset when
calculating how many bytes can be skipped for uptodate blocks.
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Tested-by: syzbot@syzkaller.appspotmail.com
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Miguel Gazquez (Schneider Electric) <miguel.gazquez@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/iomap/buffered-io.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index 219f9e1a26436..5ad3bf906b35a 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -103,17 +103,24 @@ iomap_adjust_read_range(struct inode *inode, struct iomap_page *iop,
* to avoid reading in already uptodate ranges.
*/
if (iop) {
- unsigned int i;
+ unsigned int i, blocks_skipped;
/* move forward for each leading block marked uptodate */
- for (i = first; i <= last; i++) {
+ for (i = first; i <= last; i++)
if (!test_bit(i, iop->uptodate))
break;
- *pos += block_size;
- poff += block_size;
- plen -= block_size;
- first++;
+
+ blocks_skipped = i - first;
+ if (blocks_skipped) {
+ unsigned long block_offset = *pos & (block_size - 1);
+ unsigned bytes_skipped =
+ (blocks_skipped << block_bits) - block_offset;
+
+ *pos += bytes_skipped;
+ poff += bytes_skipped;
+ plen -= bytes_skipped;
}
+ first = i;
/* truncate len if we find any trailing uptodate block(s) */
for ( ; i <= last; i++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 5.10 51/57] s390/vfio_ccw: Free all memory if cp_init() fails
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (49 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 50/57] iomap: adjust read range correctly for non-block-aligned positions Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 52/57] bpf: reject negative CO-RE accessor indices in bpf_core_parse_spec() Greg Kroah-Hartman
` (11 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Farhan Ali, Matthew Rosato,
Eric Farman, Christian Borntraeger, Sasha Levin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Farman <farman@linux.ibm.com>
[ Upstream commit 74186c2968f8f756ac3226b545b598457c910c75 ]
The routine cp_free() is called to unpin/free any memory once an I/O
is completed successfully, or if cp_prefetch() fails. But if cp_init()
fails, and cp->initialized is not enabled, the same routine cannot be
used to free all the memory.
An attempt to address this exists in ccwchain_handle_ccw(), where a
single call to ccwchain_free() is made for the currently-processed
CCW segment. But this will leak other segments (created as a result
of a Transfer in Channel) that had been allocated as part of the same
channel program.
Address this by performing the cleanup outside of the recursive
ccwchain_handle_ccw()/ccwchain_loop_tic() logic.
Fixes: 8b515be512a2 ("vfio-ccw: Fix memory leak and don't call cp_free in cp_init")
Cc: stable@vger.kernel.org
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Eric Farman <farman@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/cio/vfio_ccw_cp.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/s390/cio/vfio_ccw_cp.c b/drivers/s390/cio/vfio_ccw_cp.c
index 4da85df9f7816..1b6d0be12a7ae 100644
--- a/drivers/s390/cio/vfio_ccw_cp.c
+++ b/drivers/s390/cio/vfio_ccw_cp.c
@@ -446,9 +446,6 @@ static int ccwchain_handle_ccw(u32 cda, struct channel_program *cp)
/* Loop for tics on this new chain. */
ret = ccwchain_loop_tic(chain, cp);
- if (ret)
- ccwchain_free(chain);
-
return ret;
}
@@ -477,6 +474,23 @@ static int ccwchain_loop_tic(struct ccwchain *chain, struct channel_program *cp)
return 0;
}
+static int ccwchain_build_ccws(u32 cda, struct channel_program *cp)
+{
+ struct ccwchain *chain, *temp;
+ int ret;
+
+ ret = ccwchain_handle_ccw(cda, cp);
+
+ if (ret) {
+ /* Cleanup if an error occurred */
+ list_for_each_entry_safe(chain, temp, &cp->ccwchain_list, next) {
+ ccwchain_free(chain);
+ }
+ }
+
+ return ret;
+}
+
static int ccwchain_fetch_tic(struct ccwchain *chain,
int idx,
struct channel_program *cp)
@@ -650,7 +664,7 @@ int cp_init(struct channel_program *cp, struct device *mdev, union orb *orb)
cp->mdev = mdev;
/* Build a ccwchain for the first CCW segment */
- ret = ccwchain_handle_ccw(orb->cmd.cpa, cp);
+ ret = ccwchain_build_ccws(orb->cmd.cpa, cp);
if (!ret) {
cp->initialized = true;
--
2.53.0
^ permalink raw reply related [flat|nested] 64+ messages in thread
* [PATCH 5.10 52/57] bpf: reject negative CO-RE accessor indices in bpf_core_parse_spec()
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (50 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 51/57] s390/vfio_ccw: Free all memory if cp_init() fails Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 53/57] can: use skb hash instead of private variable in headroom Greg Kroah-Hartman
` (10 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiang Mei, Weiming Shi,
Emil Tsalapatis, Paul Chaignon, Alexei Starovoitov,
Andrey Troshin
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
commit 1c22483a2c4bbf747787f328392ca3e68619c4dc upstream.
CO-RE accessor strings are colon-separated indices that describe a path
from a root BTF type to a target field, e.g. "0:1:2" walks through
nested struct members. bpf_core_parse_spec() parses each component with
sscanf("%d"), so negative values like -1 are silently accepted. The
subsequent bounds checks (access_idx >= btf_vlen(t)) only guard the
upper bound and always pass for negative values because C integer
promotion converts the __u16 btf_vlen result to int, making the
comparison (int)(-1) >= (int)(N) false for any positive N.
When -1 reaches btf_member_bit_offset() it gets cast to u32 0xffffffff,
producing an out-of-bounds read far past the members array. A crafted
BPF program with a negative CO-RE accessor on any struct that exists in
vmlinux BTF (e.g. task_struct) crashes the kernel deterministically
during BPF_PROG_LOAD on any system with CONFIG_DEBUG_INFO_BTF=y
(default on major distributions). The bug is reachable with CAP_BPF:
BUG: unable to handle page fault for address: ffffed11818b6626
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
Oops: Oops: 0000 [#1] SMP KASAN NOPTI
CPU: 0 UID: 0 PID: 85 Comm: poc Not tainted 7.0.0-rc6 #18 PREEMPT(full)
RIP: 0010:bpf_core_parse_spec (tools/lib/bpf/relo_core.c:354)
RAX: 00000000ffffffff
Call Trace:
<TASK>
bpf_core_calc_relo_insn (tools/lib/bpf/relo_core.c:1321)
bpf_core_apply (kernel/bpf/btf.c:9507)
check_core_relo (kernel/bpf/verifier.c:19475)
bpf_check (kernel/bpf/verifier.c:26031)
bpf_prog_load (kernel/bpf/syscall.c:3089)
__sys_bpf (kernel/bpf/syscall.c:6228)
</TASK>
CO-RE accessor indices are inherently non-negative (struct member index,
array element index, or enumerator index), so reject them immediately
after parsing.
Fixes: ddc7c3042614 ("libbpf: implement BPF CO-RE offset relocation algorithm")
Reported-by: Xiang Mei <xmei5@asu.edu>
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Acked-by: Paul Chaignon <paul.chaignon@gmail.com>
Link: https://lore.kernel.org/r/20260404161221.961828-2-bestswngs@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
[Andrey Troshin: backport fixs from tools/lib/bpf/relo_core.c to
tools/lib/bpf/libbpf.c]
Signed-off-by: Andrey Troshin <drtrosh@yandex-team.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
tools/lib/bpf/libbpf.c | 2 ++
1 file changed, 2 insertions(+)
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -4554,6 +4554,8 @@ static int bpf_core_parse_spec(const str
++spec_str;
if (sscanf(spec_str, "%d%n", &access_idx, &parsed_len) != 1)
return -EINVAL;
+ if (access_idx < 0)
+ return -EINVAL;
if (spec->raw_len == BPF_CORE_SPEC_MAX_LEN)
return -E2BIG;
spec_str += parsed_len;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 53/57] can: use skb hash instead of private variable in headroom
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (51 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 52/57] bpf: reject negative CO-RE accessor indices in bpf_core_parse_spec() Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 54/57] can: isotp: fix timer drain order, wakeup handling and tx_gen ordering Greg Kroah-Hartman
` (9 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marc Kleine-Budde, Oliver Hartkopp,
Paolo Abeni
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
commit d4fb6514ff8ed6912a71294e6b66a5d59ee88007 upstream.
The can_skb_priv::skbcnt variable is used to identify CAN skbs in the RX
path analogue to the skb->hash.
As the skb hash is not filled in CAN skbs move the private skbcnt value to
skb->hash and set skb->sw_hash accordingly. The skb->hash is a value used
for RPS to identify skbs. Use it as intended.
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20260201-can_skb_ext-v8-1-3635d790fe8b@hartkopp.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/can/dev/dev.c | 2 --
drivers/net/can/slcan.c | 1 -
include/linux/can/core.h | 1 +
include/linux/can/dev.h | 1 -
include/linux/can/skb.h | 2 --
net/can/af_can.c | 14 +++++++++++---
net/can/bcm.c | 2 --
net/can/isotp.c | 3 ---
net/can/j1939/socket.c | 1 -
net/can/j1939/transport.c | 2 --
net/can/raw.c | 7 +++----
11 files changed, 15 insertions(+), 21 deletions(-)
--- a/drivers/net/can/dev/dev.c
+++ b/drivers/net/can/dev/dev.c
@@ -694,7 +694,6 @@ struct sk_buff *alloc_can_skb(struct net
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
*cf = skb_put_zero(skb, sizeof(struct can_frame));
@@ -722,7 +721,6 @@ struct sk_buff *alloc_canfd_skb(struct n
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
*cfd = skb_put_zero(skb, sizeof(struct canfd_frame));
--- a/drivers/net/can/slcan.c
+++ b/drivers/net/can/slcan.c
@@ -213,7 +213,6 @@ static void slc_bump(struct slcan *sl)
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = sl->dev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
skb_put_data(skb, &cf, sizeof(struct can_frame));
--- a/include/linux/can/core.h
+++ b/include/linux/can/core.h
@@ -58,6 +58,7 @@ extern void can_rx_unregister(struct net
void *data);
extern int can_send(struct sk_buff *skb, int loop);
+void can_set_skb_uid(struct sk_buff *skb);
void can_sock_destruct(struct sock *sk);
#endif /* !_CAN_CORE_H */
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -119,7 +119,6 @@ static inline bool can_skb_headroom_vali
if (skb->ip_summed == CHECKSUM_NONE) {
/* init headroom */
can_skb_prv(skb)->ifindex = dev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
skb->ip_summed = CHECKSUM_UNNECESSARY;
--- a/include/linux/can/skb.h
+++ b/include/linux/can/skb.h
@@ -28,12 +28,10 @@
/**
* struct can_skb_priv - private additional data inside CAN sk_buffs
* @ifindex: ifindex of the first interface the CAN frame appeared on
- * @skbcnt: atomic counter to have an unique id together with skb pointer
* @cf: align to the following CAN frame at skb->data
*/
struct can_skb_priv {
int ifindex;
- int skbcnt;
struct can_frame cf[];
};
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -641,6 +641,16 @@ static int can_rcv_filter(struct can_dev
return matches;
}
+void can_set_skb_uid(struct sk_buff *skb)
+{
+ /* create non-zero unique skb identifier together with *skb */
+ while (!(skb->hash))
+ skb->hash = atomic_inc_return(&skbcounter);
+
+ skb->sw_hash = 1;
+}
+EXPORT_SYMBOL(can_set_skb_uid);
+
static void can_receive(struct sk_buff *skb, struct net_device *dev)
{
struct can_dev_rcv_lists *dev_rcv_lists;
@@ -652,9 +662,7 @@ static void can_receive(struct sk_buff *
atomic_long_inc(&pkg_stats->rx_frames);
atomic_long_inc(&pkg_stats->rx_frames_delta);
- /* create non-zero unique skb identifier together with *skb */
- while (!(can_skb_prv(skb)->skbcnt))
- can_skb_prv(skb)->skbcnt = atomic_inc_return(&skbcounter);
+ can_set_skb_uid(skb);
rcu_read_lock();
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -338,7 +338,6 @@ static void bcm_can_tx(struct bcm_op *op
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
skb_put_data(skb, cf, op->cfsiz);
@@ -1577,7 +1576,6 @@ static int bcm_tx_send(struct msghdr *ms
}
can_skb_prv(skb)->ifindex = dev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
skb->dev = dev;
can_skb_set_owner(skb, sk);
err = can_send(skb, 1); /* send with loopback */
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -218,7 +218,6 @@ static int isotp_send_fc(struct sock *sk
can_skb_reserve(nskb);
can_skb_prv(nskb)->ifindex = dev->ifindex;
- can_skb_prv(nskb)->skbcnt = 0;
nskb->dev = dev;
can_skb_set_owner(nskb, sk);
@@ -773,7 +772,6 @@ static void isotp_send_cframe(struct iso
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
cf = (struct canfd_frame *)skb->data;
skb_put_zero(skb, so->ll.mtu);
@@ -1069,7 +1067,6 @@ static int isotp_sendmsg(struct socket *
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
so->tx.len = size;
so->tx.idx = 0;
--- a/net/can/j1939/socket.c
+++ b/net/can/j1939/socket.c
@@ -889,7 +889,6 @@ static struct sk_buff *j1939_sk_alloc_sk
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = ndev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
skb_reserve(skb, offsetof(struct can_frame, data));
ret = memcpy_from_msg(skb_put(skb, size), msg, size);
--- a/net/can/j1939/transport.c
+++ b/net/can/j1939/transport.c
@@ -608,7 +608,6 @@ sk_buff *j1939_tp_tx_dat_new(struct j193
skb->dev = priv->ndev;
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
/* reserve CAN header */
skb_reserve(skb, offsetof(struct can_frame, data));
@@ -1535,7 +1534,6 @@ j1939_session *j1939_session_fresh_new(s
skb->dev = priv->ndev;
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = priv->ndev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
skcb = j1939_skb_to_cb(skb);
memcpy(skcb, rel_skcb, sizeof(*skcb));
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -74,8 +74,8 @@ MODULE_ALIAS("can-proto-1");
*/
struct uniqframe {
- int skbcnt;
const struct sk_buff *skb;
+ u32 hash;
unsigned int join_rx_count;
};
@@ -135,7 +135,7 @@ static void raw_rcv(struct sk_buff *oskb
/* eliminate multiple filter matches for the same skb */
if (this_cpu_ptr(ro->uniq)->skb == oskb &&
- this_cpu_ptr(ro->uniq)->skbcnt == can_skb_prv(oskb)->skbcnt) {
+ this_cpu_ptr(ro->uniq)->hash == oskb->hash) {
if (ro->join_filters) {
this_cpu_inc(ro->uniq->join_rx_count);
/* drop frame until all enabled filters matched */
@@ -146,7 +146,7 @@ static void raw_rcv(struct sk_buff *oskb
}
} else {
this_cpu_ptr(ro->uniq)->skb = oskb;
- this_cpu_ptr(ro->uniq)->skbcnt = can_skb_prv(oskb)->skbcnt;
+ this_cpu_ptr(ro->uniq)->hash = oskb->hash;
this_cpu_ptr(ro->uniq)->join_rx_count = 1;
/* drop first frame to check all enabled filters? */
if (ro->join_filters && ro->count > 1)
@@ -812,7 +812,6 @@ static int raw_sendmsg(struct socket *so
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
- can_skb_prv(skb)->skbcnt = 0;
err = memcpy_from_msg(skb_put(skb, size), msg, size);
if (err < 0)
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 54/57] can: isotp: fix timer drain order, wakeup handling and tx_gen ordering
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (52 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 53/57] can: use skb hash instead of private variable in headroom Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 55/57] HID: core: fix number/pointer type confusion on long items Greg Kroah-Hartman
` (8 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oliver Hartkopp, stable,
Marc Kleine-Budde
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
commit 050f010f920da17c1044a4f174766ad553e770b6 upstream.
This patch is a follow-up to commit cf070fe33bfb ("can: isotp: serialize
TX state transitions under so->rx_lock") which addresses following
sashiko-bot findings:
- isotp_sendmsg(): drain so->txfrtimer first so a stale callback can't
re-arm echotimer after the claim
- isotp_release(): wake so->wait after forcing ISOTP_SHUTDOWN so a
sleeping sendmsg() claim isn't stranded
- isotp_sendmsg(): have both wait_event_interruptible() calls in
isotp_sendmsg() also wake on ISOTP_SHUTDOWN and do not return claim to
IDLE to avoid corrupting a concurrent isotp_release() process.
- isotp_sendmsg(): handle potential claim of a new transfer when
the wait_event_interruptible() call returns in CAN_ISOTP_WAIT_TX_DONE
mode. Don't touch timers and states of the new transfer if a new thread
incremented so->tx_gen before getting the lock at err_event_drop.
- isotp_sendmsg(): handle a stuck can_send() and omit timer and state
changes if a new transfer was claimed. wait_tx_done() returns the error
recorded in so->tx_result[], tagged with the caller's own generation.
- isotp_tx_timeout(): on a claimed timeout, record the ECOMM error for
the timed-out transfer's own generation in so->tx_result[]; sk->sk_err
is raised unconditionally, same as every other error path here.
- isotp_tx_gen_done()/isotp_tx_timeout(): always read tx.state (acquire)
before tx_gen - the reverse order let a weakly ordered CPU pair a fresh
tx.state with a stale tx_gen/tx_result slot.
- isotp_sendmsg(): wait_tx_done: drain sk_err via sock_error() once we
have read the result from so->tx_result[], so an already-reported error
doesn't stay latched for a later poll()/SO_ERROR.
Also align the remaining lock-free so->tx.state/rx.state/cfecho accesses
and use skb->hash as unique loopback echo frame indicator.
Fixes: cf070fe33bfb ("can: isotp: serialize TX state transitions under so->rx_lock")
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Link: https://patch.msgid.link/20260724181525.43556-1-socketcan@hartkopp.net
Cc: stable@kernel.org
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/can/isotp.c | 317 ++++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 230 insertions(+), 87 deletions(-)
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -114,6 +114,15 @@ MODULE_ALIAS("can-proto-6");
#define ISOTP_FC_TIMEOUT 1 /* 1 sec */
#define ISOTP_ECHO_TIMEOUT 2 /* 2 secs */
+/* so->tx_result[so->tx_gen % ISOTP_TX_RESULT_SLOTS] holds the packed value
+ * (err << ISOTP_TX_RESULT_GEN_BITS | gen) for each tx generation slot, so it
+ * can be handled with a single READ_ONCE()/WRITE_ONCE() access.
+ */
+#define ISOTP_TX_RESULT_SLOTS 4
+#define ISOTP_TX_RESULT_GEN_BITS 24
+#define ISOTP_TX_RESULT_GEN_MASK ((1U << ISOTP_TX_RESULT_GEN_BITS) - 1)
+#define ISOTP_TX_RESULT_ERR_MASK 0xFF
+
enum {
ISOTP_IDLE = 0,
ISOTP_WAIT_FIRST_FC,
@@ -150,7 +159,8 @@ struct isotp_sock {
u32 force_tx_stmin;
u32 force_rx_stmin;
u32 cfecho; /* consecutive frame echo tag */
- u32 tx_gen; /* generation, bumped per new tx transfer */
+ u32 tx_gen; /* transfer generation, increased per new tx transfer */
+ u32 tx_result[ISOTP_TX_RESULT_SLOTS]; /* per-generation result slots */
struct tpcon rx, tx;
struct list_head notifier;
wait_queue_head_t wait;
@@ -161,6 +171,65 @@ static LIST_HEAD(isotp_notifier_list);
static DEFINE_SPINLOCK(isotp_notifier_lock);
static struct isotp_sock *isotp_busy_notifier;
+/* increase (24 bit) tx generation value */
+static u32 isotp_inc_tx_gen(u32 gen)
+{
+ return (gen + 1) & ISOTP_TX_RESULT_GEN_MASK;
+}
+
+/* store 8 bit error and 24 bit tx generation values in packed u32 element */
+static u32 isotp_pack_tx_result(u32 gen, int err)
+{
+ return gen | ((u32)err << ISOTP_TX_RESULT_GEN_BITS);
+}
+
+/* get the 24 bit tx generation value from the tx result */
+static u32 isotp_get_tx_gen(u32 gen_err)
+{
+ return gen_err & ISOTP_TX_RESULT_GEN_MASK;
+}
+
+/* get the 8 bit error value from the tx result */
+static u32 isotp_get_tx_err(u32 gen_err)
+{
+ return (gen_err >> ISOTP_TX_RESULT_GEN_BITS) & ISOTP_TX_RESULT_ERR_MASK;
+}
+
+/* store transfer result in per-generation%4 so->tx_result[] slot */
+static void isotp_set_tx_result(struct isotp_sock *so, u32 gen, int err)
+{
+ WRITE_ONCE(so->tx_result[gen % ISOTP_TX_RESULT_SLOTS],
+ isotp_pack_tx_result(gen, err));
+}
+
+/* fetch the result recorded for 'gen', as a (negative) errno (0 for success) */
+static int isotp_get_tx_result(struct isotp_sock *so, u32 gen)
+{
+ u32 result = READ_ONCE(so->tx_result[gen % ISOTP_TX_RESULT_SLOTS]);
+
+ if (isotp_get_tx_gen(result) != gen) {
+ pr_notice_once("can-isotp: tx_result[] slot reused before read\n");
+
+ /* report failure rather than risk a false success */
+ return -ECOMM;
+ }
+
+ return -(isotp_get_tx_err(result));
+}
+
+/* true if done, shut down or superseded ('gen' is no longer the active
+ * transfer). Reads tx.state first (acquire) so tx_gen/tx_result reads
+ * below see at least what that state write published (common sequence).
+ */
+static bool isotp_tx_gen_done(struct isotp_sock *so, u32 gen)
+{
+ /* read tx.state first for the common sequence */
+ u32 state = smp_load_acquire(&so->tx.state);
+
+ return state == ISOTP_IDLE || state == ISOTP_SHUTDOWN ||
+ READ_ONCE(so->tx_gen) != gen;
+}
+
static inline struct isotp_sock *isotp_sk(const struct sock *sk)
{
return (struct isotp_sock *)sk;
@@ -183,7 +252,7 @@ static enum hrtimer_restart isotp_rx_tim
rxtimer);
struct sock *sk = &so->sk;
- if (so->rx.state == ISOTP_WAIT_DATA) {
+ if (READ_ONCE(so->rx.state) == ISOTP_WAIT_DATA) {
/* we did not get new data frames in time */
/* report 'connection timed out' */
@@ -192,7 +261,7 @@ static enum hrtimer_restart isotp_rx_tim
sk->sk_error_report(sk);
/* reset rx state */
- so->rx.state = ISOTP_IDLE;
+ WRITE_ONCE(so->rx.state, ISOTP_IDLE);
}
return HRTIMER_NORESTART;
@@ -349,20 +418,19 @@ static void isotp_send_cframe(struct iso
static int isotp_rcv_fc(struct isotp_sock *so, struct canfd_frame *cf, int ae)
{
struct sock *sk = &so->sk;
+ int tx_err = EBADMSG; /* default for unknown FC status */
- if (so->tx.state != ISOTP_WAIT_FC &&
- so->tx.state != ISOTP_WAIT_FIRST_FC)
+ if (READ_ONCE(so->tx.state) != ISOTP_WAIT_FC &&
+ READ_ONCE(so->tx.state) != ISOTP_WAIT_FIRST_FC)
return 0;
hrtimer_cancel(&so->txtimer);
/* isotp_tx_timeout() may have given up on this job while
- * hrtimer_cancel() above waited for it to finish; so->rx_lock
- * (held by our caller isotp_rcv()) rules out a concurrent claim,
- * so a plain recheck is enough here.
+ * hrtimer_cancel() above waited for it to finish => recheck
*/
- if (so->tx.state != ISOTP_WAIT_FC &&
- so->tx.state != ISOTP_WAIT_FIRST_FC)
+ if (READ_ONCE(so->tx.state) != ISOTP_WAIT_FC &&
+ READ_ONCE(so->tx.state) != ISOTP_WAIT_FIRST_FC)
return 1;
if ((cf->len < ae + FC_CONTENT_SZ) ||
@@ -373,13 +441,15 @@ static int isotp_rcv_fc(struct isotp_soc
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_error_report(sk);
- so->tx.state = ISOTP_IDLE;
+ isotp_set_tx_result(so, so->tx_gen, EBADMSG);
+ /* set to IDLE after publishing tx_result */
+ smp_store_release(&so->tx.state, ISOTP_IDLE);
wake_up_interruptible(&so->wait);
return 1;
}
/* get communication parameters only from the first FC frame */
- if (so->tx.state == ISOTP_WAIT_FIRST_FC) {
+ if (READ_ONCE(so->tx.state) == ISOTP_WAIT_FIRST_FC) {
so->txfc.bs = cf->data[ae + 1];
so->txfc.stmin = cf->data[ae + 2];
@@ -402,13 +472,13 @@ static int isotp_rcv_fc(struct isotp_soc
so->tx_gap = ktime_add_ns(so->tx_gap,
(so->txfc.stmin - 0xF0)
* 100000);
- so->tx.state = ISOTP_WAIT_FC;
+ WRITE_ONCE(so->tx.state, ISOTP_WAIT_FC);
}
switch (cf->data[ae] & 0x0F) {
case ISOTP_FC_CTS:
so->tx.bs = 0;
- so->tx.state = ISOTP_SENDING;
+ WRITE_ONCE(so->tx.state, ISOTP_SENDING);
/* send CF frame and enable echo timeout handling */
hrtimer_start(&so->echotimer, ktime_set(ISOTP_ECHO_TIMEOUT, 0),
HRTIMER_MODE_REL_SOFT);
@@ -423,14 +493,19 @@ static int isotp_rcv_fc(struct isotp_soc
case ISOTP_FC_OVFLW:
/* overflow on receiver side - report 'message too long' */
- sk->sk_err = EMSGSIZE;
- if (!sock_flag(sk, SOCK_DEAD))
- sk->sk_error_report(sk);
+ tx_err = EMSGSIZE;
fallthrough;
default:
- /* stop this tx job */
- so->tx.state = ISOTP_IDLE;
+ /* reserved/unknown flow status (tx_err defaults to EBADMSG) */
+
+ sk->sk_err = tx_err;
+ if (!sock_flag(sk, SOCK_DEAD))
+ sk->sk_error_report(sk);
+
+ isotp_set_tx_result(so, so->tx_gen, tx_err);
+ /* set to IDLE after publishing tx_result */
+ smp_store_release(&so->tx.state, ISOTP_IDLE);
wake_up_interruptible(&so->wait);
}
return 0;
@@ -443,7 +518,7 @@ static int isotp_rcv_sf(struct sock *sk,
struct sk_buff *nskb;
hrtimer_cancel(&so->rxtimer);
- so->rx.state = ISOTP_IDLE;
+ WRITE_ONCE(so->rx.state, ISOTP_IDLE);
if (!len || len > cf->len - pcilen)
return 1;
@@ -477,7 +552,7 @@ static int isotp_rcv_ff(struct sock *sk,
int ff_pci_sz;
hrtimer_cancel(&so->rxtimer);
- so->rx.state = ISOTP_IDLE;
+ WRITE_ONCE(so->rx.state, ISOTP_IDLE);
/* get the used sender LL_DL from the (first) CAN frame data length */
so->rx.ll_dl = padlen(cf->len);
@@ -521,7 +596,7 @@ static int isotp_rcv_ff(struct sock *sk,
/* initial setup for this pdu reception */
so->rx.sn = 1;
- so->rx.state = ISOTP_WAIT_DATA;
+ WRITE_ONCE(so->rx.state, ISOTP_WAIT_DATA);
/* no creation of flow control frames */
if (so->opt.flags & CAN_ISOTP_LISTEN_MODE)
@@ -539,7 +614,7 @@ static int isotp_rcv_cf(struct sock *sk,
struct sk_buff *nskb;
int i;
- if (so->rx.state != ISOTP_WAIT_DATA)
+ if (READ_ONCE(so->rx.state) != ISOTP_WAIT_DATA)
return 0;
/* drop if timestamp gap is less than force_rx_stmin nano secs */
@@ -554,11 +629,9 @@ static int isotp_rcv_cf(struct sock *sk,
hrtimer_cancel(&so->rxtimer);
/* isotp_rx_timer_handler() may have raced us for so->rx.state
- * while hrtimer_cancel() above waited for it to finish, already
- * reporting ETIMEDOUT and resetting the reception; don't process
- * this CF into a reassembly that has already been given up on.
+ * while hrtimer_cancel() above waited for it to finish => recheck
*/
- if (so->rx.state != ISOTP_WAIT_DATA)
+ if (READ_ONCE(so->rx.state) != ISOTP_WAIT_DATA)
return 1;
/* CFs are never longer than the FF */
@@ -579,7 +652,7 @@ static int isotp_rcv_cf(struct sock *sk,
sk->sk_error_report(sk);
/* reset rx state */
- so->rx.state = ISOTP_IDLE;
+ WRITE_ONCE(so->rx.state, ISOTP_IDLE);
return 1;
}
so->rx.sn++;
@@ -593,7 +666,7 @@ static int isotp_rcv_cf(struct sock *sk,
if (so->rx.idx >= so->rx.len) {
/* we are done */
- so->rx.state = ISOTP_IDLE;
+ WRITE_ONCE(so->rx.state, ISOTP_IDLE);
if ((so->opt.flags & ISOTP_CHECK_PADDING) &&
check_pad(so, cf, i + 1, so->opt.rxpad_content)) {
@@ -664,8 +737,10 @@ static void isotp_rcv(struct sk_buff *sk
if (so->opt.flags & CAN_ISOTP_HALF_DUPLEX) {
/* check rx/tx path half duplex expectations */
- if ((so->tx.state != ISOTP_IDLE && n_pci_type != N_PCI_FC) ||
- (so->rx.state != ISOTP_IDLE && n_pci_type == N_PCI_FC))
+ if ((READ_ONCE(so->tx.state) != ISOTP_IDLE &&
+ n_pci_type != N_PCI_FC) ||
+ (READ_ONCE(so->rx.state) != ISOTP_IDLE &&
+ n_pci_type == N_PCI_FC))
goto out_unlock;
}
@@ -759,6 +834,7 @@ static void isotp_send_cframe(struct iso
struct canfd_frame *cf;
int can_send_ret;
int ae = (so->opt.flags & CAN_ISOTP_EXTEND_ADDR) ? 1 : 0;
+ u32 old_cfecho;
dev = dev_get_by_index(sock_net(sk), so->ifindex);
if (!dev)
@@ -773,6 +849,9 @@ static void isotp_send_cframe(struct iso
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
+ /* set uid in tx skb to identify CF echo frames */
+ can_set_skb_uid(skb);
+
cf = (struct canfd_frame *)skb->data;
skb_put_zero(skb, so->ll.mtu);
@@ -789,12 +868,15 @@ static void isotp_send_cframe(struct iso
skb->dev = dev;
can_skb_set_owner(skb, sk);
- /* cfecho should have been zero'ed by init/isotp_rcv_echo() */
- if (so->cfecho)
- pr_notice_once("can-isotp: cfecho is %08X != 0\n", so->cfecho);
+ /* zero'ed by init/isotp_rcv_echo(); reached lock-free via
+ * isotp_txfr_timer_handler() too, so use READ_ONCE()/WRITE_ONCE()
+ */
+ old_cfecho = READ_ONCE(so->cfecho);
+ if (old_cfecho)
+ pr_notice_once("can-isotp: cfecho is %08X != 0\n", old_cfecho);
/* set consecutive frame echo tag */
- so->cfecho = *(u32 *)cf->data;
+ WRITE_ONCE(so->cfecho, skb->hash);
/* send frame with local echo enabled */
can_send_ret = can_send(skb, 1);
@@ -846,7 +928,6 @@ static void isotp_rcv_echo(struct sk_buf
{
struct sock *sk = (struct sock *)data;
struct isotp_sock *so = isotp_sk(sk);
- struct canfd_frame *cf = (struct canfd_frame *)skb->data;
/* only handle my own local echo CF/SF skb's (no FF!) */
if (skb->sk != sk)
@@ -858,32 +939,35 @@ static void isotp_rcv_echo(struct sk_buf
spin_lock(&so->rx_lock);
/* so->cfecho may since belong to a new transfer; recheck under lock */
- if (so->cfecho != *(u32 *)cf->data)
+ if (READ_ONCE(so->cfecho) != skb->hash)
goto out_unlock;
/* cancel local echo timeout */
hrtimer_cancel(&so->echotimer);
/* local echo skb with consecutive frame has been consumed */
- so->cfecho = 0;
+ WRITE_ONCE(so->cfecho, 0);
/* claiming a transfer also takes so->rx_lock, so a plain recheck
* is enough: so->tx.state can't have flipped to ISOTP_SENDING for
* a new claim while we're still in here
*/
- if (so->tx.state != ISOTP_SENDING)
+ if (READ_ONCE(so->tx.state) != ISOTP_SENDING)
goto out_unlock;
if (so->tx.idx >= so->tx.len) {
/* we are done */
- so->tx.state = ISOTP_IDLE;
+
+ isotp_set_tx_result(so, so->tx_gen, 0);
+ /* set to IDLE after publishing tx_result */
+ smp_store_release(&so->tx.state, ISOTP_IDLE);
wake_up_interruptible(&so->wait);
goto out_unlock;
}
if (so->txfc.bs && so->tx.bs >= so->txfc.bs) {
/* stop and wait for FC with timeout */
- so->tx.state = ISOTP_WAIT_FC;
+ WRITE_ONCE(so->tx.state, ISOTP_WAIT_FC);
hrtimer_start(&so->txtimer, ktime_set(ISOTP_FC_TIMEOUT, 0),
HRTIMER_MODE_REL_SOFT);
goto out_unlock;
@@ -905,16 +989,20 @@ out_unlock:
spin_unlock(&so->rx_lock);
}
-/* shared by so->txtimer's and so->echotimer's callbacks. Both timers get
- * cancelled under so->rx_lock elsewhere, so this must stay lock-free to
- * avoid deadlocking with that; uses so->tx_gen instead to avoid tainting
- * a new transfer with an error from the one that just timed out.
+/* isotp_tx_timeout: we did not get any flow control or echo frame in time
+ *
+ * Shared by so->txtimer's and so->echotimer's callbacks. Both timers get
+ * cancelled under so->rx_lock elsewhere, so this must stay lock-free.
+ *
+ * tx.state is acquired before tx_gen. Common sequence in isotp_tx_gen_done().
+ * cmpxchg() only orders itself, not the two preceding loads.
*/
static enum hrtimer_restart isotp_tx_timeout(struct isotp_sock *so)
{
struct sock *sk = &so->sk;
+ /* read tx.state first for the common sequence */
+ u32 old_state = smp_load_acquire(&so->tx.state);
u32 gen = READ_ONCE(so->tx_gen);
- u32 old_state = READ_ONCE(so->tx.state);
/* don't handle timeouts in IDLE or SHUTDOWN state */
if (old_state == ISOTP_IDLE || old_state == ISOTP_SHUTDOWN)
@@ -924,14 +1012,14 @@ static enum hrtimer_restart isotp_tx_tim
if (cmpxchg(&so->tx.state, old_state, ISOTP_IDLE) != old_state)
return HRTIMER_NORESTART;
- /* we did not get any flow control or echo frame in time */
+ /* detected timeout: report 'communication error on send' */
- if (READ_ONCE(so->tx_gen) == gen) {
- /* report 'communication error on send' */
- sk->sk_err = ECOMM;
- if (!sock_flag(sk, SOCK_DEAD))
- sk->sk_error_report(sk);
- }
+ /* a stale read of this slot by a waiter still falls back to ECOMM */
+ isotp_set_tx_result(so, gen, ECOMM);
+
+ sk->sk_err = ECOMM;
+ if (!sock_flag(sk, SOCK_DEAD))
+ sk->sk_error_report(sk);
wake_up_interruptible(&so->wait);
@@ -966,7 +1054,7 @@ static enum hrtimer_restart isotp_txfr_t
HRTIMER_MODE_REL_SOFT);
/* cfecho should be consumed by isotp_rcv_echo() here */
- if (so->tx.state == ISOTP_SENDING && !so->cfecho)
+ if (READ_ONCE(so->tx.state) == ISOTP_SENDING && !READ_ONCE(so->cfecho))
isotp_send_cframe(so);
return HRTIMER_NORESTART;
@@ -984,10 +1072,12 @@ static int isotp_sendmsg(struct socket *
s64 hrtimer_sec = ISOTP_ECHO_TIMEOUT;
struct hrtimer *tx_hrt = &so->echotimer;
u32 new_state = ISOTP_SENDING;
+ u32 my_gen;
+ u32 old_cfecho;
int off;
int err;
- if (!so->bound || so->tx.state == ISOTP_SHUTDOWN)
+ if (!so->bound || READ_ONCE(so->tx.state) == ISOTP_SHUTDOWN)
return -EADDRNOTAVAIL;
/* claim the socket under so->rx_lock: this serializes the claim
@@ -1004,29 +1094,33 @@ static int isotp_sendmsg(struct socket *
if (msg->msg_flags & MSG_DONTWAIT)
return -EAGAIN;
- if (so->tx.state == ISOTP_SHUTDOWN)
+ if (READ_ONCE(so->tx.state) == ISOTP_SHUTDOWN)
return -EADDRNOTAVAIL;
/* wait for complete transmission of current pdu */
err = wait_event_interruptible(so->wait,
- so->tx.state == ISOTP_IDLE);
+ READ_ONCE(so->tx.state) == ISOTP_IDLE ||
+ READ_ONCE(so->tx.state) == ISOTP_SHUTDOWN);
if (err)
return err;
}
- /* new transfer: bump so->tx_gen and drain the old one's timers,
- * still under the so->rx_lock we just claimed the socket with
- */
- WRITE_ONCE(so->tx.state, ISOTP_SENDING);
- WRITE_ONCE(so->tx_gen, READ_ONCE(so->tx_gen) + 1);
+ /* txfrtimer's callback re-arms echotimer lock-free: drain it first */
+ hrtimer_cancel(&so->txfrtimer);
hrtimer_cancel(&so->txtimer);
hrtimer_cancel(&so->echotimer);
- hrtimer_cancel(&so->txfrtimer);
- so->cfecho = 0;
+
+ /* new transfer: increment so->tx_gen and set tx.state after barrier */
+ my_gen = isotp_inc_tx_gen(READ_ONCE(so->tx_gen));
+ isotp_set_tx_result(so, my_gen, ECOMM); /* prevent stale slot matching */
+ WRITE_ONCE(so->tx_gen, my_gen);
+ smp_wmb(); /* see smp_load_acquire() in isotp_tx_[timeout|gen_done] */
+ WRITE_ONCE(so->tx.state, ISOTP_SENDING);
+ WRITE_ONCE(so->cfecho, 0);
spin_unlock_bh(&so->rx_lock);
/* so->bound is only checked once above - a wakeup may have
- * unbound/rebound the socket meanwhile, so re-validate it
+ * unbound/rebound the socket meanwhile => recheck
*/
if (!so->bound) {
err = -EADDRNOTAVAIL;
@@ -1068,6 +1162,9 @@ static int isotp_sendmsg(struct socket *
can_skb_reserve(skb);
can_skb_prv(skb)->ifindex = dev->ifindex;
+ /* set uid in tx skb to identify CF echo frames */
+ can_set_skb_uid(skb);
+
so->tx.len = size;
so->tx.idx = 0;
@@ -1075,8 +1172,9 @@ static int isotp_sendmsg(struct socket *
skb_put_zero(skb, so->ll.mtu);
/* cfecho should have been zero'ed by init / former isotp_rcv_echo() */
- if (so->cfecho)
- pr_notice_once("can-isotp: uninit cfecho %08X\n", so->cfecho);
+ old_cfecho = READ_ONCE(so->cfecho);
+ if (old_cfecho)
+ pr_notice_once("can-isotp: uninit cfecho %08X\n", old_cfecho);
/* check for single frame transmission depending on TX_DL */
if (size <= so->tx.ll_dl - SF_PCI_SZ4 - ae - off) {
@@ -1104,7 +1202,7 @@ static int isotp_sendmsg(struct socket *
cf->data[ae] |= size;
/* set CF echo tag for isotp_rcv_echo() (SF-mode) */
- so->cfecho = *(u32 *)cf->data;
+ WRITE_ONCE(so->cfecho, skb->hash);
} else {
/* send first frame */
@@ -1121,7 +1219,7 @@ static int isotp_sendmsg(struct socket *
so->txfc.bs = 0;
/* set CF echo tag for isotp_rcv_echo() (CF-mode) */
- so->cfecho = *(u32 *)cf->data;
+ WRITE_ONCE(so->cfecho, skb->hash);
} else {
/* standard flow control check */
new_state = ISOTP_WAIT_FIRST_FC;
@@ -1131,12 +1229,12 @@ static int isotp_sendmsg(struct socket *
tx_hrt = &so->txtimer;
/* no CF echo tag for isotp_rcv_echo() (FF-mode) */
- so->cfecho = 0;
+ WRITE_ONCE(so->cfecho, 0);
}
}
spin_lock_bh(&so->rx_lock);
- if (so->tx.state == ISOTP_SHUTDOWN) {
+ if (READ_ONCE(so->tx.state) == ISOTP_SHUTDOWN) {
/* isotp_release() has since taken over and already drained
* our timers - don't send into a socket that's going away
*/
@@ -1147,7 +1245,7 @@ static int isotp_sendmsg(struct socket *
return -EADDRNOTAVAIL;
}
/* WAIT_FIRST_FC for standard FF, else stays ISOTP_SENDING */
- so->tx.state = new_state;
+ WRITE_ONCE(so->tx.state, new_state);
hrtimer_start(tx_hrt, ktime_set(hrtimer_sec, 0),
HRTIMER_MODE_REL_SOFT);
spin_unlock_bh(&so->rx_lock);
@@ -1164,20 +1262,49 @@ static int isotp_sendmsg(struct socket *
__func__, ERR_PTR(err));
spin_lock_bh(&so->rx_lock);
+
+ /* new transfer already claimed by a concurrent completion,
+ * timeout or sendmsg() while we were stuck in can_send()?
+ */
+ if (READ_ONCE(so->tx_gen) != my_gen) {
+ /* don't touch timers and state of the new transfer */
+ spin_unlock_bh(&so->rx_lock);
+ return err;
+ }
+
/* no transmission -> no timeout monitoring */
hrtimer_cancel(tx_hrt);
goto err_out_drop_locked;
}
if (wait_tx_done) {
- /* wait for complete transmission of current pdu */
- err = wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
+ /* wake up for:
+ * - concurrent sendmsg() claiming a new transfer
+ * - complete transmission of current PDU
+ * - shutdown state change in isotp_release()
+ * isotp_tx_gen_done() uses common tx.state/tx_gen read sequence
+ */
+ err = wait_event_interruptible(so->wait,
+ isotp_tx_gen_done(so, my_gen));
if (err)
goto err_event_drop;
- err = sock_error(sk);
- if (err)
- return err;
+ /* still our claim, but isotp_release() force-shut it down */
+ if (smp_load_acquire(&so->tx.state) == ISOTP_SHUTDOWN &&
+ READ_ONCE(so->tx_gen) == my_gen) {
+ err = -EADDRNOTAVAIL;
+ goto err_event_drop;
+ }
+
+ /* own completion, or tx_gen moved on - either way this is
+ * what isotp_get_tx_result() recorded for my_gen
+ */
+ err = isotp_get_tx_result(so, my_gen);
+
+ /* drain to avoid stale error for a later poll()/SO_ERROR */
+ sock_error(sk);
+
+ return err ? err : size;
}
return size;
@@ -1187,15 +1314,26 @@ err_out_drop:
spin_lock_bh(&so->rx_lock);
goto err_out_drop_locked;
err_event_drop:
- /* interrupted waiting on our own transfer - drain its timers */
+ /* interrupted or shut down while waiting on our own transfer */
spin_lock_bh(&so->rx_lock);
+
+ /* new transfer already started by concurrent sendmsg()? */
+ if (READ_ONCE(so->tx_gen) != my_gen) {
+ /* don't touch timers and states of the new transfer */
+ spin_unlock_bh(&so->rx_lock);
+ return err;
+ }
+
hrtimer_cancel(&so->txfrtimer);
hrtimer_cancel(&so->txtimer);
hrtimer_cancel(&so->echotimer);
err_out_drop_locked:
/* release the claim; so->rx_lock still held from above */
- so->cfecho = 0;
- so->tx.state = ISOTP_IDLE;
+ WRITE_ONCE(so->cfecho, 0);
+
+ /* only claim to IDLE if isotp_release() has not taken over */
+ if (READ_ONCE(so->tx.state) != ISOTP_SHUTDOWN)
+ WRITE_ONCE(so->tx.state, ISOTP_IDLE);
spin_unlock_bh(&so->rx_lock);
wake_up_interruptible(&so->wait);
@@ -1263,8 +1401,9 @@ static int isotp_release(struct socket *
/* best-effort: wait for a running pdu to finish, but don't block on
* it forever - give up after the first signal
*/
- while (so->tx.state != ISOTP_IDLE &&
- wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE) == 0)
+ while (READ_ONCE(so->tx.state) != ISOTP_IDLE &&
+ wait_event_interruptible(so->wait,
+ READ_ONCE(so->tx.state) == ISOTP_IDLE) == 0)
;
/* claim the socket under so->rx_lock like sendmsg() does, so its
@@ -1272,9 +1411,12 @@ static int isotp_release(struct socket *
* unconditionally, even when a signal cut the wait above short
*/
spin_lock_bh(&so->rx_lock);
- so->tx.state = ISOTP_SHUTDOWN;
+ WRITE_ONCE(so->tx.state, ISOTP_SHUTDOWN);
spin_unlock_bh(&so->rx_lock);
- so->rx.state = ISOTP_IDLE;
+ WRITE_ONCE(so->rx.state, ISOTP_IDLE);
+
+ /* forced SHUTDOWN may have skipped IDLE (gave up on a signal) */
+ wake_up_interruptible(&so->wait);
spin_lock(&isotp_notifier_lock);
while (isotp_busy_notifier == so) {
@@ -1389,7 +1531,8 @@ static int isotp_bind(struct socket *soc
* with so->bound in the same lock_sock() section above, so there is
* no window in which a concurrent isotp_notify() could be missed.
*/
- if (so->tx.state != ISOTP_IDLE || so->rx.state != ISOTP_IDLE) {
+ if (READ_ONCE(so->tx.state) != ISOTP_IDLE ||
+ READ_ONCE(so->rx.state) != ISOTP_IDLE) {
err = -EAGAIN;
goto out;
}
@@ -1423,7 +1566,7 @@ static int isotp_bind(struct socket *soc
isotp_rcv, sk, "isotp", sk);
/* no consecutive frame echo skb in flight */
- so->cfecho = 0;
+ WRITE_ONCE(so->cfecho, 0);
/* register for echo skb's */
can_rx_register(net, dev, tx_id, SINGLE_MASK(tx_id),
@@ -1766,7 +1909,7 @@ static __poll_t isotp_poll(struct file *
poll_wait(file, &so->wait, wait);
/* Check for false positives due to TX state */
- if ((mask & EPOLLWRNORM) && (so->tx.state != ISOTP_IDLE))
+ if ((mask & EPOLLWRNORM) && (READ_ONCE(so->tx.state) != ISOTP_IDLE))
mask &= ~(EPOLLOUT | EPOLLWRNORM);
return mask;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 55/57] HID: core: fix number/pointer type confusion on long items
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (53 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 54/57] can: isotp: fix timer drain order, wakeup handling and tx_gen ordering Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 56/57] HID: sensor: custom: Fix use-after-free in enable_sensor Greg Kroah-Hartman
` (7 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jann Horn, Jiri Kosina
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <jannh@google.com>
commit 28abce951343fcec26e397610868efa4e1395c3f upstream.
When fetch_item() is called by hid_scan_report() on an item with
HID_ITEM_TAG_LONG, it stores a pointer to the item data in
item->data.longdata instead of storing a value directly in
item->data.{u8/u16/u32}.
When item_udata() or item_sdata() encounters such an item, it incorrectly
assumes that the item is in short format, and therefore returns the lower
part of a kernel pointer reinterpreted as a number.
When a HID device is connected whose descriptor contains a
HID_GLOBAL_ITEM_TAG_REPORT_SIZE encoded in long format with size=4, this
causes the lower half of a kernel pointer to be printed into dmesg as a
number, like this:
hid (null): invalid report_size 107953555
To fix it, let item_udata() and item_sdata() verify that the item is in
short format.
Note that this bug only affects hid_scan_report(), while the main parsing
pass hid_parse_collections() will always bail out when encountering a long
item.
Sidenote: There are currently no users of data.longdata; maybe we should
just remove any parsing of long-format descriptors as a follow-up.
Fixes: 3dc8fc083dbf ("HID: Use hid_parser for pre-scanning the report descriptors")
Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-core.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -346,6 +346,9 @@ static int hid_add_field(struct hid_pars
static u32 item_udata(struct hid_item *item)
{
+ if (item->format != HID_ITEM_FORMAT_SHORT)
+ return 0;
+
switch (item->size) {
case 1: return item->data.u8;
case 2: return item->data.u16;
@@ -356,6 +359,9 @@ static u32 item_udata(struct hid_item *i
static s32 item_sdata(struct hid_item *item)
{
+ if (item->format != HID_ITEM_FORMAT_SHORT)
+ return 0;
+
switch (item->size) {
case 1: return item->data.s8;
case 2: return item->data.s16;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 56/57] HID: sensor: custom: Fix use-after-free in enable_sensor
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (54 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 55/57] HID: core: fix number/pointer type confusion on long items Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 57/57] HID: hyperv: validate initial device info bounds Greg Kroah-Hartman
` (6 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko AI Review, Haoxiang Li,
Srinivas Pandruvada, Jiri Kosina
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li <haoxiang_li2024@163.com>
commit ad8fb82b04422f49530d2aa2753cc81d1c60102c upstream.
enable_sensor_store() can call set_power_report_state(), which
dereferences sensor_inst->power_state and sensor_inst->report_state.
These pointers refer to entries in sensor_inst->fields.
Create the field attributes before exposing the enable_sensor sysfs
attribute, so enable_sensor cannot be accessed before the state it
depends on has been initialized.
On remove, delete enable_sensor before freeing the field attributes,
so a concurrent sysfs write cannot dereference freed memory through
power_state or report_state.
Reported-by: Sashiko AI Review <sashiko-bot@kernel.org>
Link: https://sashiko.dev/#/patchset/20260623021950.1736413-1-haoxiang_li2024@163.com?part=1
Fixes: 4a7de0519df5 ("HID: sensor: Custom and Generic sensor support")
Cc: stable@vger.kernel.org
Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-sensor-custom.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
--- a/drivers/hid/hid-sensor-custom.c
+++ b/drivers/hid/hid-sensor-custom.c
@@ -771,26 +771,26 @@ static int hid_sensor_custom_probe(struc
return ret;
}
- ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj,
- &enable_sensor_attr_group);
+ ret = hid_sensor_custom_add_attributes(sensor_inst);
if (ret)
goto err_remove_callback;
- ret = hid_sensor_custom_add_attributes(sensor_inst);
+ ret = sysfs_create_group(&sensor_inst->pdev->dev.kobj,
+ &enable_sensor_attr_group);
if (ret)
- goto err_remove_group;
+ goto err_remove_attributes;
ret = hid_sensor_custom_dev_if_add(sensor_inst);
if (ret)
- goto err_remove_attributes;
+ goto err_remove_group;
return 0;
-err_remove_attributes:
- hid_sensor_custom_remove_attributes(sensor_inst);
err_remove_group:
sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
&enable_sensor_attr_group);
+err_remove_attributes:
+ hid_sensor_custom_remove_attributes(sensor_inst);
err_remove_callback:
sensor_hub_remove_callback(hsdev, hsdev->usage);
@@ -803,9 +803,10 @@ static int hid_sensor_custom_remove(stru
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
hid_sensor_custom_dev_if_remove(sensor_inst);
- hid_sensor_custom_remove_attributes(sensor_inst);
+ /* Remove enable_sensor first as it uses fields via power_state/report_state. */
sysfs_remove_group(&sensor_inst->pdev->dev.kobj,
&enable_sensor_attr_group);
+ hid_sensor_custom_remove_attributes(sensor_inst);
sensor_hub_remove_callback(hsdev, hsdev->usage);
return 0;
^ permalink raw reply [flat|nested] 64+ messages in thread
* [PATCH 5.10 57/57] HID: hyperv: validate initial device info bounds
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (55 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 56/57] HID: sensor: custom: Fix use-after-free in enable_sensor Greg Kroah-Hartman
@ 2026-08-25 13:27 ` Greg Kroah-Hartman
2026-08-25 17:47 ` [PATCH 5.10 00/57] 5.10.267-rc1 review Florian Fainelli
` (5 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Greg Kroah-Hartman @ 2026-08-25 13:27 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Jiri Kosina
5.10-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
commit 934b7778aa7b7c8f6bb073d2a73ba3674885bae0 upstream.
The Hyper-V synthetic HID host supplies SYNTH_HID_INITIAL_DEVICE_INFO
messages that contain a HID descriptor followed by the report descriptor
bytes. mousevsc_on_receive_device_info() trusts bLength and
wDescriptorLength without checking that the received packet contains both
byte ranges.
A malformed host or backend message can therefore make the guest read
past the received VMBus packet while copying the report descriptor. Pass
the received initial-device-info size into the parser and reject
descriptor lengths that exceed the packet.
Impact: A malicious Hyper-V host or backend can crash a guest by sending
a short initial device-info message with an oversized HID report
descriptor length.
Fixes: b95f5bcb811e ("HID: Move the hid-hyperv driver out of staging")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5-5-xhigh
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hid/hid-hyperv.c | 27 ++++++++++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
--- a/drivers/hid/hid-hyperv.c
+++ b/drivers/hid/hid-hyperv.c
@@ -179,18 +179,32 @@ static void mousevsc_free_device(struct
}
static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
- struct synthhid_device_info *device_info)
+ struct synthhid_device_info *device_info,
+ u32 device_info_size)
{
int ret = 0;
struct hid_descriptor *desc;
struct mousevsc_prt_msg ack;
+ size_t desc_offset;
+ size_t desc_size;
input_device->dev_info_status = -ENOMEM;
+ if (device_info_size < sizeof(*device_info)) {
+ input_device->dev_info_status = -EINVAL;
+ goto cleanup;
+ }
+
input_device->hid_dev_info = device_info->hid_dev_info;
desc = &device_info->hid_descriptor;
+ desc_offset = offsetof(struct synthhid_device_info, hid_descriptor);
+ desc_size = device_info_size - desc_offset;
if (desc->bLength == 0)
goto cleanup;
+ if (desc->bLength < sizeof(*desc) || desc->bLength > desc_size) {
+ input_device->dev_info_status = -EINVAL;
+ goto cleanup;
+ }
/* The pointer is not NULL when we resume from hibernation */
kfree(input_device->hid_desc);
@@ -205,6 +219,10 @@ static void mousevsc_on_receive_device_i
input_device->dev_info_status = -EINVAL;
goto cleanup;
}
+ if (input_device->report_desc_size > desc_size - desc->bLength) {
+ input_device->dev_info_status = -EINVAL;
+ goto cleanup;
+ }
/* The pointer is not NULL when we resume from hibernation */
kfree(input_device->report_desc);
@@ -285,14 +303,17 @@ static void mousevsc_on_receive(struct h
break;
case SYNTH_HID_INITIAL_DEVICE_INFO:
- WARN_ON(pipe_msg->size < sizeof(struct hv_input_dev_info));
+ if (WARN_ON_ONCE(pipe_msg->size <
+ sizeof(struct synthhid_device_info)))
+ break;
/*
* Parse out the device info into device attr,
* hid desc and report desc
*/
mousevsc_on_receive_device_info(input_dev,
- (struct synthhid_device_info *)pipe_msg->data);
+ (struct synthhid_device_info *)pipe_msg->data,
+ pipe_msg->size);
break;
case SYNTH_HID_INPUT_REPORT:
input_report =
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 5.10 00/57] 5.10.267-rc1 review
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (56 preceding siblings ...)
2026-08-25 13:27 ` [PATCH 5.10 57/57] HID: hyperv: validate initial device info bounds Greg Kroah-Hartman
@ 2026-08-25 17:47 ` Florian Fainelli
2026-08-25 19:26 ` Pavel Machek
` (4 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Florian Fainelli @ 2026-08-25 17:47 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, sudipm.mukherjee, rwarsow, conor,
hargar, broonie, achill, sr
On 8/25/26 06:26, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.10.267 release.
> There are 57 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 27 Aug 2026 13:25:02 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.267-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on
BMIPS_GENERIC:
Tested-by: Florian Fainelli <florian.fainelli@broadcom.com>
--
Florian
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 5.10 00/57] 5.10.267-rc1 review
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (57 preceding siblings ...)
2026-08-25 17:47 ` [PATCH 5.10 00/57] 5.10.267-rc1 review Florian Fainelli
@ 2026-08-25 19:26 ` Pavel Machek
2026-08-25 21:14 ` Woody Suwalski
` (3 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Pavel Machek @ 2026-08-25 19:26 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
[-- Attachment #1: Type: text/plain, Size: 505 bytes --]
Hi!
> This is the start of the stable review cycle for the 5.10.267 release.
> There are 57 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-5.10.y
Tested-by: Pavel Machek (CIP) <pavel@nabladev.com>
Best regards,
Pavel
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 5.10 00/57] 5.10.267-rc1 review
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (58 preceding siblings ...)
2026-08-25 19:26 ` Pavel Machek
@ 2026-08-25 21:14 ` Woody Suwalski
2026-08-26 5:03 ` Barry K. Nathan
` (2 subsequent siblings)
62 siblings, 0 replies; 64+ messages in thread
From: Woody Suwalski @ 2026-08-25 21:14 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
rwarsow, conor, hargar, broonie, achill, sr
Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.10.267 release.
> There are 57 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
>
Build for i386 and installed / booted on 32-bit EeePC. No problems noticed.
Tested-by: Woody Suwalski <terraluna977@gmail.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 5.10 00/57] 5.10.267-rc1 review
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (59 preceding siblings ...)
2026-08-25 21:14 ` Woody Suwalski
@ 2026-08-26 5:03 ` Barry K. Nathan
2026-08-26 8:02 ` Dominique Martinet
2026-08-26 10:32 ` Brett A C Sheffield
62 siblings, 0 replies; 64+ messages in thread
From: Barry K. Nathan @ 2026-08-26 5:03 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
rwarsow, conor, hargar, broonie, achill, sr
On 8/25/26 6:26 AM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 5.10.267 release.
> There are 57 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 27 Aug 2026 13:25:02 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.267-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
Tested on an amd64 laptop (Lenovo ThinkPad T14 Gen 1). Working well,
no regressions observed.
Tested-by: Barry K. Nathan <barryn@pobox.com>
--
-Barry K. Nathan <barryn@pobox.com>
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 5.10 00/57] 5.10.267-rc1 review
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (60 preceding siblings ...)
2026-08-26 5:03 ` Barry K. Nathan
@ 2026-08-26 8:02 ` Dominique Martinet
2026-08-26 10:32 ` Brett A C Sheffield
62 siblings, 0 replies; 64+ messages in thread
From: Dominique Martinet @ 2026-08-26 8:02 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
Greg Kroah-Hartman wrote on Tue, Aug 25, 2026 at 03:26:22PM +0200:
> This is the start of the stable review cycle for the 5.10.267 release.
> There are 57 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Thu, 27 Aug 2026 13:25:02 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v5.x/stable-review/patch-5.10.267-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-5.10.y
> and the diffstat can be found below.
Tested 8157cbcd6d36 ("Linux 5.10.267-rc1") on:
- arm i.MX6ULL (Armadillo 640)
- arm64 i.MX8MP (Armadillo G4)
- arm64 i.MX8ULP (Armadillo IoT A9E)
No obvious regression in dmesg or basic tests:
Tested-by: Dominique Martinet <dominique.martinet@atmark-techno.com>
--
Dominique Martinet
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: [PATCH 5.10 00/57] 5.10.267-rc1 review
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
` (61 preceding siblings ...)
2026-08-26 8:02 ` Dominique Martinet
@ 2026-08-26 10:32 ` Brett A C Sheffield
62 siblings, 0 replies; 64+ messages in thread
From: Brett A C Sheffield @ 2026-08-26 10:32 UTC (permalink / raw)
To: gregkh
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr,
Brett A C Sheffield
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 5.10.267-rc1-01361-g8157cbcd6d36 #1 SMP Wed Aug 26 09:57:37 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Tested-by: Brett A C Sheffield <bacs@librecast.net>
^ permalink raw reply [flat|nested] 64+ messages in thread
end of thread, other threads:[~2026-08-26 10:32 UTC | newest]
Thread overview: 64+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-25 13:26 [PATCH 5.10 00/57] 5.10.267-rc1 review Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 01/57] Bluetooth: RFCOMM: take rfcomm_mutex for the deferred setup accept Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 02/57] rndis_host: add overflow check in rndis_rx_fixup() Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 03/57] ocfs2: fix missing metadata reservation for large xattrs Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 04/57] ext4: stop retrying saturated xattr cache entries Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 05/57] ext4: clear error before retrying inode xattr space fallback Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 06/57] xfs: validate attr entry pointer before field access Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 07/57] net/x25: fix use-after-free of the socket by its timers Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 08/57] mm/huge_memory: fix huge_zero_pfn race Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 09/57] staging: rtl8723bs: fix OOB read in WMM_param_handler() Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 10/57] misc: fastrpc: separate fastrpc device from channel context Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 11/57] misc: fastrpc: Rework fastrpc_req_munmap Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 12/57] misc: fastrpc: Remove buffer from list prior to unmap operation Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 13/57] net: ipv4: Publish fib_nlmsg_size() Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 14/57] ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 15/57] NTB: ntb_netdev: Preserve RX queue depth on allocation failure Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 16/57] serial: amba-pl011: synchronize DMA teardown Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 17/57] perf: Fix cgroup state vs ERROR Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 18/57] perf: Fix dangling cgroup pointer in cpuctx Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 19/57] perf/core: Fix group leader use-after-free after sibling detach Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 20/57] packet: use consistent hard_header_len in non-ring send paths Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 21/57] packet: use consistent hard_header_len in TX_RING send path Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 22/57] net/sched: reject overly deep qdisc hierarchies Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 23/57] packet: synchronize pressure clearing with ring reconfiguration Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 24/57] inet: frags: publish queues before arming timer Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 25/57] xfs: fix ilock leak on error in xfs_dq_get_next_id Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 26/57] mmc: atmel-mci: Fix use-after-free in atmci_remove due to race condition Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 27/57] s390/vfio_ccw: Cancel existing workqueues Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 28/57] KVM: arm64: Retry fault if vma_lookup() results become invalid Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 29/57] nfc: digital: clamp SENSF_RES length to the destination buffer Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 30/57] nfc: fdp: bound the device-reported read length and fix an skb leak Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 31/57] nfc: microread: validate target discovery payload lengths Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 32/57] nfc: llcp: bound the connect_sn TLV walk to the skb Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 33/57] nfc: llcp: fix OOB read and u8 offset wrap in TLV parsers Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 34/57] nfc: llcp: reject PDUs shorter than the LLCP header Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 35/57] nfc: pn533: purge fragmented skbs during cleanup Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 36/57] nfc: st21nfca: validate ATR_REQ length against the received frame Greg Kroah-Hartman
2026-08-25 13:26 ` [PATCH 5.10 37/57] nfc: nci: fix out-of-bounds write in nci_target_auto_activated() Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 38/57] nfc: nci: free destination parameters when closing a connection Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 39/57] xfs: bounds-check buffer log items dirty bitmap Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 40/57] ipv4: reject undersized MTUs in ip_do_fragment() Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 41/57] ipv6: fix use-after-free in ip6_finish_output2() Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 42/57] nvmet-fc: fix invalid free in LS IOD error path Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 43/57] nvmet-tcp: Do not WARN on remotely-controlled oversized SGL allocations Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 44/57] gpio: ml-ioh: use raw_spinlock_t for the register lock Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 45/57] libceph: fix OOB read in decode_watchers() via missing bounds check Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 46/57] HID: magicmouse: Prevent out-of-bounds (OOB) read during DOUBLE_REPORT_ID Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 47/57] HID: core: fix OOB read of field->usage in hid_set_field() Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 48/57] Revert "Input: ims-pcu - fix race condition in reset_device sysfs callback" Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 49/57] xfrm: fix sk_dst_cache double-free in xfrm_user_policy() Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 50/57] iomap: adjust read range correctly for non-block-aligned positions Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 51/57] s390/vfio_ccw: Free all memory if cp_init() fails Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 52/57] bpf: reject negative CO-RE accessor indices in bpf_core_parse_spec() Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 53/57] can: use skb hash instead of private variable in headroom Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 54/57] can: isotp: fix timer drain order, wakeup handling and tx_gen ordering Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 55/57] HID: core: fix number/pointer type confusion on long items Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 56/57] HID: sensor: custom: Fix use-after-free in enable_sensor Greg Kroah-Hartman
2026-08-25 13:27 ` [PATCH 5.10 57/57] HID: hyperv: validate initial device info bounds Greg Kroah-Hartman
2026-08-25 17:47 ` [PATCH 5.10 00/57] 5.10.267-rc1 review Florian Fainelli
2026-08-25 19:26 ` Pavel Machek
2026-08-25 21:14 ` Woody Suwalski
2026-08-26 5:03 ` Barry K. Nathan
2026-08-26 8:02 ` Dominique Martinet
2026-08-26 10:32 ` Brett A C Sheffield
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).