summaryrefslogtreecommitdiff
AgeCommit message (Collapse)AuthorFilesLines
6 daysLinux 7.2.2v7.2.2Greg Kroah-Hartman1-1/+1
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
6 daysinet: frags: strip GSO state from fragments before reassemblyXinyang Ge1-0/+7
commit d5dc1e69fd7258ea605c9952e5d5947539159ae3 upstream. A virtio_net_hdr (tun/tap, or AF_PACKET with PACKET_VNET_HDR) can mark an IPv4 or IPv6 fragment as GSO; nothing relates gso_type to frag_off. inet_frag_reasm_prepare()/inet_frag_reasm_finish() keep the first fragment's skb as the head of the reassembled datagram, including its shinfo->gso_size/gso_type/gso_segs, and chain the remaining fragments on frag_list with whatever linear/paged layout they arrived with. After ip_defrag() (ip_local_deliver(), nf_defrag_ipv4, ...) the reassembled skb therefore still claims to be GSO (SKB_GSO_DODGY), and the next software segmentation point - udp_rcv_segment() on local delivery, validate_xmit_skb(), or the ip_finish_output_gso() slow path - hands it to skb_segment(). skb_segment()'s frag_list walk assumes GRO-shaped input and hits one of its BUG_ON()s. Two writes to a tap by an unprivileged user in its own userns are enough: kernel BUG at net/core/skbuff.c:4899! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI CPU: 0 UID: 1000 PID: 82 Comm: poc Not tainted 7.2.0-pentest+ #2 RIP: 0010:skb_segment+0x20ca/0x48b0 Call Trace: <TASK> __udp_gso_segment+0x29a/0x27d0 udp4_ufo_fragment+0x458/0x6c0 inet_gso_segment+0x429/0x1340 skb_mac_gso_segment+0x233/0x4f0 __skb_gso_segment+0x308/0x660 udp_queue_rcv_skb+0x440/0xad0 udp_unicast_rcv_skb+0xc7/0x2c0 udp_rcv+0x16ce/0x2260 ip_protocol_deliver_rcu+0x197/0x2d0 ip_local_deliver+0x430/0x690 ip_rcv+0x16f/0x1f0 __netif_receive_skb_one_core+0x15e/0x1c0 __netif_receive_skb+0x1e/0x110 netif_receive_skb+0xf6/0x5c0 tun_rx_batched.isra.0+0x3ab/0x790 tun_get_user+0x17c3/0x3550 tun_chr_write_iter+0xba/0x1b0 vfs_write+0x646/0x1130 </TASK> Kernel panic - not syncing: Fatal exception in interrupt This runs with BH disabled, so it is a panic rather than an oops. The same is reachable with CAP_NET_RAW in a netns where a defrag point precedes a GSO point, and from a guest whose VMM forwards virtio_net_hdr to a tap. The SKB_GSO_DODGY frag_list checks added by commit 3dcbdb134f32 ("net: gso: Fix skb_segment splat when splitting gso_size mangled skb having linear-headed frag_list") and by commit 9e4b7a99a03a ("net: gso: fix panic on frag_list with mixed head alloc types") do not cover it: page-backed heads skip them, and kmalloc heads skip them when gso_size == skb_headlen(head), which the sender controls. An skb entering a frag queue is an IP fragment by definition and cannot legitimately carry GSO state: GRO does not merge fragments and the stack segments before it fragments, so only untrusted sources are affected. This has been reachable since commit f43798c27684 ("tun: Allow GSO using virtio_net_hdr"), the first path that let userspace attach GSO metadata to an IP fragment. Reset the GSO fields of every fragment as it is queued, in inet_frag_queue_insert(), which IPv4, IPv6, nf_conntrack_reasm and 6lowpan reassembly share; then neither the head nor the frag_list members of the reassembled skb carry them (the members matter too: the ip_do_fragment()/ip6_fragment() fast paths send them out as they are). The head may remain CHECKSUM_PARTIAL; that is already accepted on receive and resolved by skb_checksum_help() in ip_do_fragment()/ip6_fragment() on forward. Tested on top of net.git (dc4b95b8fee9), x86_64: the tap reproducer above, two further IPv4 frag_list geometries that reach BUG_ON(i >= nfrags) and BUG_ON(!list_skb->head_frag), and an IPv6 fragment-header variant (udp6_ufo_fragment()) each panic the unpatched kernel; with this patch all four datagrams are delivered intact and nothing is logged. Fixes: f43798c27684 ("tun: Allow GSO using virtio_net_hdr") Cc: stable@kernel.org Suggested-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Xinyang Ge <xinyang@anthropic.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/937926e509f2acd8e0e66520dc2b30fd6b4d1687.1787839506.git.pabeni@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysLinux 7.2.1v7.2.1Greg Kroah-Hartman1-1/+1
Link: https://lore.kernel.org/r/20260825132541.560541185@linuxfoundation.org Tested-by: Ronald Warsow <rwarsow@gmx.de> Tested-by: Justin M. Forbes <jforbes@fedoraproject.org> Tested-by: Florian Fainelli <florian.fainelli@broadcom.com> Tested-by: Shuah Khan <skhan@linuxfoundation.org> Tested-by: Ron Economos <re@w6rz.net> Tested-by: Barry K. Nathan <barryn@pobox.com> Tested-by: Salvatore Bonaccorso <carnil@debian.org> Tested-by: Brett A C Sheffield <bacs@librecast.net> Tested-by: Miguel Ojeda <ojeda@kernel.org> Tested-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Tested-by: Peter Schneider <pschneider1968@googlemail.com> Tested-by: Benjamin Boortz <bennib@mailbox.org> Tested-by: Mark Brown <broonie@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysptp: vmclock: prevent read-only mappings from becoming writableAbdifatah Suruur1-0/+6
commit a5edadbae57e2298a56cf7a4e774a027905a331f upstream. vmclock_miscdev_mmap() rejects writable mappings of the shared vmclock ABI page with -EROFS, but leaves VM_MAYWRITE set. Userspace can map the page read-only and then upgrade it to writable with mprotect(), after which the guest can corrupt the host-written timekeeping data (sequence counter, UTC time, TSC offset) that the vmclock ABI defines as read-only. Clear VM_MAYWRITE on the read-only path so the mapping cannot be upgraded, as i915 does for its read-only objects and as fixed in drm/vc4 (CVE-2026-68445) and drm/panthor (CVE-2024-53071). Cc: stable@vger.kernel.org Fixes: 205032724226 ("ptp: Add support for the AMZNC10C 'vmclock' device") Signed-off-by: Abdifatah Suruur <suruurism@gmail.com> Link: https://patch.msgid.link/20260813174707.14809-1-suruurism@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysfutex: Fix might_sleep() warning in futex_pivot_pending()Peter Zijlstra5-4/+54
[ Upstream commit d8aa5dd97944a72d4a9e3cc79bb80fcac7d6e829 ] A younger me put a WARN in might_sleep() to warn about nested sleep loops. This younger me also build a wait-loop variant that can deal with it. This wait-loop variant doesn't have all the fancy wrappers, since it isn't used much. It also lacks wait-bit support. Add the wait-bit support and use it to fix the nested wait issue. Fixes: 8e7ff730dd96 ("futex: Fix race in futex_pivot_pending() during private hash resize") Reported-by: syzbot+350a93852ac854927f45@syzkaller.appspotmail.com Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Signed-off-by: Thomas Gleixner <tglx@kernel.org> Link: https://patch.msgid.link/20260820074927.GH1246887@noisy.programming.kicks-ass.net Closes: https://syzkaller.appspot.com/bug?extid=350a93852ac854927f45 Signed-off-by: Sasha Levin <sashal@kernel.org>
7 daysBluetooth: hci_aml: validate firmware segment lengthsLaxman Acharya Padhya1-2/+16
commit 2bf6b9baca9372ea51b6d0f2820dc9bf29a83ef4 upstream. aml_download_firmware() reads two lengths from the firmware header and uses them to build pointers before checking that the header and segment data are present. A truncated or inconsistent firmware image can make the driver read past firmware->data while constructing TCI commands. Reject images shorter than the header and ensure that the ICCM and DCCM ranges fit within the loaded firmware before downloading either segment. Fixes: 37bac77e4649 ("Bluetooth: hci_uart: Add support for Amlogic HCI UART") Cc: stable@vger.kernel.org Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysBluetooth: MGMT: reject HCI_CMD_SYNC params_len above 255Ali Ahmet Memis1-0/+8
commit 5d95286b6d6e8f1d304da7522bfa6860fc017e48 upstream. mgmt_hci_cmd_sync() checks that the message length agrees with params_len but puts no upper bound on it. params_len is __le16 while the parameter length in the HCI command header is a u8: struct hci_command_hdr { __le16 opcode; __u8 plen; } __packed; hci_cmd_sync_alloc() assigns one to the other: hdr->plen = plen; if (plen) skb_put_data(skb, param, plen); so a params_len of 256 leaves plen at 0 while all 256 bytes are still appended. The frame handed to the driver then declares no parameters and carries 256 of them. On a length framed transport such as H:4 the controller takes the trailing bytes as the start of the next packet. The mgmt socket MTU is HCI_MAX_FRAME_SIZE, so params_len can reach about 1KB this way. Commit 03f1700b9b4d ("Bluetooth: MGMT: reject malformed HCI_CMD_SYNC commands") only made params_len agree with the message length, a value that fits the message but not the header field is still accepted. Reject params_len that does not fit the header field. Fixes: 827af4787e74 ("Bluetooth: MGMT: Add initial implementation of MGMT_OP_HCI_CMD_SYNC") 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>
7 daysBluetooth: ISO: zero the sockaddr before returning it in getnameAli Ahmet Memis1-0/+2
commit 884cf2cc957da7ac178a0e6c6c69ddfec0481cc8 upstream. iso_sock_getname() fills a struct sockaddr_iso in place and returns its size without clearing it first, so bytes it does not write are copied to user space from the kernel stack. The getsockname(2) and getpeername(2) paths both run through do_getsockname(), which hands getname() an uninitialized sockaddr_storage on the stack and copies back up to the number of bytes getname() returns, so the driver has to initialize every byte it accounts for. Two ranges are left uninitialized: - struct sockaddr_iso is 10 bytes but only 9 are written (family, iso_bdaddr, iso_bdaddr_type), leaking the trailing pad byte on every call. - for a broadcast peer (BIS_LINK or PA_LINK) the returned length grows by sizeof(struct sockaddr_iso_bc), but only bc_sid, bc_num_bis and bc_bis are filled; bc_bdaddr and bc_bdaddr_type, the first 7 bytes of that structure, are never written. An unprivileged process can open a BTPROTO_ISO socket and reach the pad leak with getsockname(); the broadcast leak needs an established BIS/PA connection. l2cap and rfcomm already memset their sockaddr in getname for the same reason; do the same here. Fixes: ccf74f2390d6 ("Bluetooth: Add BTPROTO_ISO socket type") Fixes: 0a766a0affb5 ("Bluetooth: ISO: Fix getpeername not returning sockaddr_iso_bc fields") 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>
7 daysBluetooth: ISO: do not force BT_LISTEN after a failed BIG syncAli Ahmet Memis1-8/+22
commit 9838a80096ba472d5e03057136a112631aabae6e upstream. iso_sock_recvmsg() handles the deferred setup of a broadcast sink by dropping the socket lock, calling iso_conn_big_sync() and taking the lock again: release_sock(sk); iso_conn_big_sync(sk); lock_sock(sk); sk->sk_state = BT_LISTEN; The state is written unconditionally, but iso_conn_big_sync() returns void and has paths that do nothing at all: hci_get_route() may fail, and after re-acquiring the socket lock the connection may already be gone, in which case it bails out without ever issuing an LE BIG Create Sync. While the lock is dropped the connection can be torn down, for example when the controller reports HCI_EV_LE_PA_SYNC_LOST: hci_le_pa_sync_lost_evt() hci_disconn_cfm() -> iso_disconn_cfm() -> iso_conn_del() iso_chan_del() iso_pi(sk)->conn = NULL sk->sk_state = BT_CLOSED sock_set_flag(sk, SOCK_ZAPPED) iso_conn_big_sync() then finds conn == NULL and returns, but the caller still overwrites the BT_CLOSED that iso_chan_del() has just set. The socket ends up marked BT_LISTEN with no connection, so recvmsg() reports success for a setup that never happened and a later accept() waits for BIS connections that can never arrive instead of failing. A concurrent shutdown() reaches the same write by another route: __iso_sock_close() takes the BT_CONNECT2 PA sync path to iso_sock_disconn(), which sets BT_DISCONN but leaves conn and conn->hcon in place, so iso_conn_big_sync() succeeds and BT_LISTEN is written over BT_DISCONN. Both the BT_CONNECT2 and the BT_CONNECTED case write the state the same way. Let iso_conn_big_sync() report whether the BIG sync was started, and only move the socket to BT_LISTEN when it was and when the state has not changed while the lock was dropped, mirroring what the BT_CONNECT case of the same switch already does with iso_connect_cis(). Both conditions are needed, the error alone does not cover the shutdown() race. This corrupts the socket state machine only, it is not a memory safety issue. KASAN and lockdep stayed quiet in all of the runs below. Reproduced with an emulated controller over /dev/vhci on a KASAN + PROVE_LOCKING kernel. A PA sync broadcast sink socket is driven to BT_CONNECT2 and recvmsg() on it is raced against teardown, with a debug delay inside the lock-dropped section to widen the window: - HCI_EV_LE_PA_SYNC_LOST injected: 64 of 64 rounds left the socket in BT_LISTEN with the connection gone, recvmsg() returned 0 and accept() on that fd returned EAGAIN, which iso_sock_accept() can only do while the socket is BT_LISTEN. With this patch, 0 of 64, recvmsg() returns an error and accept() returns EBADFD. - shutdown() instead of a controller event: 24 of 32 rounds wedged in BT_LISTEN, 0 of 32 with this patch. With only the error check in place and a short window, one round still wedged while recvmsg() returned 0, which is the case the state re-check covers. An unraced control round behaves the same before and after: recvmsg() returns 0, the socket reaches BT_LISTEN and an LE BIG Create Sync is issued. Fixes: 7a17308c1788 ("Bluetooth: iso: Fix circular lock in iso_conn_big_sync") 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>
7 daysBluetooth: hci_sync: Fix accept list UAF during suspendChengfeng Ye1-9/+37
commit f57b399c4fa1501b2d5451f52d861ece86bcf3db upstream. hci_update_event_filter_sync() walks hdev->accept_list while sending a synchronous HCI command for each remote-wakeup device. The suspend path holds hdev->req_lock, but accept-list updates are serialized by hdev->lock. Consequently, remove_device() can free the current list entry during the controller wait. The following interleaving causes the use-after-free: hci_update_event_filter_sync() remove_device() fetch accept-list entry hci_set_event_filter_sync() wait for controller response hci_dev_lock() list_del() kfree() hci_dev_unlock() read the freed list.next KASAN reported: BUG: KASAN: slab-use-after-free in hci_suspend_sync+0x835/0x910 Read of size 8 at addr ffff88810bec8440 by task kworker/0:1/10 Workqueue: events vhci_suspend_work Call Trace: hci_suspend_sync+0x835/0x910 hci_suspend_dev+0x182/0x450 process_one_work+0x661/0x1090 worker_thread+0x45b/0xd10 Allocated by task 86: hci_bdaddr_list_add_with_flags+0x1a8/0x400 add_device+0x381/0x820 hci_sock_sendmsg+0x1033/0x1ea0 Freed by task 91: kfree+0x131/0x3c0 remove_device+0x429/0xb70 hci_sock_sendmsg+0x1033/0x1ea0 Snapshot the remote-wakeup addresses under hdev->lock. Release the lock before sending HCI commands. Clear the controller event filter before building the snapshot, and skip allocation and the second list traversal when there are no matching entries. This preserves the original filter and scan-state updates without retaining an accept-list node across a controller wait. Fixes: 182ee45da083 ("Bluetooth: hci_sync: Rework hci_suspend_notifier") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/linux-bluetooth/20260730092331.2069741-1-nicoyip.dev@gmail.com/ Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysBluetooth: hci_event: validate LE Set CIG Parameters responseLaxman Acharya Padhya1-2/+4
commit 0acd4eeb4b225b9bebbf9ef96cc10cdd79b94899 upstream. The Command Complete dispatch validates only the fixed part of the LE Set CIG Parameters response. After that part is pulled from the skb, hci_cc_le_set_cig_params() trusts num_handles and reads each entry in the trailing handle array. Matching num_handles against the command's num_cis does not guarantee that the response contains the advertised handles. A truncated response from a malfunctioning controller can therefore make the handler read beyond the skb data. Validate that the remaining skb data contains all advertised handles. Include this in the existing response validation so malformed responses also follow the established CIG failure handling. Fixes: 26afbd826ee3 ("Bluetooth: Add initial implementation of CIS connections") Cc: stable@vger.kernel.org Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysBluetooth: hci_event: fix LE list UAF on resetChengfeng Ye1-0/+2
commit 33af47e847fe4a28b109673affb5874015d54f5a upstream. hci_cc_reset() clears the LE accept and resolving lists without taking hdev->lock. Other command-complete handlers serialize updates to these lists with that lock, and the debugfs readers hold it while walking them. This permits the reset completion and a debugfs read to interleave as follows: hci_rx_work debugfs reader ----------- -------------- lock hdev->lock fetch current entry list_del(entry) kfree(entry) read entry fields The reader then dereferences a freed list entry and may follow its stale next pointer. KASAN reported: BUG: KASAN: slab-use-after-free in white_list_show+0x15f/0x180 Read of size 1 at addr ffff8881015dab16 by task poc/95 Call Trace: white_list_show+0x15f/0x180 seq_read_iter+0x3ff/0x1190 seq_read+0x267/0x3d0 vfs_read+0x177/0xa20 ksys_read+0xf7/0x1c0 Allocated by task 91: hci_bdaddr_list_add+0x1a6/0x3a0 hci_cc_le_add_to_accept_list+0xab/0x140 hci_cmd_complete_evt+0x26c/0x9a0 hci_event_packet+0x454/0xb20 hci_rx_work+0x293/0x730 Freed by task 90: kfree+0x131/0x3c0 hci_bdaddr_list_clear+0xd8/0x160 hci_cc_reset+0x28a/0x370 hci_cmd_complete_evt+0x26c/0x9a0 hci_event_packet+0x454/0xb20 hci_rx_work+0x293/0x730 Take hdev->lock around both list clears. This matches the existing mutation and traversal locking convention. Fixes: a4d5504d5c39 ("Bluetooth: Clear LE white list when resetting controller") Fixes: cfdb0c2d095a ("Bluetooth: Store Resolv list size") Cc: stable@vger.kernel.org Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com> Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: input: read battery capacity from its actual report offsetJose Villaseñor Montfort2-4/+15
commit d07644524b6511b622ee7b0e2e68c9ee43d522a4 upstream. hidinput_query_battery_capacity() assumes the state-of-charge value is the first byte following the report ID (buf[1]) and ignores where the battery field actually sits within the report. An Apple Magic Trackpad 2 precedes the AbsoluteStateOfCharge byte with a byte of status flags in its battery reports, so this query returns the flags byte instead of the charge level. The device happens to make that easy to observe, because it exposes the same cell twice: its report descriptor declares AbsoluteStateOfCharge in two reports (0x90 and 0x9b), so hidinput_setup_battery() registers two power supplies. Only the first one is refreshed by hid-magicmouse -- it uses hid_get_battery(), which returns the first battery of the list -- and that refresh goes through the report event path, which parses the field correctly. Nothing ever reports the second one, so every read of its capacity takes the query path above. On a USB-C Magic Trackpad over USB, on an unpatched 7.1.5: hid-<serial>-battery-144 = 100% (Charging) <- report event path hid-<serial>-battery-155 = 3% (Discharging) <- query path Both are the same physical battery. A raw HIDIOCGINPUT of the two reports at that same moment: report 0x90 -> [90 03 64] report 0x9b -> [9b 03 64 64 00 00 10 00 00 00 00 00 00 00] ^flags ^SoC = 0x64 = 100% The device answers correctly in both cases; only the offset the kernel reads the capacity from is wrong. 0x03 is the flags byte (present, charging), reported as "3%". Bluetooth takes the same query path for its capacity, where the trackpad reported a bogus near-constant ~4% -- 0b100, the FullyCharged flag -- regardless of the real charge. Store the battery field's offset within the report at setup time and use it when querying, so the capacity is read from its real position. The report event path already parses the field correctly through the HID core; only the explicit GET_REPORT query was wrong. Devices whose capacity field is the first field in the report have a report_offset of 0 and are unaffected (buf[1 + 0] == buf[1]). Fixes: 581c4484769e ("HID: input: map digitizer battery usage") Cc: stable@vger.kernel.org Signed-off-by: Jose Villaseñor Montfort <pepemontfort@gmail.com> Reviewed-by: Alec Hall <signshop.alec@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: hyperv: validate initial device info boundsMichael Bommarito1-3/+24
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>
7 daysHID: uclogic: fix use-after-free of inrange_timer on removeIbrahim Hashimov1-1/+11
commit 506fd50a9027340f0e9dcc587d10ccb03312dba6 upstream. uclogic_remove() cancels the pen in-range timer and then stops the device: timer_delete_sync(&drvdata->inrange_timer); hid_hw_stop(hdev); timer_delete_sync() only guarantees the timer is idle at that instant. uclogic_raw_event_pen() keeps delivering pen reports until hid_hw_stop() stops the transport several lines later, and every report with pen->inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE re-arms the timer: mod_timer(&drvdata->inrange_timer, jiffies + msecs_to_jiffies(100)); A report landing between the timer_delete_sync() call and the transport teardown in hid_hw_stop() re-arms inrange_timer after it was cancelled. uclogic_remove() then returns and the devm drvdata is freed, while hid_hw_stop() has already freed the input device drvdata->pen_input points at, so when the timer fires ~100 ms later uclogic_inrange_timeout() dereferences freed memory -- a use-after-free in timer-softirq context. Swapping the two calls is not a fix: stopping the device first frees drvdata->pen_input via hidinput_disconnect() while the timer may still be pending, so a timer already armed before removal fires on the freed input device in the window before timer_delete_sync() runs. Use timer_shutdown_sync() before hid_hw_stop() instead. It cancels the timer, waits for a running callback while pen_input is still valid, and prevents any further re-arming -- a later mod_timer() from an in-flight report is silently ignored -- so the timer is provably dead before hid_hw_stop() frees the inputs. This is the ordering the timer core documents for this "timer re-armed from another path" teardown case. Fixes: 01309e29eb95 ("HID: uclogic: Support in-range reporting emulation") Cc: stable@vger.kernel.org Signed-off-by: Ibrahim Hashimov <security@auditcode.ai> Assisted-by: AuditCode-AI:2026.07 Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: sensor: custom: Fix use-after-free in enable_sensorHaoxiang Li1-8/+9
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>
7 daysHID: ft260: fix stack-use-after-return write in I2C read raceRaman Varabets1-1/+24
commit bf3e39df3a397fd82967a31d17c4e02c7feab221 upstream. ft260_i2c_read() points dev->read_buf at a caller-supplied buffer (often an on-stack variable), arms a completion and waits up to five seconds for the device to return the data. The HID input callback ft260_raw_event() runs in the input/IRQ path, independent of the dev->lock mutex held by the read path, and copies the device-supplied payload into dev->read_buf after a plain NULL check. These two paths share read_buf, read_idx and read_len with no serialization. If the device delays its response until the read times out, ft260_i2c_read() resets the controller, clears read_buf and returns, unwinding the stack frame the buffer lived in. A response that arrives at that moment lets ft260_raw_event() pass the NULL check and then memcpy() the device-controlled payload into the now-freed stack location, a bounded but attacker-influenced stack-use-after-return write triggerable by malicious or malfunctioning hardware. Add a dedicated spinlock that serializes every access to read_buf, read_idx and read_len. ft260_raw_event() now holds it across the NULL check, the memcpy and the index update, while the read path takes it when arming and when clearing the buffer, so the teardown can no longer slip between the check and the copy. Fixes: 6a82582d9fa4 ("HID: ft260: add usb hid to i2c host bridge driver") Cc: stable@vger.kernel.org Signed-off-by: Raman Varabets <kernel-linux-20260610-80b7ab08@raman.v1.sg> Reviewed-by: Michael Zaidman <michael.zaidman@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: core: fix number/pointer type confusion on long itemsJann Horn1-0/+6
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>
7 daysHID: rapoo: fix missing hid_is_usb() checkJann Horn2-1/+2
commit b57af2448268c30c25509a832b6ff6dc27176b28 upstream. to_usb_interface() can only be used on a hid_device whose parent is really USB; uhid can create devices that identify as being on BUS_USB, but don't actually have a USB parent. Fix the use of to_usb_interface() without a hid_is_usb() check. Add a dependency on USB_HID for hid_is_usb(), as other HID drivers do; the alternative would be to provide a simple stub implementation on !USB_HID builds. I have verified that it is currently possible to trigger a kernel splat due to this bug in an ASAN build, and that this commit fixes the issue. Fixes: b3b1c68fb726 ("HID: rapoo: Add support for side buttons on RAPOO 0x2015 mouse") 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>
7 daysHID: nintendo: stop device IO before hid_hw_stop on probe failureJiangshan Yi1-3/+4
commit 1f74d3bff6fe04a64e02ab3661d2e0d554565aa6 upstream. nintendo_hid_probe() calls hid_device_io_start() before joycon_init() and joycon_leds_create(). If either fails, the error path jumps to err_close which calls hid_hw_close()/hid_hw_stop() without first calling hid_device_io_stop(). hid_hw_stop() does not stop device IO, so hid_input_report() may still run and access driver data that is being torn down, resulting in a use-after-free. Add an err_io_stop label that calls hid_device_io_stop() before hid_hw_close(), and point the two post-io_start error paths at it. Fixes: 2af16c1f846b ("HID: nintendo: add nintendo switch controller driver") Cc: stable@vger.kernel.org Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: nintendo: register input device after capabilities are setJiangshan Yi1-4/+4
commit d723bc1fe2e72b9252234e94c11af644ec477bf7 upstream. input_register_device() exposes the device to userspace immediately. In joycon_input_create() it was called before joycon_config_rumble() configures the FF_RUMBLE capability and the memless force-feedback device, so a concurrent EVIOCSFF could dereference a NULL dev->ff. Registering early also means the initial udev event lacks button and axis information, which can make input managers ignore the device. Move input_register_device() to the end of joycon_input_create(), after all capabilities, the IMU input device and the force-feedback callbacks have been configured. Fixes: 2af16c1f846b ("HID: nintendo: add nintendo switch controller driver") Reported-by: sashiko-bot@kernel.org Closes: https://sashiko.dev/#/patchset/20260730031927.25444-1-yijiangshan@kylinos.cn?part=1 Cc: stable@vger.kernel.org Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn> Link: https://sashiko.dev/#/patchset/20260730031927.25444-1-yijiangshan@kylinos.cn?part=1 Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: nintendo: fix out-of-bounds read in joycon_ctlr_read_handler()Ibrahim Hashimov1-1/+6
commit 27b376b945c0aac46fcdfcc950b14a85b874b557 upstream. joycon_ctlr_read_handler() casts an incoming HID input report to struct joycon_input_report and parses it, guarding the cast only with a 12-byte length check: if (size >= 12) /* make sure it contains the input report */ joycon_parse_report(ctlr, (struct joycon_input_report *)data); struct joycon_input_report is 49 bytes: a 13-byte header followed by a union whose IMU arm is 36 bytes. For an IMU report joycon_parse_report() -> joycon_parse_imu_report() walks that union (struct offsets 13..48), so a report of exactly 12 bytes with data[0] == JC_INPUT_IMU_DATA passes the guard yet is read up to 37 bytes past its declared length. The over-read bytes are decoded into accelerometer/gyroscope values and forwarded to userspace through the "(IMU)" input device, leaking driver-internal memory. data[0] and size are fully controlled by a malicious or spoofed Joy-Con/Pro Controller. Receive buffers are sized to the maximum report length, so this is an over-read within the allocation rather than a slab OOB, but the decoded bytes still reach userspace. The sibling subcmd path in joycon_ctlr_handle_event() already bounds the same cast correctly: if (size < sizeof(struct joycon_input_report) || data[0] != JC_INPUT_SUBCMD_REPLY) break; Use the same sizeof(struct joycon_input_report) bound here. Fixes: 2af16c1f846b ("HID: nintendo: add nintendo switch controller driver") Cc: stable@vger.kernel.org Signed-off-by: Ibrahim Hashimov <security@auditcode.ai> Assisted-by: AuditCode-AI:2026.07 Reviewed-by: Silvan Jegen <s.jegen@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: huawei: fix missing hid_is_usb() checkJann Horn1-2/+3
commit 4cdb6b4b34d7823254f6e1b22faf56c96ac57fb9 upstream. to_usb_interface() can only be used on a hid_device whose parent is really USB; uhid can create devices that identify as being on BUS_USB, but don't actually have a USB parent. Fix the use of to_usb_interface() without a hid_is_usb() check. I have verified that it is currently possible to trigger a kernel splat due to this bug in an ASAN build, and that this commit fixes the issue. Fixes: e93faaca84b7 ("HID: huawei: fix CD30 keyboard report descriptor issue") 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>
7 daysHID: asus: fix missing hid_is_usb() checkJann Horn1-1/+1
commit 02bf61dfb44f17ec187d1da1a82495951bbd12df upstream. to_usb_interface() can only be used on a hid_device whose parent is really USB; uhid can create devices that identify as being on BUS_USB, but don't actually have a USB parent. Fix the use of to_usb_interface() without a hid_is_usb() check. I have verified that it is currently possible to trigger a kernel splat due to this bug in an ASAN build, and that this commit fixes the issue. Fixes: 00e005c952f7 ("hid-asus: check ROG Ally MCU version and warn") 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>
7 daysnet/ionic: avoid OOB TX partner lookup for hwstamp RXQAnand Khoje2-3/+21
commit d92255b405fb6f5acca408239ccd742e0a42c9cb upstream. The dedicated hardware timestamp RX queue is allocated with q->index equal to lif->ionic->nrxqs_per_lif. The normal txqcqs array only contains the regular queue pairs, so using that index to set rxq->partner can read one entry past txqcqs[] and then write through the derived pointer. Only link RX/TX partners for normal queue-pair indexes. Leave the hwstamp RX queue unpaired, and make the XDP_TX path abort cleanly if an RX queue has no TX partner. Fixes: 8eeed8373e1c ("ionic: Add XDP_TX support") Reviewed-by: Si-Wei Liu <si-wei.liu@oracle.com> Reviewed-by: Shannon Nelson <sln@onemain.com> Cc: stable@vger.kernel.org Signed-off-by: Anand Khoje <anand.a.khoje@oracle.com> Reviewed-by: Simon Horman <horms@kernel.org> Reviewed-by: Brett Creeley <brett.creeley@amd.com> Link: https://patch.msgid.link/20260813083705.454897-1-anand.a.khoje@oracle.com Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: pidff: fix OOB write when hid->inputs is emptyBaul Lee1-3/+10
commit 67bb1074e3d2d12fa059a9cc707e89398a4e4704 upstream. hid_pidff_init_with_quirks() derives its input_dev from list_entry(hid->inputs.next, struct hid_input, list) without first checking that hid->inputs is non-empty. The list member of struct hid_input is at offset 0, so on an empty list list_entry() yields &hid->inputs itself and the following hidinput->input load reads an unrelated member of struct hid_device. dev is then a type-confused pointer, and force-feedback init writes through it: each set_bit(FF_*, dev->ffbit) stores 8 bytes at dev + 192, past the end of the object dev actually aliases, and input_ff_create() adds further writes of a heap pointer and two function pointers. Until hid-universal-pidff the only caller was hid_pidff_init() from usbhid, which runs under HID_CLAIMED_INPUT and therefore always has at least one hid_input. universal_pidff_probe() starts the device with HID_CONNECT_DEFAULT & ~HID_CONNECT_FF and then calls hid_pidff_init_with_quirks() directly whenever the descriptor carries a PID usage page, bypassing that gate. A report descriptor whose only application collection is on HID_UP_PID leaves hid->inputs empty while hid_connect() still succeeds through the hidraw claim, so probe reaches the unguarded list_entry(). The write happens in the USB probe path, on the hotplug workqueue, so plugging in a malicious device is enough to trigger it; no attacker software and no logged-in user are required. KASAN reports an 8-byte out-of-bounds write in hid_pidff_init_with_quirks() reached from universal_pidff_probe(). Check for an empty list before deriving dev and return -ENODEV, as the other HID force-feedback drivers already do. universal_pidff_probe() propagates the error and unwinds. Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com> Fixes: f06bf8d94fff ("HID: Add hid-universal-pidff driver and supported device ids") 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>
7 daysHID: core: fix OOB read of field->usage in hid_set_field()Baul Lee1-2/+3
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>
7 daysHID: magicmouse: do not keep a stale msc->input if no input is claimedJose Villaseñor Montfort1-0/+10
commit 0af3b89705688af01aa06025b84fa7a1e06ba6cc upstream. magicmouse_input_mapping() caches the first hid_input's input_dev in msc->input while the report descriptor is parsed, and the rest of the driver treats a non-NULL msc->input as proof that an input device was registered. That does not hold on the hid-input error path. If hidinput_connect() fails -- for instance because input_register_device() returns an error -- it unwinds through hidinput_disconnect(), which frees every input_dev it created, including the one cached in msc->input. The failure does not abort the probe. hid_connect() only skips the claim: if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev, connect_mask & HID_CONNECT_HIDINPUT_FORCE)) hdev->claimed |= HID_CLAIMED_INPUT; and the "device has no listeners" bailout below it does not fire for this driver, which sets ->raw_event; on the USB Magic Mouse 2 / Magic Trackpad 2 paths hidraw and hiddev are claimed as well. hid_hw_start() therefore returns 0 and magicmouse_probe() continues with msc->input pointing at freed memory. Being non-NULL, it passes the "input not registered" check in probe and the NULL checks in ->raw_event and ->event, so the next input report dereferences freed memory. Clear msc->input when the HID core did not claim an input device, so the existing NULL checks cover this case as well. Fixes: f1a9a149abc8 ("HID: magicmouse: fix race between input_register() and probe()") Link: https://lore.kernel.org/linux-input/20260728185542.65F091F000E9@smtp.kernel.org/ Cc: stable@vger.kernel.org Signed-off-by: Jose Villaseñor Montfort <pepemontfort@gmail.com> Reviewed-by: Alec Hall <signshop.alec@gmail.com> Tested-by: Alec Hall <signshop.alec@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: magicmouse: re-enable multitouch after reset-resumeChristopher Kodama1-0/+19
commit 4253fe22b137c4ee68f36b707fdb1b44b191edc4 upstream. When the Apple Magic Trackpad 2 (USB) is reset across a power transition (e.g. resume from hibernation) it drops out of multitouch mode: it keeps sending report ID 0x02 on its HID_TYPE_USBMOUSE interface, but the packet shrinks from 21 to 8 bytes and the trackpad2 handler drops it (size < 12). Clicks still work but pointer motion is lost until the device is re-plugged or the driver reloaded. Re-enable multitouch from .reset_resume via the workqueue. Only .reset_resume is needed; suspend-to-idle keeps the device powered and retains multitouch. Fixes: 87a2f10395c8 ("HID: magicmouse: Apple Magic Trackpad 2 USB-C driver support") Cc: stable@vger.kernel.org Assisted-by: Claude-Code:claude-opus-4-8 Signed-off-by: Christopher Kodama <ckhordiasma@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: magicmouse: prevent unbounded recursion in magicmouse_raw_event()Jose Villaseñor Montfort1-5/+20
commit db8d634128d2ba88d79c0b601e983ebe14bb0519 upstream. magicmouse_raw_event() handles DOUBLE_REPORT_ID (0xf7) packets, which pack two touch reports into one, by splitting the packet and calling itself on each half. The only guard against runaway recursion is a "size < 1" check, which stops zero-sized calls but does not bound the recursion depth. A malicious HID device that matches this driver can send a report starting with DOUBLE_REPORT_ID and filled with the sequence [0xf7, 0x00]. Each level consumes two bytes and recurses on the remainder, so an incoming report of up to HID_MAX_BUFFER_SIZE (16 KiB) drives roughly 8000 nested calls. That easily exhausts the 16 KiB kernel stack, leading to a stack overflow: a panic with CONFIG_VMAP_STACK, or memory corruption without it. A double report only ever wraps two normal reports; it is never legitimately nested. Refuse to re-enter the DOUBLE_REPORT_ID case from a recursive call so the recursion depth is bounded to two, while all valid packets keep being parsed exactly as before. Fixes: a462230e16ac ("HID: magicmouse: enable Magic Trackpad support") Link: https://lore.kernel.org/linux-input/20260706181347.700DB1F00A3F@smtp.kernel.org/ Cc: stable@vger.kernel.org Signed-off-by: Jose Villaseñor Montfort <pepemontfort@gmail.com> Reviewed-by: Alec Hall <signshop.alec@gmail.com> Tested-by: Alec Hall <signshop.alec@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysHID: magicmouse: fix battery reporting for Bluetooth Magic Trackpad USB-CAndrei Fed2-1/+21
commit a1556b48efc157fdda07b52ecc56c7bd1e1786f0 upstream. The Apple Magic Trackpad 2 (USB-C) reports a wildly wrong battery capacity over Bluetooth, for example a constant 4% for a pack that is actually at 74%. The device's battery input report (0x90) is laid out as [report-id][status][charge]. hid-input's synchronous capacity query, hidinput_query_battery_capacity(), assumes the common [report-id][capacity] layout and returns buf[1], which for this device is the status byte rather than the charge (buf[2]). magicmouse_fetch_battery(), which requests the battery report through hid_hw_request() so the reply is decoded via the report descriptor at the correct field offset, is gated to the USB models and never runs over Bluetooth. The device does not push battery reports on its own either, except a single one at connect time, which is delivered while probe holds driver_input_lock and is silently dropped. All userspace reads therefore go through the misparsing query, and the device is stuck reporting its status byte as the capacity. Enabling the fetch for Bluetooth is not sufficient on its own: user space reacts to the power_supply registration immediately, so a query is typically already in flight when the fetch reply is parsed. hidinput_get_battery_property() stores the query result and marks the battery as queried without rechecking whether a report arrived while it was waiting, clobbering the just-reported correct value with the misparsed one. Fix this by adding HID_BATTERY_QUIRK_AVOID_QUERY for the Bluetooth Magic Trackpad USB-C so the misparsing query path is never used, and by fetching the battery at the end of probe for this device. hidp has no asynchronous request() callback, so the fetch is serviced synchronously via __hid_request() while probe still holds driver_input_lock; call hid_device_io_start() first so the reply is processed instead of being discarded. Tested with a Magic Trackpad USB-C (004c:0324) over Bluetooth on 6.18.37: the reported capacity now matches the device (verified against a raw GET_REPORT of report 0x90) and updates on reconnect. Fixes: 87a2f10395c8 ("HID: magicmouse: Apple Magic Trackpad 2 USB-C driver support") Cc: stable@vger.kernel.org Signed-off-by: Andrei Fed <andfed.net@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysnvmet: pci-epf: put CQ ref on create_cq mapping failureYifei Gao1-0/+1
commit 659ae9d02cb5d72c76f74fff7441eb8fb64d8f5c upstream. nvmet_pci_epf_create_cq() calls nvmet_cq_create(), which takes a reference on the controller and installs the completion queue. If the subsequent PCI address-space mapping fails or returns a too-small partial mapping, the function jumps to err_internal / err_unmap_queue without calling nvmet_cq_put(). The matching put in nvmet_pci_epf_delete_cq() is gated on NVMET_PCI_EPF_Q_LIVE, which is only set after the mapping succeeds, so teardown never releases these references. A remote PCI host that drives Create IO CQ commands with a failing PRP1/pci_addr therefore leaks the CQ and a controller reference on each attempt. Drop the CQ reference on the mapping-failure paths. The err_internal and err_unmap_queue labels are only reachable after nvmet_cq_create() has succeeded, so this pairs the create/put correctly. Fixes: 0faa0fe6f90e ("nvmet: New NVMe PCI endpoint function target driver") Cc: stable@vger.kernel.org Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Yifei Gao <gyf161023@gmail.com> Signed-off-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysnvmet: pci-epf: fix use-after-free in nvmet_pci_epf_exec_iod_work()Shin'ichiro Kawasaki1-3/+6
commit c9e9bb757971485b4e8414b1744507af186d72c9 upstream. nvmet_pci_epf_exec_iod_work() submits an I/O command with req->execute() and then waits for the command to complete and transfers the data back to the host. This wait is not needed for commands that do not transfer data from the device to the host. To decide whether that wait is needed, it reads iod->data_len and iod->dma_dir after calling req->execute(). However, once req->execute() is called, the command may complete asynchronously on another CPU. For commands that do not require a device-to-host data transfer, nvmet_pci_epf_queue_response() calls nvmet_pci_epf_complete_iod() directly, which can free the iod before it reads iod->data_len and iod->dma_dir, resulting in the KFENCE use-after- free: BUG: KFENCE: use-after-free read in nvmet_pci_epf_exec_iod_work+0x288/0x798 [nvmet_pci_epf] Use-after-free read at 0x00000000fdfa6d03 (in kfence-#63): nvmet_pci_epf_exec_iod_work+0x288/0x798 [nvmet_pci_epf] process_one_work+0x15c/0x4f0 worker_thread+0x18c/0x30c kthread+0x130/0x140 ret_from_fork+0x10/0x20 kfence-#63: 0x00000000e3de0e71-0x00000000c938ad62, size=712, cache=kmalloc-1k allocated by task 10 on cpu 0 at 73.995480s (0.005122s ago): mempool_kmalloc+0x1c/0x28 mempool_alloc_noprof+0x40/0x9c nvmet_pci_epf_poll_sqs_work+0xd4/0x344 [nvmet_pci_epf] process_one_work+0x15c/0x4f0 worker_thread+0x18c/0x30c kthread+0x130/0x140 ret_from_fork+0x10/0x20 freed by task 131 on cpu 3 at 73.995521s (0.008385s ago): mempool_kfree+0x10/0x20 mempool_free+0x44/0x64 nvmet_pci_epf_free_iod+0x88/0x98 [nvmet_pci_epf] nvmet_pci_epf_cq_work+0xfc/0x280 [nvmet_pci_epf] process_one_work+0x15c/0x4f0 worker_thread+0x18c/0x30c kthread+0x130/0x140 ret_from_fork+0x10/0x20 Fix this by referring to iod->data_len and iod->dma_dir before calling req->execute(). The remaining iod accesses such as iod->status are only reached on the device-to-host read path. In this case, nvmet_pci_epf_queue_response() signals iod->done instead of freeing the iod, so the iod stays valid. Fixes: 0faa0fe6f90e ("nvmet: New NVMe PCI endpoint function target driver") Cc: stable@vger.kernel.org Reviewed-by: Damien Le Moal <dlemoal@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Signed-off-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysnvmet-tcp: Do not WARN on remotely-controlled oversized SGL allocationsGreg Kroah-Hartman1-2/+4
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>
7 daysnvmet-tcp: bound SGL data length before allocating command buffersIbrahim Hashimov1-0/+13
commit 4a3f00262a044e8e15064b1a6860968bf0500bf4 upstream. nvmet_tcp_map_data() reads the host-controlled 32-bit sgl->length and, for the in-capsule offset descriptor (type 0x01), checks it against port->inline_data_size before use. Any other SGL descriptor type -- including the non-inline transport SGL data-block descriptor (type (NVME_TRANSPORT_SGL_DATA_DESC << 4) | NVME_SGL_FMT_TRANSPORT_A, the type a real host uses for out-of-capsule writes) skips that check entirely and falls straight through to: cmd->req.sg = sgl_alloc(len, GFP_KERNEL, &cmd->req.sg_cnt); with len taken directly from the wire, unbounded up to 4 GiB. nvmet_req_init() only parses the command and never inspects sgl->length, and nvmet_check_transfer_len() -- the only other place transfer_len is validated -- runs later, from req->execute(), after the allocation has already happened. For a write command the target responds with an R2T and parks the command waiting for the host to send the data; if the host (or an unauthenticated peer that simply never follows up) never does, the sgl_alloc() buffer stays resident for the life of the command. NVMe/TCP has no mandatory authentication in the default configuration, so any peer able to reach the target portal and complete a Fabrics connect can drive this with a single crafted command, repeatable across queues and connections for amplification. This is unbounded kernel memory allocation triggered by a remote, effectively unauthenticated peer. Validate len against the same NVMET_TCP_MAXH2CDATA ceiling this file already uses to bound per-PDU H2C data, for every SGL descriptor type, before doing any allocation. This closes the gap for the non-inline descriptor while leaving the existing, tighter inline_data_size check in place for the in-capsule case. Runtime-verified on a v6.19 KASAN stand: with this bound in place, a crafted write command carrying an oversized non-inline SGL length is rejected before sgl_alloc() runs, where the same request previously drove an unbounded ~256 MiB kernel allocation (up to 4 GiB) that stayed resident pending an R2T the host never satisfies. Fixes: 872d26a391da ("nvmet-tcp: add NVMe over TCP target driver") Cc: stable@vger.kernel.org Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ibrahim Hashimov <security@auditcode.ai> Assisted-by: AuditCode-AI:2026.07 Signed-off-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysnvmet-fc: fix invalid free in LS IOD error pathJiang HongHui1-1/+1
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>
7 daysnvmet-auth: zero the AUTH_RECEIVE response bufferBryam Vargas1-1/+1
commit 3ddcfb013322aa37eaa7a0d344b73079c38dfa21 upstream. nvmet_execute_auth_receive() allocates the response buffer with kmalloc() sized by the host-supplied AUTH_RECEIVE allocation length, but the DH-HMAC-CHAP builders write only a fixed-size message into it. The full allocation length is then copied to the wire by nvmet_copy_to_sgl(), so a remote initiator receives the bytes past the built message -- up to nearly a page of uninitialized slab -- during the pre-authentication handshake. Allocate the buffer with kzalloc() so the unwritten tail is zeroed before it is sent; conforming responses are unaffected. Fixes: db1312dd9548 ("nvmet: implement basic In-Band Authentication") Cc: stable@vger.kernel.org Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Keith Busch <kbusch@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysdmaengine: fsl-edma: Add error handling for devm_kasprintfGriffin Kroah-Hartman1-0/+2
commit bf1af4dfdc017dfe989c0dbcf0e608dc95f1d2cb upstream. Add error handling statement to fls_edma3_irq_init() for the devm_kasprintf call. Assisted-by: gkh_clanker_2000 Cc: stable <stable@kernel.org> Cc: Frank Li <Frank.Li@nxp.com> Cc: Vinod Koul <vkoul@kernel.org> Cc: imx@lists.linux.dev Signed-off-by: Griffin Kroah-Hartman <griffin@kroah.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Frank Li <Frank.Li@nxp.com> Link: https://patch.msgid.link/2026070605-frying-fling-b9c5@gregkh Signed-off-by: Vinod Koul <vkoul@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysmailbox: mchp-ipc-sbi: Add null check for devm_kasprintf()Griffin Kroah-Hartman1-0/+2
commit b37c4d0a2fd90c0c31223acd37f763eb8953ed1a upstream. Add a check to see if devm_kasprintf() is not NULL in mchp_ipc_get_cluster_aggr_irq(), returning -ENOMEM if the function failed. Assisted-by: gkh_clanker_t1000 CC: Jassi Brar <jassisinghbrar@gmail.com> Signed-off-by: Griffin Kroah-Hartman <griffin@kroah.com> Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysipv6: fix use-after-free in ip6_finish_output2()Luxiao Xu1-0/+2
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>
7 daysipv4: reject undersized MTUs in ip_do_fragment()Yong Wang1-0/+4
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>
7 daysnfc: nci: free destination parameters when closing a connectionLinmao Li1-0/+1
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>
7 daysnfc: nci: fix uninit-value in the RF discover/activated NTF handlersSamuel Page1-2/+2
commit 8cbe06c1e699c0a165dae5093a2550e65f914818 upstream. nci_rf_discover_ntf_packet() and nci_rf_intf_activated_ntf_packet() each parse a notification into an on-stack struct (nci_rf_discover_ntf / nci_rf_intf_activated_ntf) that is not initialised. The RF technology-specific parameters are only extracted when rf_tech_specific_params_len is non-zero, so a notification that reports a zero length leaves the rf_tech_specific_params union uninitialised - and both handlers then pass it to nci_add_new_protocol(), which reads it: - discover: nci_add_new_target() -> nci_add_new_protocol(); - activated: nci_target_auto_activated() -> nci_add_new_protocol(). nci_add_new_protocol() uses nfca_poll->nfcid1_len as both a branch condition and a memcpy() length and copies nfcid1/sens_res/sel_res into ndev->targets, which is later exposed to user space via NFC_CMD_GET_TARGET. BUG: KMSAN: uninit-value in nci_add_new_protocol+0x624/0x6c0 nci_add_new_protocol+0x624/0x6c0 nci_ntf_packet+0x25b2/0x3c30 nci_rx_work+0x318/0x5d0 process_scheduled_works+0x84b/0x17a0 worker_thread+0xc10/0x11b0 kthread+0x376/0x500 Local variable ntf.i created at: nci_ntf_packet+0xbc2/0x3c30 Zero-initialise both on-stack notifications so the union reads back as zero when no technology-specific parameters are present. Fixes: 019c4fbaa790 ("NFC: Add NCI multiple targets support") Fixes: e8c0dacd9836 ("NFC: Update names and structs to NCI spec 1.0 d18") Link: https://lore.kernel.org/netdev/20260623172109.1105965-2-horms@kernel.org/ Cc: stable@vger.kernel.org Assisted-by: Bynario AI Signed-off-by: Samuel Page <sam@bynar.io> Link: https://patch.msgid.link/20260626090301.2139500-1-sam@bynar.io Signed-off-by: David Heidelberg <david@ixit.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysnfc: nci: fix out-of-bounds write in nci_target_auto_activated()Samuel Page1-0/+6
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>
7 daysnfc: nci: add data_len bound checks to activation parameter extractorsBryam Vargas1-4/+22
commit 0428fa2c22e2ba0cff766d3b80d461e149102045 upstream. nci_extract_activation_params_iso_dep() and nci_extract_activation_params_nfc_dep() read an inner length byte from the NCI RF_INTF_ACTIVATED_NTF payload and use it to memcpy() into fixed kernel buffers, but neither function receives the caller-validated activation_params_len. A crafted NCI notification with activation_params_len=1 and an inner length byte of up to 20 (NFC-A) or 50 (NFC-B) causes memcpy() to read that many bytes past the one valid byte in the activation params region -- a slab out-of-bounds read of kernel memory adjacent to the NCI skb. The sibling nci_extract_rf_params_*() family was given equivalent protection by commit 571dcbeb8e63 ("net: nfc: nci: Fix parameter validation for packet data"), but the two activation parameter extractors were not updated at that time. Add a data_len parameter to both functions, guard against an empty region before consuming the inner length byte, decrement the remaining count after consuming it, and clamp the copy length to what is actually available. Update both call sites to pass ntf.activation_params_len, which is already validated against the skb at ntf.c:801. Fixes: e8c0dacd9836 ("NFC: Update names and structs to NCI spec 1.0 d18") Cc: stable@vger.kernel.org Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me> Link: https://patch.msgid.link/20260612-b4-disp-6d52d8b0-v3-1-e26221f8826d@proton.me Signed-off-by: David Heidelberg <david@ixit.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
7 daysnfc: st21nfca: validate ATR_REQ length against the received frameDoruk Tan Ozturk1-0/+3
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>
7 daysnfc: pn533: purge fragmented skbs during cleanupXu Rao1-0/+1
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>
7 daysnfc: llcp: reject PDUs shorter than the LLCP headerDoruk Tan Ozturk1-0/+5
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>
7 daysnfc: llcp: fix OOB read and u8 offset wrap in TLV parsersMuhammad Bilal1-2/+16
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>
7 daysnfc: llcp: bound the connect_sn TLV walk to the skbDoruk Tan Ozturk1-4/+6
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>