summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
4 daysvirtio-net: Ensure that TCP packets don't overflow gso_segsAlice Mikityanska
The user can specify any gso_size in a packet crafted with an AF_PACKET PACKET_VNET_HDR socket, even smaller than TCP_MIN_GSO_SIZE = 8. At the same time, GSO_MAX_SIZE = 8 * GSO_MAX_SEGS = 8 * 65535. When the user crafts a packet with gso_size < 8, there is a risk for partial GSO to overflow the 16-bit gso_segs field when dividing the SKB length by gso_size. Adjust gso_size of TCP packets to be at least TCP_MIN_GSO_SIZE = 8. Keep gso_size of UDP GSO packets, as gso_size=1 is valid and explicitly tested at tools/testing/selftests/net/tun.c:649. Fixes: 7c6d2ecbda83 ("net: be more gentle about silly gso requests coming from user") Signed-off-by: Alice Mikityanska <alice@isovalent.com> Suggested-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260822120117.1163423-2-alice.kernel@fastmail.im Signed-off-by: Paolo Abeni <pabeni@redhat.com>
4 daysdrm/xe: Reject page faults from non-fault-mode scratch VMsArvind Yadav
Having scratch enabled does not make a VM capable of handling recoverable page faults. Allowing scratch VMs through the ASID lookup also admits dma-fence mode VMs. If such a VM faults on an already valid VMA, the handler reports success without fixing the fault, causing the GPU to retry indefinitely. Only allow fault-mode VMs through the ASID lookup. Fault-mode VMs using scratch remain supported, while faults from 3D VMs are rejected. Fixes: ad9843aac91a ("drm/xe/madvise: Implement purgeable buffer object support") Cc: Matthew Brost <matthew.brost@intel.com> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Suggested-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Arvind Yadav <arvind.yadav@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260820065445.567228-1-arvind.yadav@intel.com (cherry picked from commit bfb24a06405b652d37831f3fb66b71d33a6605de) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
4 daysdrm/xe/xe_gt_idle: Add CCS to the powergating info printBalasubramani Vivekanandan
While reading the main GT powergating info from debugfs, include both RCS and CCS engine masks. Fixes: 0914c1e45d3a1 ("drm/xe/xe_gt_idle: add debugfs entry for powergating info") Signed-off-by: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com> Link: https://patch.msgid.link/20260819073457.1812722-2-balasubramani.vivekanandan@intel.com Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> (cherry picked from commit 8899e413c5ab85443ec9bbc50cffe924c6b596de) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
4 daysdrm/xe: Do not apply WA 14025883347 to media 3503Daniele Ceraolo Spurio
The database was updated and the WA is no longer listed as applicable to media 3503, so don't enable it there. Fixes: c57db41b8d2c ("drm/xe/guc: Add Wa_14025883347 for GuC DMA failure on reset") Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: Sk Anirban <sk.anirban@intel.com> Cc: Badal Nilawar <badal.nilawar@intel.com> Cc: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Link: https://patch.msgid.link/20260818213520.283063-1-daniele.ceraolospurio@intel.com (cherry picked from commit fae59d5de5de39bc51ac2839f74970312e0c8905) Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
4 daysnetfilter: conncount: use DEBUG_NET_WARN_ON_ONCE on reaching count limitFernando Fernandez Mancera
Replace WARN_ON_ONCE with DEBUG_NET_WARN_ON_ONCE in __nf_conncount_add. The function handles count limit breaches safely by returning -EOVERFLOW, so a production backtrace is not needed. This prevents unnecessary system panics when panic_on_warn=1 is enabled in production systems. Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
4 daysnetfilter: tproxy: use DEBUG_NET_WARN_ON_ONCE for protocol fallbacksFernando Fernandez Mancera
Replace WARN_ON calls with DEBUG_NET_WARN_ON_ONCE in the default switch blocks of nf_tproxy_get_sock_v4 and v6. Unsupported transport protocols are already safely handled by returning a NULL socket pointer. This prevents unnecessary system panics when panic_on_warn=1 is enabled in production systems. Link: https://patch.msgid.link/cover.1786968834.git.zhilinz@nebusec.ai/ Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
5 daysslip: fix use-after-free in sl_sync()Aleksandr Khromov
slip_devs[] stores bare net_device pointers and takes no reference on them. sl_sync() and sl_alloc() walk that table from slip_open() under rtnl_lock(), while an entry is dropped by sl_free_netdev(), which sl_setup() installs as dev->priv_destructor. priv_destructor is called from netdev_run_todo(), which deliberately runs with the RTNL semaphore released so that it can sleep while waiting for the device refcount to drop: /* Snapshot list, allow later requests */ list_replace_init(&net_todo_list, &list); __rtnl_unlock(); ... if (dev->priv_destructor) dev->priv_destructor(dev); /* slip_devs[i] = NULL */ if (dev->needs_free_netdev) free_netdev(dev); ... /* Free network device */ kobject_put(&dev->dev.kobj); So rtnl_lock() does not serialise slip_open() against the teardown at all. sl_sync() can load slip_devs[i] while the entry is still published and dereference it after netdev_run_todo() has run the destructor and released the device: CPU0 (slip_open) CPU1 (slip_close) unregister_netdev() rtnl_unlock() netdev_run_todo() __rtnl_unlock() rtnl_lock() sl_sync() dev = slip_devs[i] priv_destructor(dev) slip_devs[i] = NULL kobject_put(&dev->dev.kobj) /* dev is freed */ sl = netdev_priv(dev) if (sl->tty || sl->leased) /* use-after-free */ BUG: KASAN: use-after-free in sl_sync drivers/net/slip/slip.c:730 [inline] BUG: KASAN: use-after-free in slip_open+0xef4/0x1210 drivers/net/slip/slip.c:806 Read of size 1 at addr ffff8880712dac71 by task syz-executor.2/6506 CPU: 2 PID: 6506 Comm: syz-executor.2 Not tainted 6.1.134-syzkaller-00260-g0c8fc3469765 #0 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014 Call Trace: sl_sync drivers/net/slip/slip.c:730 [inline] slip_open+0xef4/0x1210 drivers/net/slip/slip.c:806 tty_ldisc_open+0xa2/0x120 drivers/tty/tty_ldisc.c:433 tty_set_ldisc+0x324/0x720 drivers/tty/tty_ldisc.c:564 tiocsetd drivers/tty/tty_io.c:2428 [inline] tty_ioctl+0x5f0/0x1530 drivers/tty/tty_io.c:2712 Allocated by task 6502: alloc_netdev_mqs+0x98/0xfe0 net/core/dev.c:10719 sl_alloc drivers/net/slip/slip.c:756 [inline] slip_open+0x36d/0x1210 drivers/net/slip/slip.c:817 tty_ldisc_open+0xa2/0x120 drivers/tty/tty_ldisc.c:433 tty_set_ldisc+0x324/0x720 drivers/tty/tty_ldisc.c:564 Freed by task 6497: device_release+0xa2/0x240 drivers/base/core.c:2507 kobject_put+0x179/0x280 lib/kobject.c:729 netdev_run_todo+0x6c8/0xef0 net/core/dev.c:10509 slip_close+0x166/0x1c0 drivers/net/slip/slip.c:906 tty_ldisc_close+0x113/0x1a0 drivers/tty/tty_ldisc.c:456 tty_ldisc_kill+0x94/0x160 drivers/tty/tty_ldisc.c:614 tty_ldisc_release+0xe3/0x2b0 drivers/tty/tty_ldisc.c:782 tty_release+0xbcc/0xe70 drivers/tty/tty_io.c:1860 Commit e58c19124189 ("slip: Fix use-after-free Read in slip_open") fixed a different source of stale entries - a device left in slip_devs[] after slip_open() freed it on the registration error path - and does not address this race, which is why the report survives it. Drop the entry from ndo_uninit instead. unregister_netdevice() calls ndo_uninit under RTNL, before the device is queued to netdev_run_todo(), so an entry that sl_sync() can still see while holding RTNL belongs to a device that cannot be freed until RTNL is dropped. sl_free_netdev() stays only for the slip_open() error path, where register_netdevice() may have failed before ndo_init and ndo_uninit is then not called either. Both running for the same device is harmless: they run under the same RTNL section, so the slot cannot have been reused in between. This also removes the second symptom of the missing exclusion: a destructor running after sl_alloc() had already handed the slot out to another channel used to clear a live entry, so sl_sync() stopped at that NULL, sl_alloc() returned the same index again, and register_netdevice() failed with -EEXIST because slN was still there. Reproduced on x86_64 with several threads looping over open("/dev/ptmx") + ioctl(TIOCSETD, N_SLIP) + close(). Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Fixes: 5342b77c4123 ("slip: Clean up create and destroy") Cc: stable@vger.kernel.org Suggested-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Aleksandr Khromov <haa@amicon.ru> Link: https://patch.msgid.link/20260824100547.164773-1-haa@amicon.ru Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet: stmmac: selftests: Pass the IP proto mask in the TC selftestMaxime Chevallier
The stmmac TC filtering rules have recently gained sanity checks to make sure the passed keys and their respective masks are aligned with the HW filtering abilities. The stmmac selftests failed to pass the mask in the match data for L4 filtering tests, and are now failing consistently with -EINVAL : $ ethtool -t eth1 [...] 23. L4 DA TCP Filtering -22 24. L4 SA TCP Filtering -22 25. L4 DA UDP Filtering -22 26. L4 SA UDP Filtering -22 Let's pass the ip_proto mask in the l4 filtering tests match data. Found on imx8mp, which now have passing L4 tests : $ ethtool -t eth1 [...] 23. L4 DA TCP Filtering 0 24. L4 SA TCP Filtering 0 25. L4 DA UDP Filtering 0 26. L4 SA UDP Filtering 0 While at it, initialize the masks and keys to avoid re-using whatever was on the stack. Fixes: 5536d7c84363 ("net: stmmac: fix l3l4 filter rejecting unsupported offload requests") Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> Link: https://patch.msgid.link/20260825211748.360935-1-maxime.chevallier@bootlin.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet: wangxun: use BIT_ULL() to prevent shift overflow on 32-bit archsJiawen Wu
The macros TXGBE_INTR_MISC() and WX_INTR_Q() rely on the standard BIT() macro to generate interrupt masks based on the queue vector index. On 32-bit architectures, BIT() evaluates to a 32-bit `unsigned long`. Since the number of queue vectors can be up to 63 on txgbe devices, performing a left shift of 32 or more results in an integer overflow and undefined behavior. This causes incorrect interrupt masking and unmasking logic for both the queue and miscellaneous interrupts on 32-bit systems. Fix this by replacing BIT() with BIT_ULL() in these macros. This ensures that the bitwise shift is always performed safely on a 64-bit `unsigned long long` type, regardless of the underlying architecture. Fixes: e37546ad1f9b ("net: wangxun: revert the adjustment of the IRQ vector sequence") Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Link: https://patch.msgid.link/45F5565CE6AC4329+20260824072119.48399-1-jiawenwu@trustnetic.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daystcp: fix AO info use-after-free in tcp_ao_connect_init()Qing Ming
tcp_v4_connect() adds a SYN-SENT socket to the ehash before calling tcp_connect(). If TCP-AO is configured, tcp_connect() first verifies that a key matches the peer and the bound device's current L3 master. tcp_ao_connect_init() later resolves the L3 master again and removes keys which do not match it. The socket lock does not stabilize the bound device's VRF membership. Detaching the device from its VRF between the initial validation and the L3-master calculation in tcp_ao_connect_init() can therefore make the validation succeed while initialization observes the default L3 domain and removes the only key. The subsequent AO lookup then fails, so the no-key path clears tp->ao_info and frees it directly. The receive path can find the socket in the ehash and load tp->ao_info under RCU before acquiring the socket lock. A reader which loaded the old pointer can thus continue into tcp_inbound_ao_hash() after the direct free. The issue was found during a static audit of TCP-AO object lifetime. An unprivileged reproducer in self-created user and network namespaces raced connect() with detaching a veth from its VRF while sending TCP-AO segments. It triggered the same KASAN report on two fresh boots: BUG: KASAN: slab-use-after-free in tcp_inbound_ao_hash+0x585/0x19f0 Write of size 8 at addr ffff88800bf88128 by task tcp_ao_vrf_race/232 Call Trace: tcp_inbound_ao_hash+0x585/0x19f0 tcp_inbound_hash+0x677/0xa80 tcp_v4_rcv+0x1c3e/0x3ab0 Allocated by task 235: tcp_ao_alloc_info+0x43/0xf0 tcp_ao_add_cmd+0xdf7/0x13b0 do_tcp_setsockopt+0x168c/0x2640 Freed by task 235: kfree+0x1b8/0x550 tcp_connect+0x252/0x4f00 tcp_v4_connect+0x1114/0x1720 The bad address is 40 bytes inside the freed 128-byte object, matching the tcp_ao_info counters.key_not_found field. The two runs used 1000 attempts each, reached the no-key path 366 and 411 times, and produced one and two KASAN reports respectively. With this change, the same reproducer reached the no-key path 366 times in 1000 attempts without a KASAN report or oops. Use tcp_ao_destroy_sock() for the no-key path. It unpublishes the AO info, updates the socket memory and static-key accounting, and defers the free until after an RCU grace period. Also drop the WARN_ON_ONCE() and its stale comment. The VRF detach race makes the no-key state reachable during normal operation, so it is a handled condition rather than an impossible assertion. On panic_on_warn kernels the WARN would turn this handled race into a kernel panic. Fixes: 248411b8cb89 ("net/tcp: Wire up l3index to TCP-AO") Cc: stable@vger.kernel.org Assisted-by: Codex:gpt-5 Signed-off-by: Qing Ming <a0yami@mailbox.org> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260825072033.6921-1-a0yami@mailbox.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysselftests: net: tcp_ao: test VRF-scoped key deletionRastislav Szabo
Verify that TCP_AO_DEL_KEY can remove a TCP-AO key scoped to a VRF. Assisted-by: Codex:GPT-5 Signed-off-by: Rastislav Szabo <rastislav.szabo@isovalent.com> Reviewed-by: David Ahern <dsahern@kernel.org> Acked-by: Dmitry Safonov <dima@arista.com> Link: https://patch.msgid.link/20260822201119.272269-2-rastislav.szabo@isovalent.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet/tcp: fix TCP-AO key deletion in VRFsRastislav Szabo
TCP-AO keys with TCP_AO_KEYF_IFINDEX store the VRF L3 interface index in l3index. tcp_ao_del_cmd() validates the supplied ifindex, but does not assign it to its local l3index before matching keys. As a result, deleting a key scoped to a non-default VRF always fails with ENOENT because it is matched against l3index 0. Fixes: 248411b8cb89 ("net/tcp: Wire up l3index to TCP-AO") Cc: stable@vger.kernel.org Signed-off-by: Rastislav Szabo <rastislav.szabo@isovalent.com> Reviewed-by: David Ahern <dsahern@kernel.org> Acked-by: Dmitry Safonov <0x7f454c46@gmail.com> Link: https://patch.msgid.link/20260822201119.272269-1-rastislav.szabo@isovalent.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet: phy: air_en8811h: move LED GPIO configuration to config_initVitaliy Sochnev
The LED GPIO pins (GPIO3/4/5, mapped to LED2/LED1/LED0) are only ever configured as outputs once, in .probe(). But .config_init() restarts the MD32 MCU via en8811h_restart_mcu() on every call after the first (priv->mcu_needs_restart), and that restart resets buckpbus-mapped MCU state, including EN8811H_GPIO_OUTPUT. As a result the LED GPIOs fall back to inputs after the first event that re-triggers .config_init() (link renegotiation, ifdown/ifup, resume), and the PHY's LEDs stop reflecting link/activity state even though they worked right after probe. Move the GPIO-as-output configuration from .probe() to the end of .config_init(), so it is reapplied every time the MCU may have been restarted. Fixes: 71e79430117d ("net: phy: air_en8811h: Add the Airoha EN8811H PHY driver") Suggested-by: Mikhail Zhilkin <csharper2005@gmail.com> Signed-off-by: Vitaliy Sochnev <sochnev.v.74@gmail.com> Link: https://patch.msgid.link/20260823130638.1166453-2-sochnev.v.74@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysbnxt_en: Write doorbell when linearizing skb failsJoe Damato
When the driver is handed a burst of packets, the doorbell is deferred until the end. If the last packet has a huge number of frags, but fails to linearize, the doorbell will not be written adding latency on TX for any packets in the ring and holding their DMA mappings until the next TX. Note that the queue is not stopped, so this issue would delay pending BDs until the next TX. This issue was discovered by Sashiko and reading the code verifies that, while unlikely, it is possible. Fix this by jumping to tx_free, which replicates the same pre-existing logic but also writes the doorbell. Fixes: b91e82129400 ("bnxt_en: Linearize TX SKB if the fragments exceed the max") Cc: stable@vger.kernel.org Signed-off-by: Joe Damato <joe@dama.to> Reviewed-by: Michael Chan <michael.chan@broadcom.com> Reviewed-by: Andy Gospodarek <gospo@broadcom.com> Link: https://patch.msgid.link/20260826000234.2031564-1-joe@dama.to Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet/smc: release the internal TCP sock on IPPROTO_SMC socket creation failureYifei Chu
IPPROTO_SMC sockets create an internal TCP sock ("clcsock") from the proto->init hook. When socket creation fails after proto->init has run - e.g. a cgroup BPF program attached to BPF_CGROUP_INET_SOCK_CREATE denies the socket - sk_common_release() only invokes sk_prot->destroy if it is set, but neither smc_inet_prot nor smc_inet6_prot defines it, and smc_destruct() returns early unless sk_state is SMC_CLOSED. As a result, every failing socket(AF_INET, SOCK_STREAM, IPPROTO_SMC) call leaks one tcp_sock, so an unprivileged task able to attach a deny-all BPF_CGROUP_INET_SOCK_CREATE program to its own cgroup can grow kernel memory unboundedly. Add a .destroy hook to both protos that releases the clcsock via smc_clcsock_release(). smc_sk_init() hashes the sock into the smc hashinfo before the clcsock is created, and smc_diag dumps walk that hash dereferencing smc->clcsock without taking clcsock_release_lock, while sk_common_release() calls .destroy before .unhash. Unhash the sock before releasing the clcsock, as __smc_release() does, so a concurrent dump cannot observe the release; the second unhash in sk_common_release() is a no-op. Fixes: d25a92ccae6b ("net/smc: Introduce IPPROTO_SMC") Reported-by: Abaci <abaci@linux.alibaba.com> Assisted-by: abaci:qwen3.8-max Signed-off-by: Yifei Chu <Chuyf26@linux.alibaba.com> Reviewed-by: Dust Li <dust.li@linux.alibaba.com> Link: https://patch.msgid.link/178753843966.342810.566471390946765094@linux.alibaba.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet: fix spurious TX timeout after dev_activate()Breno Leitao
While debugging another issue today, I found out that my TX queue is reported as stopped for 4294907392 ms (49.7 days), on a machine that had been up for four minutes. bnxt_en 0002:01:00.0 eth0: NETDEV WATCHDOG: CPU: 28: transmit queue 23 timed out 4294907392 ms 4294907392 is not an elapsed time. It is the value of jiffies at that moment: INITIAL_JIFFIES is 4294667296, which leaves jiffies 59 seconds short of wrapping. dev_activate() runs transition_one_qdisc() over every TX queue, which resets trans_start to 0, and then stamps only queue 0 through netif_trans_update(). Stamp jiffies instead. A queue stopped across dev_activate() now gets a full watchdog_timeo of grace, and is still reported if it is stopped that long. Fixes: 9b36627acecd ("net: remove dev->trans_start") Cc: stable@vger.kernel.org Signed-off-by: Breno Leitao <leitao@debian.org> Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de> Reviewed-by: Jason Xing <kerneljasonxing@gmail.com> Link: https://patch.msgid.link/20260825-trans_start-v2-1-286b4d6d70cb@debian.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysnet: ethernet: sun4i-emac: Fix IRQ error handlingbui duc phuc
irq_of_parse_and_map() returns 0 when parsing or mapping an IRQ fails. The current code checks for -ENXIO and therefore does not detect the failure. Check for a zero return value and convert it to -ENXIO. Fixes: 492205050d77 ("net: Add EMAC ethernet driver found on Allwinner A10 SoC's") Signed-off-by: bui duc phuc <phucduc.bui@gmail.com> Reviewed-by: Andre Przywara <andre.przywara@arm.com> Link: https://patch.msgid.link/20260824100901.31675-1-phucduc.bui@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
5 daysf2fs: support resizable tail section and unify pinned allocationDaeho Jeong
Currently, zoned block devices restrict pinned file allocations to conventional zones at the beginning of the storage (before first_seq_zone_segno), triggering range GC when conventional space is exhausted. On regular block devices, when preparing for future online filesystem resizing (e.g. partition shrinking), pinned files must not be allocated in the tail area that will be truncated, as pinned files cannot be relocated by GC. Specifying the resizable tail area size (in sections) allows uniform mount configuration across devices of different storage capacities. To support this, introduce a unified `pinned_area_max_secno` boundary abstraction in `f2fs_sb_info`: 1. Add `-o resizable_tail_secno=%u` mount option to specify the number of sections at the tail of the filesystem reserved for resizing. 2. In `f2fs_fill_super()`, initialize `sbi->pinned_area_max_secno` as: min(MAIN_SECS(sbi) - resizable_tail_sec, zoned_max_sec). 3. In `get_new_segment()`, restrict segment allocation for pinned files (`pinning == true`) to `0 .. sbi->pinned_area_max_secno - 1`. If no free section is available in the pinned area, return -EAGAIN. 4. In `f2fs_allocate_pinning_section()`, unify the range GC trigger to run `f2fs_gc_range()` up to `sbi->pinned_area_max_secno` whenever `sbi->pinned_area_max_secno < MAIN_SECS(sbi)` and allocation returns -EAGAIN. 5. Expose `/sys/fs/f2fs/<dev>/pinned_area_max_secno` as a read-only sysfs node. Signed-off-by: Daeho Jeong <daehojeong@google.com> Signed-off-by: Sunmin Jeong <s_min.jeong@samsung.com> Reviewed-by: Wenjie Qi <qiwenjie@xiaomi.com> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
5 daysMerge tag 'hyperv-next-signed-20260826' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux Pull hyperv updates from Wei Liu: - Decrypt netvsc buffer on contiguous direct-map addresses (Kameron Carr) - Drop WS2012/2012R2 & Win8/8.1 Hyper-V support (Michael Kelley) - Use more meaningful errnos for hypercall status code (Hardik Garg) - Fix lost interrupts on CPU hot-unplug for Hyper-V PCI/MSI (Naman Jain) - Reserve more MSHV vectors for Linux root partition (Wei Liu) * tag 'hyperv-next-signed-20260826' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: clocksource: hyper-v: Remove support for stimer interrupts in message mode scsi: storvsc: Remove support for storvsc protocol of old Hyper-V hosts hv_netvsc: Remove GPADL teardown special case for old Hyper-V hosts hv_sock: Remove check for old Hyper-V hosts Drivers: hv: Remove support for WS2012/2012R2 & Win8/8.1 version of Hyper-V hv_netvsc: Allocate send/receive buffers using vmbus_alloc_buffer() Drivers: hv: vmbus: Add vmbus_alloc_buffer()/vmbus_free_buffer() for CoCo VMs Drivers: hv: vmbus: add vmbus_establish_gpadl_caller_decrypted() Drivers: hv: vmbus: Skip VMBus module cleanup for non-nested root partition x86/hyperv: reserve more vectors PCI: hv: Set irq_retrigger callback for the Hyper-V PCI MSI irqchip Drivers: hv: Use meaningful errnos for hypercall status codes
5 daysASoC: amd: acp-config: change quirks to cover all ASUS FA401EA variantsShengyu Qu
Existing quirk doesn't cover all known existing FA401EA devices, so use "FA401EA" to cover all of them. Link: https://bugzilla.kernel.org/show_bug.cgi?id=221310#c49 Fixes: 27d090f3ccd4 ("ASoC: amd: acp: add ACP70 DMI override for new ASUS TUF platforms") Signed-off-by: Shengyu Qu <wiagn@4d2.org> Link: https://patch.msgid.link/20260826172050.15686-1-wiagn@4d2.org Signed-off-by: Mark Brown <broonie@kernel.org>
5 daysMerge tag 'nfs-for-7.3-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfsLinus Torvalds
Pull NFS client updates from Trond Myklebust: "Highlights include: Stable fixes: - Use-after-free fixes for the sunrpc client code - Delegation hash table leak - NULL dereference on lockowner allocation failure - Fix a handshake completion race in the TLS code - Fix an error sign checking issue when deciding whether the pNFS layout is still in use, or can be returned - Fix a layout segment leak in pnfs_layout_process() Other bugfixes: - Fix a missing NULL check in the rpcbind client - annotate shared socket callbacks with READ_ONCE/WRITE_ONCE - nfs_inode_set_delegation() error paths should return the delegation - Use clear_and_wake_up_bit() in nfs_clear_invalid_mapping() and the pNFS code. - Fix the nfs4_alloc_client() error paths to free the IDR allocation - fix folio dereference before NULL check in nfs_inode_remove_request() - Fix delayed delegation return - Fix another state manager race with umount - Fix device leaks on parse failure - Avoid cancelling in-flight I/O during a layout recall if the server doesn't require it - flexfiles: report cancelled I/O as a layout error - flexfiles: fix NULL dereference for NFSv4.0 data servers - Fix incorrect argument passed to nfs4_delete_lease() - Fix several symlink issues resulting from nfs_atomic_open_v23() - Fix an uninitialised variable issue in the NFSv4.1 callback code - fix LAYOUTSTATS send buffer exhaustion Features and cleanups: - NFSv4.2: Allow the server to specify that file data may not be cached - localio: optimise I/O submission when when not doing memory reclaim - localio: Remove duplicate wait code in nfs_local_commit - flexfiles: support loosely coupled NFSv4.x data servers - pNFS: key the data server cache on the NFS version" * tag 'nfs-for-7.3-1' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: (33 commits) NFSv4.1: fix layout segment leak on the pnfs_layout_process() forget path NFSv4/pnfs: key the data server cache on the NFS version NFSv4.2: fix LAYOUTSTATS send buffer exhaustion pNFS: Fix EBUSY check in pnfs_layout_need_return NFSv4.1: zero referring call lists before decoding nfs: fix ENXIO on O_CREAT open of existing symlink over NFSv3 SUNRPC: wait for in-flight client TLS handshake callback NFSv4: Fix incorrect argument passed to nfs4_delete_lease() in nfs4_add_lease() lockd: fix NULL dereference on lockowner allocation failure NFS: fix delegation_hash_table leak when nfs4_server_common_setup() fails NFSv4/flexfiles: support loosely coupled data servers NFSv4/flexfiles: fix NULL dereference for NFSv4.0 data servers NFSv4: pin the superblock for active state owners sunrpc: fix use-after-free in __rpc_clnt_handle_event and __rpc_clnt_remove_pipedir NFS/localio: issue commit inline when not in a memory-reclaim context NFS/localio: remove dead FLUSH_SYNC handling from nfs_local_commit NFS/localio: issue IO inline when not in a memory-reclaim context NFS: Fix delayed delegation return list handling NFS: Verify symlink inode before caching target NFS: fix folio dereference before NULL check in nfs_inode_remove_request() ...
5 daysMerge tag 'trace-rv-v7.3-2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace Pull runtime verification fix from Steven Rostedt: - Use .old instead of .bak for rvgen kunit backup files The rvgen kunit command generates .bak backup files and these are checked in for selftests as "golden" files for make check. But 'make distclean' removes such files, leaving the tree dirty. Switch to .old to preserve a clean tree after make disclean. * tag 'trace-rv-v7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: verification/rvgen: Use .old instead of .bak for kunit backup files
5 daysMerge tag 'thermal-7.3-rc1-2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull more thermal control updates from Rafael Wysocki: "This mostly consists of assorted updates of thermal drivers, including new hardware support (Airoha AN7583, Qualcomm Master BandGap thermal monitor, QCom PMIC5 Gen3 ADC), but it also includes two reverts of recent cosmetic thermal core updates that went against driver core plans to eliminate class_create(): - Fix missing bitfield include headers in Armada and QCom SPM BMG drivers (Daniel Lezcano) - Fix missed file when manually applying a change after a conflict resolution for the QCom SPMI ADC TM5 Gen3 (Daniel Lezcano) - Move thermal_zone_device_enable() to the right place in order to prevent calling it if the thermal zone registration failed (Dan Carpenter) - Improve bitfield manipulations on Armada (Bryan B. Lima) - Remove unneeded 'fast_io' on Sun8i and Armada (Wolfram Sang) - Fix wrong boundary when clamping the low values in the set_trips() callback and fix wrong mask when setting the temperature interval on Airoha (Christian Marangi) - Make use of the regmap API to support Airoha AN7583 (Christian Marangi) - Fix adc_tm5_get_temp() return check value on the QCom SPMI ADC sensor (Rakesh Kota) - Fix unbalanced clock enablement when the resume fails on the iMX driver (Can Peng) - Add Qualcomm Master BandGap thermal monitor support (Satya Priya Kakitapalli) - Add Maili Temperature bindings compatible (Haritha S K) - Add a devm action to clean hardware interrupts, sampling, and control registers on Spacemit K1 (Pei Xiao) - Fix trivial typo in a thermal OF code comment (Marek Vasut) - Remove unnecessary print on Qcom SPMI ADC driver when a call to devm_request_threaded_irq() fails as this one already prints a message (Jishnu Prakash) - Add support for QCom PMIC5 Gen3 ADC by using auxiliary driver and shared interrupt with the IIO driver (Jishnu Prakash) - Make resets optional on MT8196 and add the corresponding property in the DT bindings (AngeloGioacchino Del Regno) - Fix clock staying enabled on failing resume operation on Qoriq (Can Peng) - Fix wrong closing brace position in thermal library header (Andreas Haufler) - Fix low and high trip point validation by moving the check after the clamp on the spacemit driver (surendra) - Remove redundant error messages on IRQ request failure (Pan Chuang) - Add IIO_CONSUMER namespace import to the qcom-spmi-mbg-tm thermal driver to avoid modpost warnings that would appear after merging the iio tree against the thermal updates (Nathan Chancellor) - Revert two recent cosmetic updates of the thermal core conflicting with driver core plans to eliminate class_create() (Rafael Wysocki)" * tag 'thermal-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (32 commits) thermal/drivers/qcom-spmi-mbg-tm: Add module namespace import for IIO_CONSUMER Revert "thermal/core: Allocate the thermal class dynamically" Revert "thermal/core: Use the thermal class pointer as init guard" thermal/drivers/armada: Fix missing bitfields include thermal/drivers/qcom/spm mbg tm: Fix missing bitfield header thermal/drivers/qcom: Fix missing spmi adc tm5 gen3 file thermal/drivers: Remove redundant error messages on IRQ request failure thermal/drivers/spacemit: Validate clamped trip thresholds tools/lib/thermal: Fix misplaced extern "C" closing brace thermal/drivers/qoriq: Disable clock on resume failure thermal/drivers/mediatek/lvts_thermal: Make reset optional for MT8196 dt-bindings: thermal: mediatek: Make resets optional for MT8196 thermal/drivers/qcom: add support for PMIC5 Gen3 ADC thermal monitoring iio: adc: qcom-spmi-adc5-gen3: Share SDAM0 IRQ with ADC_TM auxiliary driver iio: adc: qcom-spmi-adc5-gen3: Remove an unnecessary print thermal/of: Fix trivial enabled typo thermal/drivers/spacemit/k1: Add shutdown action and reorder registration order dt-bindings: thermal: qcom-tsens: Document the Maili Temperature Sensor thermal/drivers/qcom: Add support for Qualcomm MBG thermal monitoring dt-bindings: thermal: Add Qualcomm MBG thermal monitor support ...
5 daysMerge tag 'pm-7.3-rc1-2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull more power management updates from Rafael Wysocki: "These fix two issues in the intel_rapl power capping driver, fix a potential issue in the schedutil cpufreq governor on 32-bit systems, fix a runtime PM issue related to failing system suspend, and update the intel_pstate cpufreq driver: - Fix a kernel panic during PMU unbind in the intel_rapl power capping driver and sign-extend the PMU delta on counter wraparound in it to avoid misreporting energy (Sumeet Pawnikar and Yifan Li) - Unblock runtime PM when device prepare fails that was not done by mistake (Shibo Zhu) - Fix possible rate limit overflow on 32-bit systems in the schedutil cpufreq governor (Hui Su) - Consolidate HWP P-states initialization in the intel_pstate cpufreq driver and make that driver avoid using the DESIRED_PERF HWP hint when the Dynamic Efficiency Control (DEC) is enabled in the processor to avoid inconsistent behavior (Rafael Wysocki)" * tag 'pm-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: powercap: intel_rapl: Fix kernel panic during PMU unbind PM: sleep: Unblock runtime PM when device prepare fails powercap: intel_rapl: Sign-extend the PMU delta on counter wraparound cpufreq: intel_pstate: Avoid using DESIRED_PERF when DEC is enabled cpufreq: intel_pstate: Consolidate HWP P-states initialization cpufreq: schedutil: Fix rate limit overflow
5 daysMerge tag 'acpi-7.3-rc1-2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull more ACPI support updates from Rafael Wysocki: "These update documentation to reflect recent changes in the upstream ACPICA project, fix issues in the core ACPI device enumeration code (one of which has been introduced recently), improve the primary "physical" device lookup for ACPI device objects in that code, and update ACPI device drivers: - Update MAINTAINERS, CREDITS and ACPI subsystem documentation to reflect recent changes in the upstream ACPICA project (Rafael Wysocki) - Prevent the core ACPI enumeration code from combining device resources that overlap completely in order to avoid resource conflicts during platform device registration because there are drivers that expect such resources to be present (Rafael Wysocki) - Defer device power initialization during ACPI-based device enumeration to the point when the given device is known to be present and functional and all of its dependencies have been met (Peixin Xie) - Fix bus ID cleanup on device_add() failures during ACPI device object registration (Hongyan Xu) - Introduce a new helper function for looking up the primary "physical" device for a given ACPI device object and update the core ACPI device enumeration code to use that function (Rafael Wysocki) - Protect all battery properties with a separated mutex in the ACPI battery driver to prevent race conditions from occurring and avoid evaluating the _BST ACPI control method multiple times in parallel for the same battery device (Rong Zhang) - Add DMI quirk for the Razer Blade Pro 17 early 2020 lid switch to the ACPI button driver (Robin Everaars) - Convert fixed clock rates in the ACPI driver for AMD SoCs (APD) to use HZ_PER_MHZ and add a clock frequency for the HJMC01 I2C controller to it (Hongnan Li and Xiangyang Yu) - Fix a stack buffer overflow in query_capability() in the ACPI platform firmware runtime update driver (Anirudh Prasad)" * tag 'acpi-7.3-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPI: button: Add DMI quirk for Razer Blade Pro 17 early 2020 lid switch ACPI: scan: Do not combine resources that overlap completely ACPI: Update upstream ACPICA repository URL in documentation ACPI: Update MAINTAINERS entry for ACPICA ACPI: Add Bob Moore to CREDITS ACPI: pfr_update: fix stack buffer overflow in query_capability() ACPI: scan: Defer device power initialization ACPI: APD: Add clock frequency for HJMC01 I2C controller ACPI: APD: Convert fixed clock rates to use HZ_PER_MHZ ACPI: scan: Use acpi_bus_get_primary_device() ACPI: platform: Use acpi_bus_get_primary_device() ACPI: bus: Introduce acpi_bus_get_primary_device() ACPI: scan: fix bus ID cleanup on device_add() failures ACPI: battery: Protect all properties with a separated mutex
5 dayssamples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-multi-modifyHaotian Zhang
ftrace_direct_multi_init() assigns kthread_run()'s return value to simple_tsk without an IS_ERR() check. When kthread_run() fails it returns ERR_PTR(-ENOMEM), but init still returns 0, so the module loads with simple_tsk holding an error pointer. On unload, ftrace_direct_multi_exit() then passes that ERR_PTR to kthread_stop(), leading to a null-pointer-dereference. Check the return value of kthread_run() with IS_ERR(); on failure, unregister the ftrace direct call and propagate the error code. Link: https://patch.msgid.link/20260826015050.10772-1-vulab@iscas.ac.cn Fixes: e1067a07cfbc ("ftrace/samples: Add module to test multi direct modify interface") Suggested-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
5 dayssamples/ftrace: Fix kthread_stop() on ERR_PTR in ftrace-direct-modifyHaotian Zhang
ftrace_direct_init() assigns kthread_run()'s return value to simple_tsk without an IS_ERR() check. When kthread_run() fails it returns ERR_PTR(-ENOMEM), but init still returns 0, so the module loads with simple_tsk holding an error pointer. On unload, ftrace_direct_exit() then passes that ERR_PTR to kthread_stop(), leading to a null-pointer-dereference. Check the return value of kthread_run() with IS_ERR(); on failure, unregister the ftrace direct call and propagate the error code. Link: https://patch.msgid.link/20260826015034.10755-1-vulab@iscas.ac.cn Fixes: ae0cc3b7e7f5 ("ftrace/samples: Add a sample module that implements modify_ftrace_direct()") Suggested-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
5 daysMerge tag 'clk-for-linus' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux Pull clk updates from Stephen Boyd: "Mostly the usual clk driver updates and new SoC additions plus non-critical data fixes for things that weren't used yet. One thing that's new here in the core is SSC spread spectrum support (SSC) in the clk provider API. The idea is that DT authors will configure SSC for certain clks and they'll be configured at clk provider registration time or when a consumer device is probed, similar to how we handle assigned clk rates or parents. On the clk driver side we have Qualcomm adding almost half the diff because they add support for 4 different SoCs and then a long tail of other SoCs like Mediatek, Renesas, Rockchip, SpaceMiT, etc. add more SoC support this time around. Luckily it's mostly clk data for these new SoCs because the actual clk_ops are already there. Beyond the new drivers we get all the little fixups for more compilation coverage or usage of more modern APIs. That all looks normal. Finally, I kinda buried the lede, I'm bringing on Brian and Jerome to help out with maintaining the clk subsystem. The current working model is already semi-distributed in that silicon vendors typically take care of their drivers and send me pull requests but I'm becoming a bottleneck for new drivers and core framework review because this has become a 100% volunteer effort on my part. Mike is stepping down after all these years (thanks Mike!) and that jump started the conversation around finding co-maintainers. Brian and Jerome have graciously offered to help me with the work load, meaning in the future they'll be sending pull requests and committing directly to the clk.git tree. They've both been around on the list for a while, I've met them both in person, and they've been making changes to the core clk framework along with helping review patches so I'm pretty confident this will work well. Core: - devm_clk_bulk_get_enable() consumer API - devm_clk_hw_register_composite_pdata() provider API - Spread Spectrum Clock (SSC) support via DT bindings and provider APIs - Divider clk rounding improved (and tested) New Drivers: - Cix Sky1 audio subsystem (AUDSS) - UltraRISC DP1000 - MediaTek MT8173 MFG_TOP - Si549 - Aspeed AST2700 PECI - Airoha EN7523 PCIe - Rockchip RV1106 - Mobileye EyeQ7H - Qualcomm Maili GCC, TCSR, RPMh, and video clks - Qualcomm Shikra GCC, RPM, GPU, display, and audio clks - Qualcomm Nord display and graphics clks - Qualcomm Glymur camera and EVA clks - Qualcomm Hawi video clks - Amlogic A9 AO and peripheral clks - Renesas R-Car X5H (R8A78000) CPG" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (269 commits) clk: microchip: mpfs: fix regmap_update_bits() mask/val order clk: visconti: Make sure clk_init_data is fully initialized clk: ti: Make sure clk_init_data is fully initialized MAINTAINERS: Add Brian Masney and Jerome Brunet as co-maintainers for clk subsystem Drop Michael Turquette's clk maintainer entry clk: ti: composite: resolve parent clocks by DT index, not by name clk: ti: mux: resolve parent clocks by DT index, not by name clk: devres: fix cleanup in devm_clk_get_optional_enabled_with_rate() dt-bindings: clock: ti,keystone-gate: Convert to DT schema dt-bindings: clock: ti: Convert APLL clock to DT schema clk: zynq: pll: Fix kernel-doc after determine_rate() conversion dt-bindings: clock: ti,clockdomain: Convert to DT schema dt-bindings: clock: Correct white-space style clk: samsung: Don't include <linux/mod_devicetable.h> clk: at91: Read "reg" with helper clk: renesas: Add R-Car X5H CPG driver clk: rockchip: rk3576: fix source muxes for SPI0..SPI4 clk: rockchip: Add clock controller for the RV1106 dt-bindings: clock: rockchip: Add RV1106 CRU support dt-bindings: clock: Document Renesas R-Car X5H Clock Pulse Generator ...
5 daysMerge tag 'apparmor-pr-2026-08-26' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor Pull AppArmor updates from John Johansen: "The biggest functional change is Jann Horn's fix for how aparmor is doing stale cred updates after a policy replacement. apparmor: fix cred UAF caused by begin_current_label_crit_section() It moves the update to be done during task_work at the end of the syscall. One major feature is allowing policy to be compressed in userspace instead of after the fact (in kernel) if we need to hold onto it for CRIU/introspection. The other major change is to do with network mediation. It is a lot of code churn but does not do any functional changes to mediation. It moves the code around, and refactors it to use newer patterns for consistency, and in preparation for some improvements in mediation in a future patchset. Features: - support loading compressed policies - add audit mode to provide a mechanism to silence complain messages - refactor network mediation to use new patterns, and prepare to for extended inet mediation (no functional change) Cleanups: - switch website link to https - make include headers self-contained, and fix circular include - constify aa_label, aa_dfa, aa_profile, and aa_perms paraneters - mark static tables and structs as read only - drop use of _confined variant for iteration - refactory mount to use check_perms - refactor network mediation code to be together - refactor xattr attachment, to take the file path - optimize current_label_crit_section() - leverage audit_log_n_untrustedstring() when possible Bug Fixes: - initialized policy lists heads before fail path - fix deadlock in complain-mode change_hat - auditing of mount binary data - fix error debug output in fn_label_build - fix race condition in label replacement - fix unconfined user namespace restriction forced stack - fix error handling for copy_from_user in policy_update - fix out-of-bounds write when null terminating a label vec - fix integer overflow in verify_tags() bounds check - fix cred UAF caused by begin_current_label_crit_section() - use SEND_SIG_NOINFO instead of NULL in aa_audit()" * tag 'apparmor-pr-2026-08-26' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor: (40 commits) apparmor: policy_int make sure list heads are initialized before fail path apparmor: fix deadlock in complain-mode change_hat apparmor: constify aa_label parameters on read-only query helpers apparmor: constify aa_dfa parameters on read-only compute paths apparmor: constify aa_profile parameters on read-only compute paths apparmor: constify aa_perms parameters that are read-only apparmor: drop use of _confined variant for iteration apparmor: refactory mount to use check_perms apparmor: fix auditing of mount binary data apparmor: add audit mode to provide a mechanism to silence complain messages apparmor: mark static tables and structs as read only apparmor: fix error debug output in fn_label_build apparmor: make table entry count last enum for static tables apparmor: fix race condition in label replacement apparmor: refactor xattr attachment, to take the file path apparmor: fix unconfined user namespace restriction forced stack apparmor: reserve mediation class for packet mediation apparmor: move sock_rcv_skb() next to inet_conn_request apparmor: move netfilter functions next to the LSM network operations apparmor: refactor network socket mediation to support compatibility ...
5 daysceph: force a cap message when a deferred revoke can't be acked immediatelyMax Kellermann
When the MDS revokes capabilities, handle_cap_grant() normally guarantees a response by setting `CHECK_CAPS_FLUSH_FORCE` (see commit 31634d7597d8 ("ceph: force sending a cap update msg back to MDS for revoke op")), so ceph_check_caps() sends a cap message even if the client would otherwise decide it has nothing to do. That guarantee is skipped whenever the revoke has to be deferred (via revoke_wait): revoking Fb while dirty data is still buffered (writeback is queued first) or revoking Fc while pages are cached (async invalidation is queued first). In those cases, the ack is left to the deferred completion (ceph_put_wrbuffer_cap_refs() after writeback, or the invalidate worker after invalidation); both of which call ceph_check_caps(ci,0) i.e. without `CHECK_CAPS_FLUSH_FORCE`. Nothing gets sent under one of the following conditions: - the inode is retaining caps because the file was used recently (file_wanted != 0; retain |= CEPH_CAP_ANY) - the revoked cap is still used because the page was re-cached (e.g. a file being re-read) - the MDS has meanwhile re-granted, so `issued==implemented` and the client sees nothing being revoked The client then never emits the cap message which the MDS is waiting for. The MDS blocks on the revoke indefinitely and logs, for minutes or hours: client.NNN isn't responding to mclientcaps(revoke), ino 0x... pending pAsxLsXsxFsxcrwb issued pAsxLsXsxFsxcrwb, sent 964.899182 seconds ago The client-side state at that point shows the full cap set still issued, nothing in the revoking/flushing sets. Thus nothing gets sent. This patch fixes it by remembering that a forced response is expected. When a revoke is deferred, set `CEPH_I_FLUSH_FORCE` on the inode. ceph_check_caps() replays it as `CHECK_CAPS_FLUSH_FORCE`, so whichever path re-checks the inode next (the writeback/invalidate completion, the delayed worker, or any other caller) is guaranteed to send a cap message to the MDS. __prep_cap() clears the flag once a message is actually built. This is the deferred-path counterpart of the existing `CHECK_CAPS_FLUSH_FORCE` handling; a normal (non-deferred) revoke still forces the response inline as before. Cc: stable@vger.kernel.org Fixes: 31634d7597d8 ("ceph: force sending a cap update msg back to MDS for revoke op") Fixes: 257e6172ab36 ("ceph: don't let check_caps skip sending responses for revoke msgs") Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 dayslibceph: reject buckets with mismatched CRUSH idsJérémy Jean
crush_decode() stores bucket data by array slot, and the mapper later derives the per-bucket workspace index from the decoded bucket id. A malformed map can therefore make one bucket reuse another bucket's workspace by encoding an id different from -1 - slot. For uniform buckets, the second replica selection expands the source bucket's permutation into that aliased workspace buffer. If the source bucket is larger than the aliased bucket, the write runs past the smaller permutation array and can escape the kvmalloc'd CRUSH workspace. KASAN reports a slab OOB write of 4 bytes in bucket_perm_choose(). Reject buckets whose encoded id does not match their array slot. Valid CRUSH maps already use the canonical negative id corresponding to the bucket slot, so this restores the invariant expected by work->work[-1 - in->id] without changing valid map behavior. Cc: stable@vger.kernel.org Fixes: 66a0e2d579db ("crush: remove mutable part of CRUSH map") Assisted-by: Codex:gpt-5 Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: reject export_targets ranks >= CEPH_MAX_MDS in mdsmap decodeJérémy Jean
MDSMap export_targets entries are monitor controlled. check_new_map() uses each entry as a bit number in a fixed stack bitmap, so a rank outside the protocol namespace can make set_bit() write past the end of the array. Reject ranks outside CEPH_MAX_MDS while decoding the map. Do not validate against possible_max_rank here because maps may legitimately reference ranks beyond a temporarily reduced max_mds. Cc: stable@vger.kernel.org Fixes: d517b3983dd3 ("ceph: reconnect to the export targets on new mdsmaps") Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: fix leaked inode reference on writeback abort at umountMatthew Brown
ceph_dirty_folio() takes a wrbuffer claim on each newly dirtied folio: it bumps i_wrbuffer_ref (taking an ihold() on the 0->1 transition) and attaches the snap_context to folio->private. That claim is released only by ceph_put_wrbuffer_cap_refs(), which for a submitted write runs from writepages_finish(). In ceph_submit_write(), if ceph_inc_osd_stopping_blocker() fails -- which happens during umount -- the request is aborted before submission: the already-collected folios are only redirtied and unlocked, so writepages_finish() never runs and the claim is leaked. redirty_page_for_writepage() -> folio_redirty_for_writepage() -> filemap_dirty_folio() sets PG_dirty directly and does not go through ->dirty_folio, so ceph_dirty_folio() is not re-entered to rebalance it. Because every subsequent writeback also fails the osd_stopping_blocker, i_wrbuffer_ref never returns to 0, the ihold() is never dropped, and the inode cannot be evicted: VFS: Busy inodes after unmount of ceph kernel BUG at fs/super.c:650! Release the orphaned claim in the abort path before redirtying, via ceph_undo_wrbuffer_claim(): detach the snap_context, drop the wrbuffer reference (letting i_wrbuffer_ref reach 0 and iput() the inode), and drop the snap_context reference -- i.e. do what writepages_finish() would have done for these never-submitted folios. Only the locked_pages entries are undone; folios still in the fbatch were never dirty-cleared by this call (folio_clear_dirty_for_io() is the ownership-transfer point, and a successful move NULLs the fbatch slot), so they hold no claim this call owns. Cc: stable@vger.kernel.org Fixes: fd7449d937e7 ("ceph: fix generic/421 test failure") Signed-off-by: Matthew Brown <matthew@bargrove.com> Reviewed-by: Xiubo Li <xiubo.li@clyso.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 dayslibceph: remove ceph_put_page_vector()Tal Zussman
ceph_put_page_vector() was paired with ceph_get_direct_page_vector(), which was removed in commit 97a385e55829 ("libceph: remove ceph_get_direct_page_vector()"). Its only remaining caller, finish_netfs_read(), uses it to put a page vector allocated with iov_iter_get_pages_alloc2(), which is confusing. Open-code the put_page() loop and kvfree() there instead. The caller passed dirty = false, so this also removes the dead dirty branch and with it a call to the deprecated set_page_dirty_lock(). Signed-off-by: Tal Zussman <tz2294@columbia.edu> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 dayslibceph: validate banner payload lengthAleksandr Nogikh
When parsing the Ceph messenger v2 protocol banner, the `payload_len` field is decoded from the banner prefix. If a client sends a banner with a `payload_len` of 0, the kernel sets up a 0-length socket read. This violates an invariant in the state machine, triggering a warning in `populate_in_iter()`: ------------[ cut here ]------------ !iov_iter_count(&con->v2.in_iter) WARNING: net/ceph/messenger_v2.c:3129 at populate_in_iter net/ceph/messenger_v2.c:3129 [inline], CPU#1: kworker/1:3/5070 WARNING: net/ceph/messenger_v2.c:3129 at ceph_con_v2_try_read+0x6634/0x6810 net/ceph/messenger_v2.c:3159, CPU#1: kworker/1:3/5070 ... Call Trace: <TASK> ceph_con_workfn+0x1f5/0x14a0 net/ceph/messenger.c:1575 process_one_work kernel/workqueue.c:3322 [inline] process_scheduled_works+0xa8e/0x14e0 kernel/workqueue.c:3405 worker_thread+0xa47/0xfb0 kernel/workqueue.c:3486 kthread+0x388/0x470 kernel/kthread.c:436 ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 </TASK> According to the msgr2 protocol specification, the banner payload is expected to contain at least two 64-bit integers (`server_feat` and `server_req_feat`). Therefore, `payload_len` must be at least 16 bytes. Fix this by adding a check in `process_banner_prefix()` to reject a `payload_len` smaller than 16 bytes. This prevents the 0-length read and correctly aborts the connection with a protocol error. Fixes: cd1a677cad99 ("libceph, ceph: implement msgr2.1 protocol (crc and secure modes)") Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot Reported-by: syzbot+87c7c2d63c44e41c77a3@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=87c7c2d63c44e41c77a3 Link: https://syzkaller.appspot.com/ai_job?id=c8ca3d63-717a-4933-89ec-f3d761b8690d Signed-off-by: Aleksandr Nogikh <nogikh@google.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: make nearfull sync writes opt-inAlex Markuze
The kernel CephFS client has historically treated a cluster or pool NEARFULL condition as a request to force successful writes through generic_write_sync(). That effectively turns otherwise buffered writes into synchronous writes and can cause a severe throughput drop as soon as a single OSD or the file data pool crosses the nearfull threshold. On modern large clusters, NEARFULL is primarily an operator health signal rather than an immediate client-side capacity failure. Operators can still have substantial usable capacity while a cluster is rebalancing, splitting PGs, or expanding onto new devices. RBD, RGW and the userspace CephFS client do not impose this extra client-side sync-write throttle, so the kernel client behavior is surprising and operationally painful. Change the default behavior so NEARFULL no longer changes normal write-sync semantics. FULL and pool FULL still fail with -ENOSPC, and explicitly synchronous writes continue to be synced by generic_write_sync(). Add a nearfull_sync mount option for deployments that want the legacy backpressure behavior. When this option is set, successful writes are promoted to IOCB_DSYNC if the cluster or file data pool is marked NEARFULL, preserving the old behavior for conservative deployments. Link: https://tracker.ceph.com/issues/74849 Signed-off-by: Alex Markuze <amarkuze@redhat.com> Reviewed-by: Xiubo Li <xiubo.li@clyso.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: do not repeat ceph_trim_dentries() if no progress possibleMax Kellermann
ceph_cap_reclaim_work() re-queues itself for as long as ceph_trim_dentries() returns -EAGAIN, which happens whenever a lease walk exhausts its `nr_to_scan` budget. This creates a busy loop that consumes CPU without making any progress when there is nothing to reclaim: with no cap pressure (`count==0`) and every scanned lease still valid, each pass runs the full scan budget down to zero and returns `-EAGAIN`, only to be queued again immediately. The dir-lease walk made this worse. When `expire_dir_lease` is `false` (i.e. we have no intention of reclaiming dir leases), __dir_lease_check() returned `TOUCH` for every valid lease. `TOUCH` moves the dentry to the tail of the list and resets `di->time` via __dentry_dir_lease_touch(), so a walk over N valid leases pointlessly rewrote the list, refreshed the timestamps (preventing them from ever aging out) and always drained `nr_to_scan`, guaranteeing the `-EAGAIN` requeue. Fix this in three steps: - Return `KEEP` instead of `TOUCH` when `expire_dir_lease` is `false`. If we are not going to reclaim the lease, leave it in place instead of churning the list and resetting its timestamp; the walk then terminates naturally (or via `STOP` at the first fresh lease). - Only return `-EAGAIN` from the first (dentry-lease) walk when something was actually freed. A full batch that frees nothing means retrying the same list immediately is futile; fall through to the dir-lease walk instead. - After both walks, bail out with success (0) when nothing was freed and there is no cap pressure (`count==0`). There is no reason to keep retrying when we are not over the cap limit and made no progress. Under real cap pressure (`count>0`) the reclaim path is unchanged and still retries via `-EAGAIN`. Without this patch, I saw 500 ceph_trim_dentries() calls per second on our web servers. This is very visible in `/proc/lock_stat` (5 minute capture): class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg &mdsc->dentry_list_lock: 126180 128218 0.04 8063.44 15986965.20 124.69 1573354 5296812 0.04 8291.28 74164526.48 14.00 ----------------------- &mdsc->dentry_list_lock 111736 [<000000007b11e319>] __ceph_dentry_dir_lease_touch+0x7c/0xa8 &mdsc->dentry_list_lock 2631 [<0000000050597999>] __dentry_leases_walk+0x64/0x2c8 &mdsc->dentry_list_lock 3878 [<00000000c0022f62>] __ceph_dentry_lease_touch+0x5c/0xa8 &mdsc->dentry_list_lock 9973 [<000000002f27cb6f>] __dentry_lease_unlist+0x50/0xa0 ----------------------- &mdsc->dentry_list_lock 123621 [<0000000050597999>] __dentry_leases_walk+0x64/0x2c8 &mdsc->dentry_list_lock 1822 [<000000007b11e319>] __ceph_dentry_dir_lease_touch+0x7c/0xa8 &mdsc->dentry_list_lock 2720 [<000000002f27cb6f>] __dentry_lease_unlist+0x50/0xa0 &mdsc->dentry_list_lock 55 [<00000000c0022f62>] __ceph_dentry_lease_touch+0x5c/0xa8 With this patch: class name con-bounces contentions waittime-min waittime-max waittime-total waittime-avg acq-bounces acquisitions holdtime-min holdtime-max holdtime-total holdtime-avg &mdsc->dentry_list_lock: 1203 1215 0.16 408.88 33082.88 27.23 4320501 7357389 0.04 500.64 1961578.00 0.27 ----------------------- &mdsc->dentry_list_lock 1029 [<000000003c9aea8a>] __ceph_dentry_dir_lease_touch+0x7c/0xa8 &mdsc->dentry_list_lock 169 [<000000002038c577>] __dentry_lease_unlist+0x50/0xa0 &mdsc->dentry_list_lock 16 [<00000000c991106d>] __ceph_dentry_lease_touch+0x5c/0xa8 &mdsc->dentry_list_lock 1 [<00000000612fe15f>] __dentry_leases_walk+0x64/0x2c8 ----------------------- &mdsc->dentry_list_lock 158 [<000000002038c577>] __dentry_lease_unlist+0x50/0xa0 &mdsc->dentry_list_lock 858 [<000000003c9aea8a>] __ceph_dentry_dir_lease_touch+0x7c/0xa8 &mdsc->dentry_list_lock 182 [<00000000612fe15f>] __dentry_leases_walk+0x64/0x2c8 &mdsc->dentry_list_lock 17 [<00000000c991106d>] __ceph_dentry_lease_touch+0x5c/0xa8 __dentry_leases_walk() is almost gone. The total wait time is reduced by a factor of 483. That will give some latency gains to ceph_readdir(). Cc: stable@vger.kernel.org Fixes: 37c4efc1ddf9 ("ceph: periodically trim stale dentries") Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: drop mdsc->mutex before decoding the MDS replyMax Kellermann
handle_reply() held `mdsc->mutex` across parse_reply_info(), i.e. across the full decode of the reply message. For large replies (a big readdir allocates and parses many dir_entries), this can take a while and blocks ceph_mdsc_submit_request() calls meanwhile. The decode does not need `mdsc->mutex`: parse_reply_info() mostly fills the request's `r_reply_info`. Create replies may also add delegated inode numbers to the session xarray, but that xarray is protected by its own lock and is not serialized by `mdsc->mutex` today. By the time we reach parse_reply_info(), all `mdsc->mutex`-protected state has already been updated under the lock (the request has either been unregistered (safe reply) or added to the session's unsafe list (unsafe reply)) and the request is pinned by the reference taken in lookup_get_request(). Drop `mdsc->mutex` before calling parse_reply_info() so reply decoding no longer blocks request submission. This only widens the existing unlocked window that already covers the heavier ceph_fill_trace() / ceph_readdir_prepopulate() processing, so no new races are introduced. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Xiubo Li <xiubo.li@clyso.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: fix UAF in check_new_map() on session freed during unlockXiubo Li
check_new_map() iterates mdsc->sessions[] and for each active session drops mdsc->mutex to perform per-session operations. The forced-close path (rank removed from map) correctly takes a reference on s via ceph_get_mds_session() before releasing mdsc->mutex, but three other paths do not: Path A (address changed): mutex_unlock → mutex_lock(&s->s_mutex) Path B (reconnect): mutex_unlock → send_mds_reconnect(mdsc, s) Path C (active transition): mutex_unlock → mutex_lock(&s->s_mutex) Without the extra reference, another thread can acquire mdsc->mutex during the unlock window, call __unregister_session() which drops the last reference on s, and free it. The original thread then accesses freed memory via s->s_mutex. Fix by adding ceph_get_mds_session(s) before each mutex_unlock and ceph_put_mds_session(s) after the corresponding mutex_lock, matching the pattern already used in the forced-close path. Race timeline (Path A): Thread A (check_new_map) Thread B (another map update holds mdsc->mutex or session teardown) -------------------------- -------------------------- s = mdsc->sessions[i] (refcount == 1, held only by sessions[] array) mutex_unlock(&mdsc->mutex) ---> acquires mdsc->mutex __unregister_session(mdsc, s) sessions[i] = NULL ceph_put_mds_session(s) refcount: 1 -> 0 kfree(s) <--- freed! mutex_lock(&s->s_mutex) UAF on freed s->s_mutex Cc: stable@vger.kernel.org Signed-off-by: Xiubo Li <xiubo.li@clyso.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlockXiubo Li
list_for_each_entry() iterates ci->i_cap_flush_list but drops i_ceph_lock to send cap messages. During the unlock window, handle_cap_flush_ack() can acquire i_ceph_lock, detach cf entries with tid <= flush_tid from the list, release i_ceph_lock, and free them via ceph_free_cap_flush() outside any lock. When the original thread reacquires i_ceph_lock and the for-loop macro advances via cf = list_next_entry(cf, i_list), it dereferences cf->i_list.next on freed memory. The race timeline: __kick_flushing_caps() handle_cap_flush_ack() ----------------------- ----------------------- holds i_ceph_lock <--- iterates to cf (tid=10) prepares FLUSH message drops i_ceph_lock <--- __send_cap() ── FLUSH(tid=10) MDS sends FLUSH_ACK(tid=10) ---> acquires i_ceph_lock cf->tid(10) <= flush_tid(10), detaches cf from i_cap_flush_list drops i_ceph_lock ceph_free_cap_flush(cf) <- frees it! acquires i_ceph_lock <--- for-loop advances: cf = list_next_entry(cf, i_list) -- UAF on freed cf->i_list.next The cf was just sent by __kick_flushing_caps itself via __send_cap(). The MDS may respond with FLUSH_ACK quickly enough that handle_cap_flush_ack() frees cf before __kick_flushing_caps can finish the iteration. Fix by converting to a manual while loop: save the next pointer under i_ceph_lock before dropping it, then use the saved pointer after reacquiring, so the potentially-freed cf is never accessed again. Cc: stable@vger.kernel.org Signed-off-by: Xiubo Li <xiubo.li@clyso.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: pass inode pointer around instead of reloading itMax Kellermann
All these functions already have a ceph_inode_info pointer, so let's use that instead of letting every function reload it from RAM (i.e. `ceph_cap.ci`). This eliminates several memory accesses. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: mark cap remove with RB_CLEAR_NODE() instead of setting ci=NULLMax Kellermann
__ceph_remove_cap() erases the ceph_cap object from the RB tree, thus it seems natural to use RB_CLEAR_NODE() / RB_EMPTY_NODE() for the removal check. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: add helper function ceph_cap_is_removed()Max Kellermann
Having it as a wrapper allows replacing the implementation, which the next patch will do. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: make __ceph_remove_cap() staticMax Kellermann
It's only used from within caps.c. Signed-off-by: Max Kellermann <max.kellermann@ionos.com> Reviewed-by: Alex Markuze <amarkuze@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: cap delegated inode count in ceph_parse_deleg_inos()Michael Bommarito
ceph_parse_deleg_inos() decodes interval sets of delegated inode numbers from an MDS create-with-delegation reply. For each set it reads a 64-bit start and a 64-bit len with ceph_decode_64_safe(), which only validates that the eight bytes are present in the message, not the value, and then loops over len while inserting entries into s_delegated_inos. len is fully attacker controlled. A malicious or compromised MDS can send one huge interval, many intervals in one reply, duplicate intervals, or repeated replies that accumulate delegated inodes on the same session. The original code bounded none of these and could spin the insert loop or grow the xarray without limit. Bound both dimensions with a single enforcement point. Track the number of delegated inodes held by each MDS session in an atomic counter and grow it only in ceph_insert_deleg_ino(), which uses atomic_add_unless() to refuse to push the count past CEPH_MAX_DELEG_INOS. Because that helper is the only place the counter grows, the per-session population can never exceed the cap, so no separate per-session pre-check is needed. The counter is decremented when async create consumes a delegated inode or when an insert fails, incremented when a delegated inode is restored, initialized with the session xarray, and reset when reconnect destroys the xarray. A per-session cap alone still lets one reply spin the insert loop on duplicate ranges without growing the counter, so also cap the aggregate interval length accepted from a single reply. Together these bound both the loop trip count per reply and the xarray population across replies. The cap is a fixed, client-chosen constant rather than a value derived from the MDS. mds_client_prealloc_inos is a userspace MDS configuration option; it is never sent to the kernel client on the wire, and a server-supplied bound could not be trusted for a defensive limit in any case. The constant is set well above that option's documented default of 1000 (a generous multiple), so legitimate refill behavior is unaffected while the CPU and xarray memory a malformed delegation stream can consume stays bounded. Impact: a malicious or compromised Ceph MDS can no longer make a client spin through an unbounded delegated-inode interval or grow one session's delegated-inode xarray without limit. Cc: stable@vger.kernel.org Fixes: d48464878708 ("ceph: decode interval_sets for delegated inos") Suggested-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: bound num_export_targets array for mds info v2/v3Michael Bommarito
ceph_mdsmap_decode() in fs/ceph/mdsmap.c reads num_export_targets from each per-mds info record and advances the decode cursor by num_export_targets * sizeof(u32) without first checking that many bytes remain. The only upper-bound check that catches a runaway cursor (*p > info_end) is gated on info_v >= 4, because info_end is left NULL for info_v 2 and 3. When the monitor sends an MDS map whose per-mds info version is 2 or 3 with an oversized num_export_targets, the cursor moves past the message front buffer and the later export-targets loop calls the unchecked ceph_decode_32() on out-of-bounds memory. A kernel client processes CEPH_MSG_MDS_MAP from its monitor session (net/ceph/mon_client.c dispatches it; fs/ceph/super.c routes it to ceph_mdsc_handle_mdsmap(), which sets end to the front buffer bound and calls ceph_mdsmap_decode()). A malicious or compromised monitor, or an on-path attacker on an unsigned/unencrypted messenger session, can therefore drive an out-of-bounds read in the client kernel; on x86_64 with KASAN it is reported as a slab-out-of-bounds read in ceph_mdsmap_decode(). The decoded values land in the internal info->export_targets[] array, so the consequence is a kernel out-of-bounds read, not an information leak to the attacker. Impact: a malicious or compromised Ceph monitor sending an MDS map with a per-mds info version of 2 or 3 and an oversized num_export_targets field triggers an out-of-bounds read in the CephFS client kernel. Add a ceph_decode_need() for the export-targets array before advancing the cursor, so the bound is enforced for every info_v >= 2, not only info_v >= 4. This mirrors the count-then-need idiom already used for m_data_pg_pools later in the same function. Compute the export-targets byte count with size_mul() and reuse that checked length when advancing the cursor, so the attacker-controlled num_export_targets multiplication fails closed on overflow rather than relying on the later kcalloc() guard. Cc: stable@vger.kernel.org Fixes: d463a43d69f4 ("ceph: CEPH_FEATURE_MDSENC support") Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: bound MDSCapAuth path and fs_name decode in handle_session()Michael Bommarito
handle_session() decodes the MDSCapAuth records carried by a CEPH_SESSION_OPEN message (msg_version >= 6). For each record the match.path and match.fs_name byte strings are read by first decoding a 32-bit length and then copying that many bytes with the bare ceph_decode_copy(). Unlike the surrounding fields, which all use the _safe decode variants, these two copies are not preceded by a ceph_decode_need() bounds check, and the enclosing MDSCapAuth and MDSCapMatch struct_len fields are skipped rather than enforced as an upper bound. A length larger than the bytes remaining in the message front makes ceph_decode_copy() read past the end of the front buffer. The message front is a dedicated allocation (ceph_msg_new2() -> kvmalloc), so the over-read runs off that object. A malicious or compromised MDS can trigger this with the first post-connect message on mount, with no client-side user interaction; under KASAN it is reported as a slab-out-of-bounds read in handle_session(). Impact: a malicious MDS can force the kernel client to read up to 4 GiB past the message front allocation during session setup, crashing the client (out-of-bounds read). Switch both copies to ceph_decode_copy_safe(), which performs the ceph_decode_need() bounds check before the copy and branches to the existing bad label, matching the rest of the decoder and the error path that frees the partially decoded cap_auths array. Cc: stable@vger.kernel.org Fixes: 1d17de9534cb ("ceph: save cap_auths in MDS client when session is opened") Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: bound xattr value length in __build_xattrs()Michael Bommarito
__build_xattrs() decodes the MDS-supplied xattr blob one attribute at a time. For each attribute it reads a 32-bit name length, advances past the name bytes, reads a 32-bit value length, records the value pointer, and advances past the value bytes. The two length fields are read with ceph_decode_32_safe(), but the value bytes themselves are advanced over with a bare "p += len" and no ceph_decode_need() check that "len" bytes remain in the blob. For every attribute except the last, the next iteration's ceph_decode_32_safe() on the following name length implicitly verifies that the previous value did not run past the blob end. The final attribute has no successor, so its decoded value length is never checked against the blob bounds. A malicious or compromised metadata server can set the last attribute's value length larger than the bytes actually present in the blob. The blob is a dedicated kvmalloc() allocation sized to the wire length (ceph_buffer_new() in ceph_fill_inode()). __set_xattr() records the oversized length in xattr->val_len verbatim, and a later getxattr(2) runs memcpy(value, xattr->val, xattr->val_len) into a user-supplied buffer, copying bytes past the end of the allocation back to user space. Impact: a malicious metadata server discloses adjacent kernel heap bytes to a local user via getxattr(2) on a CephFS file. Add the missing ceph_decode_need() so an out-of-bounds value length on the final attribute fails the decode and returns -EIO instead of being stored. Cc: stable@vger.kernel.org Fixes: 355da1eb7a1f ("ceph: inode operations") Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 daysceph: bound copied dentry name length in NFS export get_nameMichael Bommarito
ceph_get_name() copies the MDS-supplied name into the caller's NAME_MAX-sized buffer with memcpy(name, rinfo->dname, rinfo->dname_len) and then writes name[rinfo->dname_len] = 0, without checking dname_len against NAME_MAX. A malicious or buggy MDS that returns a LOOKUPNAME reply with dname_len > NAME_MAX overflows the buffer. __get_snap_name() copies rde->name / rde->name_len the same unchecked way. Impact: a malicious or compromised Ceph MDS overflows the NAME_MAX name buffer in a client's NFS-export get_name path, a slab out-of-bounds write reported by KASAN. Reachable when a CephFS mount is re-exported over NFS. Add ceph_export_copy_name(), which rejects lengths above NAME_MAX with -ENAMETOOLONG before the copy, and use it in both ceph_get_name() and __get_snap_name(). Cc: stable@vger.kernel.org Fixes: 19913b4eac4a ("ceph: add get_name() NFS export callback") Assisted-by: Claude:claude-opus-4-8 Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
5 dayslibceph: validate OSD extent maps before cursor advanceMichael Bommarito
net/ceph/osd_client.c:osd_sparse_read() validates that the sparse-read data length matches the summed extent lengths, but it does not validate that each OSD-supplied extent is monotonic and lies inside the original request range. A malformed authenticated OSD reply can advertise a far-forward nonzero extent offset with a matching data length and make the client advance the message-data cursor beyond the request buffer. This reaches the BUG_ON(!*length) assertion in ceph_msg_data_next() from the client receive path. Impact: A malicious or compromised authenticated Ceph OSD peer can crash a kernel Ceph client via a malformed sparse-read reply. Reject sparse extent maps that overflow, move backwards, overlap, or extend outside the original sparse-read request before advancing the cursor. [ idryomov: perform sparse_extent_map_valid() check a bit earlier, in CEPH_SPARSE_READ_DATA_LEN instead of CEPH_SPARSE_READ_DATA_PRE state ] Cc: stable@vger.kernel.org Fixes: f628d7999727 ("libceph: add sparse read support to OSD client") Assisted-by: Codex:gpt-5-5-xhigh Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>