Commit graph

1,485,280 commits

Author SHA1 Message Date
Linus Torvalds
7b441fe5a6 power sequencing fixes for v7.3
- with the PCIe code reworked to power the endpoint via pwrctl before it
   starts the link training, we can now remove the workaround for WLAN
   power which instead started causing an issue with endpoint enumeration
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEkeUTLeW1Rh17omX8BZ0uy/82hMMFAmrR5D4ACgkQBZ0uy/82
 hMOEaxAApBLm3IqWdD5Ll1u63o09TXi1+vhgrdu3OkDekzhuI3gGDU8zfKNNuFpf
 UNZbGcf2HNIz3mWaKMZflt9BPnA4z/ruFp7coWTL2ytpz65StOZ500BtfVv2+/bX
 bm07lojdDini1IT0gvKSy3QdW2ygvIXDe78AhWZWYybwnFN+HRoOIj8Dzg13lJAb
 B4JAckLJZT4XEs5UvxTt97gn0KRDsr91XNlF6ADVP17VKo5MloYgeUsczlidYdeg
 P3w7OWNuqdvCXD0OZBN8oggGiiFljm7OFqjvQMAOyuMQ/CYev6qWE2FWVhglTMNc
 Xnvu9aLz4yKlP6oTs1k9InPvbD5mhOYXwyckyg7+FpvQyehsSBZ2qv8JraD6gNVi
 gQiB0WG04khhvYhxG/OYNLY1vEWw1zcVSKSYmLzv3YV/geF/qkFZ1x+l0s4PoCez
 ShiFDNnn5tkxMATJn14t8lNzZkXoWZvVXaER06hjsR2MTjf1bJc6K5rerw47KG1y
 FKMvwrnc07zslnB8GksXIHMFe6GAbXzoWIUwlZzrzwZ3GXXsB6xNMaz9dnzlkPEc
 vSo8wUT6LBuV17/6fXZMr4kI2M4nI6wiiF78c+fP0jyKw33HI0s9ybRyMzCKFW6L
 n9BZ2EbOlHs/N66UCcZQZs2/4KiPAvG5+dBOIGxeYU4MOxkyVug=
 =SaiM
 -----END PGP SIGNATURE-----

Merge tag 'pwrseq-fixes-for-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull power sequencing fix from Bartosz Golaszewski:

 - with the PCIe code reworked to power the endpoint via pwrctl before
   it starts the link training, we can now remove the workaround for
   WLAN power which instead started causing an issue with endpoint
   enumeration

* tag 'pwrseq-fixes-for-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  power: sequencing: qcom-wcn: power off WLAN at probe
2026-10-16 08:17:30 -07:00
Linus Torvalds
586a28a179 gpio fixes for v7.3
- gracefully handle unsupported fwnode-only, no-device GPIO lookup for
   shared pins
 - mark the GPIO controller as sleeping in gpio-nct6694
 - fix a GPIO device reference leak in kunit tests
 - fix memory leak in error path in gpiod_set_array_value_complex()
 - fix races in GPIO controller and its associated irqchip setup in
   gpio-mxc
 - use atomic bitops where races can occur in gpio-mxc
 - fix build failure in gpio tools
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEkeUTLeW1Rh17omX8BZ0uy/82hMMFAmrR4iEACgkQBZ0uy/82
 hMNndxAAmWw+V/POtQI8MUVVpp9vvmxSbBA+E//owQRKE8+67RR42pxvVyL1KDj1
 laLUX/ZEWSe4jfLwK11hSbqona3wcGTzgzNJIpDfix70QNwY2rKaJ9xx5xAF8+LJ
 v1do7Et54FYJyhhuoeMNgLvaULpSXw4Vg9FeO6yHlLdUmkbKRSEgxlBN2UZ70Wgb
 +7xeYgZpzN9OHQ/ldIsdsFwZTn8Zc7zx1a+dxlUy6OZ/ndXBBE5FOOOBCj97qCbN
 AdDhNuIxH72l9dMgGJ9uvgVYU0ZVFl6RXYG4XB239dVsX80ewDP/XolOJM9wlxVT
 p3i/zgv4SaTn8n/oKeUojvCNcR9dXrDouL/Fo2iRSEwwv87mVWyBMVAyWmTKAo9b
 tvi3F2cZeSLYrvf0ZKGz08BbOxtxToATWxHq303PYRExFWq1h5l9n5D0XairNZrZ
 cFeqP5rAOxWkB44aQRT1xU9LCZjYDO+LYYvevwfANrDseMpeJJmue/hBFPsIfWfs
 I2gWNpKC9cG1R5H/pNsEn9JqO7VwQCuYx6QswTIDUlE4Wca11qZcz3APeriDIO67
 PAHBOSm7jwKJ9nuXp9PfLYjqGss+uT1o6pYiJfYOA8PtvZofwqkeXvU0B8G2OIFt
 KxcvHDg+soCqpaoYOBJLNAnMlvaJLg6ABHHi4SLrjUxsY1SiTAQ=
 =ZNMF
 -----END PGP SIGNATURE-----

Merge tag 'gpio-fixes-for-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

Pull gpio fixes from Bartosz Golaszewski:

 - gracefully handle unsupported fwnode-only, no-device GPIO lookup for
   shared pins

 - mark the GPIO controller as sleeping in gpio-nct6694

 - fix a GPIO device reference leak in kunit tests

 - fix memory leak in error path in gpiod_set_array_value_complex()

 - fix races in GPIO controller and its associated irqchip setup in
   gpio-mxc

 - use atomic bitops where races can occur in gpio-mxc

 - fix build failure in gpio tools

* tag 'gpio-fixes-for-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux:
  gpio: mxc: fix race between gpiochip registration and IRQ domain setup
  gpio: mxc: fix wakeup_pads bit operations
  gpio: mxc: fix both_edges bit operations
  gpio: mxc: fix race between chained IRQ handler install and probe completion
  gpiolib: fix memory leak in gpiod_set_array_value_complex() on error paths
  gpio: kunit: fix GPIO device reference leak with __free()
  gpio: shared: gracefully handle no-device lookup of shared GPIOs
  gpio: shared: fix use-after-free bug when adding shared proxies
  tools: gpio: fix building from the top level with O=
  gpio: nct6694: Mark the GPIO controller as sleeping
2026-10-16 08:14:37 -07:00
Linus Torvalds
1dbb742205 vfs-7.3-rc8.fixes
Please consider pulling these changes from the signed vfs-7.3-rc8.fixes tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCatHrlQAKCRCRxhvAZXjc
 ooBKAQCaO0P/WCAUk+nHRuqKMT5Wjpcb+RKbZEDYxMt+JobeOwEAhx4ThOT8eOwX
 D2x/HjeOJ66fkbtFP1dXJzKaySf/PAs=
 =g2mr
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.3-rc8.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs fixes from Christian Brauner:

 - Fix a range of use-after-frees during rcu pathwalk caused by non-rcu
   frees.

   Whatever ->permission(), ->d_revalidate(), ->get_link(), ->d_hash()
   and ->d_compare() read in rcu mode has to be freed after a grace
   period. umount(2) hides most of it because namespace_unlock() waits
   for one, but a chdir() out of a lazily unmounted directory or the
   close() of the last file on it drops the last reference without.

    * ext4_get_link() reads the sbi and the extent status counters for a
      symlink stored in a data block. Both are freed after a grace
      period now.

    * The unicode map of casefolded ext4, f2fs and tmpfs was freed under
      generic_ci_d_hash() and generic_ci_d_compare().

    * ntfs3 with nocase freed its sbi and mount options under its dentry
      hash and compare. A remount freed the old options right away too.

    * eventfs freed an eventfs_inode after an SRCU grace period only
      while tracefs_d_revalidate() reads it under rcu_read_lock().

    * afs and 9p are only saved by the grace period their private bdi
      gets in bdi_unregister(). They stop depending on it.

    * create_ipc_ns() leaked the mqueue mount and its superblock on a
      late failure. A long-term mount needs kern_unmount().

 - Don't let idle threads pin the initramfs.

   The idle threads of the secondary cpus are forked from PID 1 with a
   private copy of its fs_struct, aren't on the task list so
   pivot_root() never moves them and never exit. So the initramfs stayed
   pinned forever on every machine with more than one cpu, 70 to 150 MB
   in the reports. They share init_fs now like init_task does.

 - A mount that copy_tree() leaves out can't take over a lock.

   copy_tree() drops mounts of mount namespace files from the copies it
   makes for unshare(CLONE_NEWNS) and propagation without looking at
   MNT_LOCKED. So root in a user namespace could bind a child's
   /proc/<pid>/ns/mnt beneath a locked cover, let it take the lock over,
   unshare(CLONE_NEWNS) and read the file. copy_tree() refuses with
   EPERM now and the move beneath a locked mount is refused up front.

 - Revert "namei: don't reveal overmounted entries in refwalk" from the
   rc7 fixes. The bug class is bigger than that patch.

 - namei: lookup_fast_for_open() checked ->d_inode while
   traverse_mounts() checks the type in d_flags, which is set second, so
   a refwalk racing the instantiation could fail an O_CREAT open with
   ENOENT. Use d_is_negative() in both places.

 - Drop the smp_mb()s in mntput_no_expire_slowpath() and do_umount()
   that mnt_get_count()'s own barrier made redundant.

 - fsnotify: a mark added while fsnotify_destroy_marks() walks the
   connector could be missed and the connector detached, so an fdinfo
   read called igrab(NULL). New marks are refused during teardown.

 - pipe: a failed second fasync enable on an O_RDWR FIFO removed the
   existing reader entry and cleared FASYNC while the writer entry
   stayed, a use-after-free in send_sigio() later.

 - watch_queue: post_one_notification() could see nr_notes before the
   note pool behind it and dereference a NULL array. An unprivileged
   user can trigger that with a key watch. Publish nr_notes last.

 - pid_namespace: zap_pid_ns_processes() waits without bound for a
   tracer outside the namespace to reap its zombies and neither wait was
   freezable, so every suspend attempt failed.

 - exit: is_child_subreaper and has_child_subreaper shared a word with
   other bitfields written without a common lock, so racing prctl()s
   lost a bit. They are separate bools now.

 - autofs: a notification write that failed on a pipe the daemon had
   already replaced put the superblock into catatonic mode again and
   closed the replacement. Only do that for the current pipe.

 - ovl: reject a lowerdir ending with an unescaped backslash with EINVAL
   instead of a confusing ENOENT later.

 - ocfs2/dlm: take dlm_reco_state_lock when the debugfs state file walks
   the recovery participant list.

 - samples/pidfd: fix the userprogs typo that kept pidfd-metadata from
   being built.

* tag 'vfs-7.3-rc8.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (24 commits)
  Revert "namei: don't reveal overmounted entries in refwalk"
  selftests/filesystems: test that a mntns file can't take over a lock
  fs: let idle threads share init_fs
  namespace: a mount that copy_tree() leaves out can't take over a lock
  namei: test for a negative dentry the way traverse_mounts() does
  fs: pass flags to copy_fs()
  ovl: reject lowerdir ending with unescaped backslash
  fsnotify: prevent mark additions during connector teardown
  pid_namespace: make zap_pid_ns_processes() freezable
  fs: drop the smp_mb()s that mnt_get_count() made redundant
  autofs: ignore notification errors from a replaced pipe
  ntfs3: free replaced mount options after a grace period
  ntfs3: free the sbi after a grace period
  unicode: free the map after a grace period
  ipc: drop the mqueue mount with kern_unmount() on setup failure
  eventfs: free the eventfs_inode after an rcu grace period too
  9p: free the session after a grace period
  watch_queue: Fix note pool publication race in watch_queue_set_size()
  afs: free the super info after a grace period
  pipe: preserve existing fasync readers on writer setup failure
  ...
2026-10-16 07:53:16 -07:00
Darrick J. Wong
519abe8d9a MAINTAINERS: remove myself
After 14 years at Oracle and 23 years working on Linux, I've decided to
step back for a while.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-10-16 07:50:11 -07:00
Toke Høiland-Jørgensen
90201351a8 wifi: atk9k: Revert "wifi: ath9k: reject short WMI command responses"
This reverts commit 93ce8ea704.

Mehmet reported that the offending commit breaks his AR9271 USB adapter
which uses zero-length replies to commands that don't return a value.
Revert the whole thing to restore the functionality.

Cc: stable@vger.kernel.org # the offending commit is in 6.12.113
Reported-by: Mehmet Fide <mehmet.fide@gmail.com>
Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-10-16 04:46:43 -07:00
Christian Brauner
214897acc8
Revert "namei: don't reveal overmounted entries in refwalk"
This reverts commit 8189ab688f.

This bug class is bigger than can be fixed with this simple patch.
Back out of it and give us some time to fix this properly.

Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-10-16 10:50:57 +02:00
Linus Torvalds
2f2f7eeef8 soc: fixes for 7.3, part 3
A small number of last minute bug fixes came up since LPC.
 Most of these are for devicetree files:
 
  - Tegra264 needs fan descriptions to keep the system from
    overheating
 
  - A cleanup on TI DRA7 caused a regression on PCI support
    and needs a fixup
 
  - The beaglev-fire board can no longer probe the mcp3564
    sensor after a an inconsistent update in 7.1
 
  - A few fixes address compile time dtc warnings on tegra
 
 The other three patches are all addressing minor problems
 in tegra drivers and the sama5 defconfig.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmrRN+gACgkQmmx57+YA
 GNk1DBAAiYSI8eVMq5N2EllU+A8Sdi2xf/2SwGlJ9StAR8IiQJy9hp+RvyKxfESJ
 0Y00nME3eHklrDtlL8WZn3k9UmqK+yJDO+XuE2ZqIlDajWyzAWodyVRvsAT8KCNT
 UqCyDTOWVdKO7J5E1PqGBdkYofyMzn12vmdlJxZT/GTs1tE0EXDuRIqoMcAwNAFw
 TPMqhuFhpyNUTLBTyroUkQT/wkO+rGwSlgD0xVH3C+EO0FT9/RfeOiyJt/DjFJpF
 XRrQyzglVuQG4IUfLyX/vJWTYnnMDH+2urFZKr70FmLwnaowv19NAUUMfDq2SM82
 /XKYwDrV4PZrASQO8i7z6x+gyNs3J+mJccqO0DORxZ2y020SMLe6ovWyHJkvr2PQ
 +bQD8XfocAV+GpoqdX9+jlg/xRsavtg56uToMP+wMkbzc1P0/Ujuz+AyOUmoiA+p
 pMjOZX1Q+0UoKH+R5OgjoEXCnhWRsvvvpMpdDDfW3/c7KIzYtW/PumEqX2xphhHR
 RC7b6iehd9/n+t8pBA2lScLTxuNVBPLz23yEEKbH5En7dJh9Wk1Prmdcx/uOFzRk
 Iin7OFuc/vWVWGbUe+StY+HCPEOvCG8wEjNLc0eTbmyGIyC5CW8p5pJwoUznkomT
 6Sa7z9+QpF14x+upjy38TiA4LdYh5oDfkacu0wram6HF6rSIu04=
 =EhfK
 -----END PGP SIGNATURE-----

Merge tag 'soc-fixes-7.3-3' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc

Pull SoC fixes from Arnd Bergmann:
 "A small number of last minute bug fixes came up since LPC.
  Most of these are for devicetree files:

   - Tegra264 needs fan descriptions to keep the system from overheating

   - A cleanup on TI DRA7 caused a regression on PCI support and needs a
     fixup

   - The beaglev-fire board can no longer probe the mcp3564 sensor after
     a an inconsistent update in 7.1

   - A few fixes address compile time dtc warnings on tegra

  The other three patches are all addressing minor problems
  in tegra drivers and the sama5 defconfig"

* tag 'soc-fixes-7.3-3' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc:
  ARM: configs: sama5: enable current Microchip KSZ DSA symbols
  soc/tegra: pmc: Fix uninitialised clock rate
  riscv: dts: microchip: beaglev-fire: remove double definition of gpio interrupts
  ARM: dts: ti/omap: dra7: fix PCIe PHY clock divider definition
  soc/tegra: fuse: Add missing newline to APBMISC error message
  arm64: tegra: Add PCIe root ports on Tegra264
  arm64: tegra: Reorder reg and reg-names to match bindings
  arm64: tegra: Add PWM fan on Jetson AGX Thor DevKit
  arm64: tegra: Add PWM controllers on Tegra264
2026-10-15 15:10:26 -07:00
Linus Torvalds
62f482ff73 IOMMU Fixes for Linux v7.3-rc7:
Including:
 
   - AMD IOMMU:
     - Revert an interrupt remapping check removal that caused GPU
       regressions on some platforms.
 
   - Generic page tables:
     - Fix KUnit builds with distributed Clang ThinLTO by preserving
       compiler flags, preventing x86-64 code generation from arm64
       bitcode.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEr9jSbILcajRFYWYyK/BELZcBGuMFAmrRHVAACgkQK/BELZcB
 GuOjzQ/9GY563Et8jjc1CaAYjnVeBnD+s9waLfmnRgkiRUosgR46pe6+sbjLFCYv
 QvciJFblQ5nbF5+tcTDD6lNZje/LvI4H0Rmx6gdFf+mApSlTpls/Pc2adf/Quhvw
 rNAtZXxZuzPXocxPk50Q2eLcntvSuPWcyF2faUnlkY0cWbaSajjvWgG8Ak/qxIyx
 ifnQG+cv3u006Rf+YAQ/yewiyt9fbm+1t+bLtlyLZmv9gDLZ5pOWx/2mHfYeg5Gc
 EkeS4MYz/tR7RcPse3r8IHEVB55cVa+P1frx25oNlAHtl5xtjKGM7nAzugLLpGCK
 eVnXGF8h6bRYta3AfIr2BrE9u4AgV8toXK4g5Dg3evhGtOBrI7i3/YQe/DfBa9fi
 bP8HWyrT1SsFEDHBeyS9H0CmaXdYe0Try73m30OivDOP2hgNqv0uWoZUHxD8Ej4j
 Ht/JsfbpJ40uH3b2nRyHmuWXPr3bmeyiAq0m9TKqG6AZEKgcjwRPopuce9bqtjku
 IiVXmCIBAwrM9Guwhzlo/2R5E44edEPjvuoquu6hI4tjZFp1+8nmZe51FKmCMYCk
 uFsCzCJINFZ5vB1lWGDgCoVD5csnNqlwx1kxNnxBUpvJMCDOluY9h3LOTZVKJFaW
 hQEMl3639119WelxWhG8+Oc4P5DYeMWc4+mFrQ7YwYhzNCNcV+w=
 =fthU
 -----END PGP SIGNATURE-----

Merge tag 'iommu-fixes-v7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux

Pull IOMMU fixes from Joerg Roedel:
 "AMD IOMMU:

   - Revert an interrupt remapping check removal that caused GPU
     regressions on some platforms

  Generic page tables:

   - Fix KUnit builds with distributed Clang ThinLTO by preserving
     compiler flags, preventing x86-64 code generation from arm64
     bitcode"

* tag 'iommu-fixes-v7.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/iommu/linux:
  iommupt/kunit: Use if_changed_rule for the kunit
  Revert "iommu/amd: Remove redundant check in irq_remapping_select()"
2026-10-15 12:24:14 -07:00
Linus Torvalds
045958acaa This is considerably smaller than in recent history, mostly due to
reduced capacity and increased backlog. Also we actively redirected
 more stuff towards next. I'm not aware of any pending regression.
 
 Current release - regressions:
 
   - eth: move netops initialization to fix crash
 
 Previous releases - regressions:
 
   - sched: fix use-after-free in __tcf_action_put()
 
   - rds: fix uninitialized trans dereference in CM event handler
 
 Previous releases - always broken:
 
   - vsock: treat TCP_CLOSING as once-established
 
   - netlink: avoid hashing the network namespace pointer
 
   - eth: mlx5: HWS, release L2 to L3 tunnel reformats to their own pool
 
 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
 -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCgA0FiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmrQ3CYWHHBhb2xvLmFi
 ZW5pQGdtYWlsLmNvbQAKCRApJHmNzI8TpBecD/9Ktu/KinUgc3Olh9pWQcvj4yFr
 ug1HxizS9Nb4cQVtrLOjuzzhLLD75i0Tt6aKCExnCT8AdFd3oRMHFRq+T3GyAnv6
 06A6cnTHPSIohVl6hEY4YxLjKuxbtZNjsSNETk3tyJwByIPImO5uCQ1GoEtNTY4w
 I/tIYWTJT1/sFp5cbJxHuApGJx7kBpH7A+4xSBX+zDIrYjPRAYY49cTJmMpXpNg0
 EtEp8LNynuJNNp2MLcLAJ/l7jiUdVzjjxzrZFNqQM9RW3LOCYCa2tLs8M2BOYKk5
 5e33JGkBHdSJiIcjHJubcPNxfUogUzqfn6bAWHYAtkw9ZW5OwtrKiDjZR3K7P/d6
 oxGsasEP1idoKioak9O30jjeACNzCObTdBCJxibKvFFL27yECV0KPf0Al1SRdkXI
 /dNZz0223oXNuz202zk3y9yCCcbJko+LRbdnfz96JHOBz6iwj334TzTYT7bO0tyj
 VcKml3Kw9p9ESaNGJmAGKHKlR2UgeLt1p6HZrqAHDVSjkKHHXCrkQ7pIbLWIRC27
 TOiQQq/qtUBAHfSihjGnI9avPb8Qo41j0xpEo+dRFcXdzTJl290d6/B12ZR0zKG/
 1cRwtWSKzwh8HKpL4DgbY3E0LTvYq0pYaqupXXi1T7WPVaJaTr6ayQ/sNX2JVya5
 qx9zjtewnAfeTHWaLQ==
 =Trok
 -----END PGP SIGNATURE-----

Merge tag 'net-7.3-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from Paolo Abeni:
 "This is considerably smaller than in recent history, mostly due to
  reduced capacity and increased backlog. Also we actively redirected
  more stuff towards next. I'm not aware of any pending regression.

  Current release - regressions:

   - eth: move netops initialization to fix crash

  Previous releases - regressions:

   - sched: fix use-after-free in __tcf_action_put()

   - rds: fix uninitialized trans dereference in CM event handler

  Previous releases - always broken:

   - vsock: treat TCP_CLOSING as once-established

   - netlink: avoid hashing the network namespace pointer

   - eth: mlx5: HWS, release L2 to L3 tunnel reformats to their own pool"

* tag 'net-7.3-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (23 commits)
  net: stmmac: dwmac1000: clear the RGMII status interrupt
  net/sched: fix use-after-free in __tcf_action_put()
  calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()
  MAINTAINERS: add Gustavo Luiz Duarte as netconsole reviewer
  net: bcmgenet: unshare the skb before writing the control block
  microchip: lan865x: move setting of netops to fix crash
  net: ti: icssm-prueth: Move setting of netops to fix crash
  net: ethernet: aeroflex: move setting of netops to fix crash
  net: ethoc: move setting of netops to fix crash
  net: au1000: move setting of netops to fix crash
  net: mv643xx: move setting of netops to fix crash
  net: ethernet: adi: Move setting of netops to fix crash
  net: ethernet: actions: Move setting of netops to fix crash
  net: hisilicon: hip04_eth: Move setting of netops to fix crash
  net: hisilicon: hisi_femac: Move setting of netops to fix crash
  netlink: avoid hashing the network namespace pointer
  net/mlx5: HWS, fix flow meter offset within its bulk
  net/mlx5: HWS, release L2 to L3 tunnel reformats to their own pool
  netlink: reset skb headers before unicast and multicast filtering
  sctp: revalidate output stream after association connect wait
  ...
2026-10-15 08:20:20 -07:00
Linus Torvalds
9aa622dbaa Even more x86 fixes:
- Avoid a false positive panic in the #PF handler, if the kernel triggers
   a page fault within the asynchronous page fault handler before the flags
   are reset.  This can happen for example because of a perf NMI.
 
 - Always reset a vCPU's MMU pointer back to the root MMU when loading
   nested guest state fails during RSM or KVM_SET_NESTED_STATE.  Otherwise,
   KVM tries to run a non-nested guest with a nested MMU, which can result
   in a NULL pointer dereference attempting to get the nested MMU's pgd
   (EPTP or nested CR3).
 -----BEGIN PGP SIGNATURE-----
 
 iQFIBAABCgAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmrQj4kUHHBib256aW5p
 QHJlZGhhdC5jb20ACgkQv/vSX3jHroOVGQf/cWZSdm/Ct31wH7UjwZiPkRUNQFMy
 Oy8jrGwXd/h/nfVAgF25wY49gx9JopCPHWJ1EU5NPSkOLTDJ+eMNZUfoCMuhDyYS
 gbMdvAbAEILKlgBAbC1pWr1fg6kMUQTJilp54elEP9XhKCOBG+KxfYu9BEvbonoc
 SvW/lN3RhIfHKLhTaOMwAA55Ta5ypebEUhjzZZXWFduWgOJn2F2L9ur8KlcpGQDq
 fXIeZihH0gmz3n00Q2M+F6BhGnNIxalmjvJ0khHHSUuLBUqKmvAPlzAcHwEbENWT
 gVGzq5Jr8nCVey6iLoUQu2Y1Tms/t+zFyAJXFsDE0TBCswW3XAX7DG8hxg==
 =4PsA
 -----END PGP SIGNATURE-----

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fixes from Paolo Bonzini:
 "Even more x86 fixes:

   - Avoid a false positive panic in the #PF handler, if the kernel
     triggers a page fault within the asynchronous page fault handler
     before the flags are reset.

     This can happen for example because of a perf NMI.

   - Always reset a vCPU's MMU pointer back to the root MMU when loading
     nested guest state fails during RSM or KVM_SET_NESTED_STATE.

     Otherwise KVM tries to run a non-nested guest with a nested MMU,
     which can result in a NULL pointer dereference attempting to get
     the nested MMU's pgd (EPTP or nested CR3)"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
  KVM: nVMX: Reset MMU back to the root MMU if loading L2 state fails for !VM-Entry
  x86/kvm: Don't consume async #PF flags on a kernel #PF in NMI context
2026-10-15 08:12:47 -07:00
Linus Torvalds
6a66840a68 Hyper-V fixes for 7.3-rc8
-----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCgAxFiEEIbPD0id6easf0xsudhRwX5BBoF4FAmrQiJsTHHdlaS5saXVA
 a2VybmVsLm9yZwAKCRB2FHBfkEGgXp1UB/4uruLK5Zg/Sf4PguV7WgO9hrEYCTnk
 urzYhnkOB3G8w0/2p9HVVQUXX29E6oz5w5V/h5piPLXNUSLyei119qhIaZx5BbTe
 EjCbsIMaqSzI3cGojUNEp6F93wl4ztrKFHQ6nELOfJtFu07R9dr00FRjP8qvJdcn
 IPCTDotMtRseV/ALG6DCfvWxykmmxGG0odKYQKJTT80q8GEPdDDo+p5SL/4RtxtO
 h+S2VZ21VgHoU4N6qdJH/dFj0g58wwIMYgj5j2mhpiriXPBMVAQjK1kiMRM7n1xP
 JvhrKoW794vCMJBHFSTPRl2oxUwbLU1FYacshNcIa8TRm9YAnIhO+Nef
 =Vqks
 -----END PGP SIGNATURE-----

Merge tag 'hyperv-fixes-signed-20261015' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull Hyper-V fixes from Wei Liu:

 - Typo and comment fixes (Hemanth Selam, Jiangshan Yi)

 - Update maintainers list (Wei Liu, Long Li)

 - Two Hyper-V PCI driver fixes (Naman Jain, Sahil Chandna)

 - Small fixes for core Hyper-V code (Hardik Garg, Michael Kelley,
   Waiman Long)

* tag 'hyperv-fixes-signed-20261015' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  MAINTAINERS: drop KY from Hyper-V maintainers list
  PCI: hv: Warn when wait_for_response() waits indefinitely
  PCI: hv: Probe vPCI buses asynchronously
  MAINTAINERS: remove myself from the Hyper-V entries
  mshv_vtl: Check per-CPU register page before mmap
  tools/hv: fix typo "retrive" in comment
  Drivers: hv: vmbus: fix typo "substract" in comment
  Drivers: hv: Don't reset VMBus connection state on error/exit paths
  x86/hyperv: Avoid using per-cpu output page in hv_apicid_to_vp_index()
  x86/hyperv: Fix stale comments after stimer message mode removal
  Drivers: hv: Avoid infinite retry loop in init_vp_index()
2026-10-15 08:06:26 -07:00
Igor Velkov
aa07285705 net: stmmac: dwmac1000: clear the RGMII status interrupt
Since commit 2e2c878a31 ("net: stmmac: remove SGMII/RGMII/SMII
interrupt handling") nothing on the RGMII path reads GMAC_RGSMIIIS, so
RGSMIIIS stays pending behind GMAC_INT_MASK from the first link change
on. stmmac_resume() resets the MAC in stmmac_hw_setup(); the reset sets
GMAC_INT_MASK to 0 until dwmac1000_core_init() writes the mask again,
and the pending status storms the line:

  dwmac_dma_interrupt: unexpected status 04000000

A register dump at the first message on ODROID-HC4 showed it:

  core int_status 00000001 int_mask 00000000 pmt 00000000 rgsmiiis 0000000d

When the resume thread runs on the CPU that takes the MAC interrupt,
the storm starves it: a soft lockup, then a watchdog reset or a hang.

Read GMAC_RGSMIIIS in dwmac1000_irq_status() when the status is not
masked, as the driver did before 2e2c878a31; the read clears it.

Wake-on-LAN resume from s2idle with the resume thread and the MAC
interrupt on one CPU: Helios64 (dwmac-rk), 7.3-rc6, soft-locked in 3 of
3 resumes without a fix and in 0 of 10 with this patch; it ran with an
out-of-tree dwmac-rk change that keeps the GMAC powered across suspend.
ODROID-HC4 (dwmac-meson8b): 0 of 10 with this patch, 2 of 2 without a
fix on a 7.3-rc5 build. irq_rgmii_n went up by one per resume.

Fixes: 2e2c878a31 ("net: stmmac: remove SGMII/RGMII/SMII interrupt handling")
Assisted-by: LLM
Signed-off-by: Igor Velkov <iav@iav.lv>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261009201709.1917585-1-iav@iav.lv
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 14:57:52 +02:00
Peng Fan
205cccd06e gpio: mxc: fix race between gpiochip registration and IRQ domain setup
devm_gpiochip_add_data() makes the GPIO chip visible to consumers
immediately. Since the chip sets .to_irq = mxc_gpio_to_irq, which calls
irq_find_mapping(port->domain, offset), any to_irq() call between
gpiochip registration and IRQ domain creation will operate on a NULL
domain.

Fix by moving devm_gpiochip_add_data() after the IRQ domain and generic
irq chip are fully initialized, ensuring port->domain and the irq chip
handlers are ready before the chip becomes visible to consumers.

Fixes: d37a65bb46 ("gpio/mxc: Move Freescale MXC gpio driver to drivers/gpio")
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Link: https://patch.msgid.link/20261013-gpio-mxc-cleanup-v7-4-c4d769587d3e@nxp.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
2026-10-15 14:21:15 +02:00
Peng Fan
170aeff46f gpio: mxc: fix wakeup_pads bit operations
gpio_set_wake_irq() can be called concurrently for different pins on
the same port. The writer-vs-writer race is the concern: two concurrent
gpio_set_wake_irq() calls for different pins on the same port both do
a non-atomic read-modify-write on the same wakeup_pads word. The old
|= and &= compile to separate load/modify/store instructions that can
interleave, losing one CPU's update.

assign_bit() uses an atomic RMW instruction, so concurrent writers to
different bits in the same word are safe.

The reader side (for_each_set_bit in noirq_suspend, wakeup_pads > 0)
runs in noirq context where no concurrent writer can execute, so
reader atomicity is not needed.

wakeup_pads is a u32, while assign_bit() operates on unsigned long
pointers. On 64-bit platforms, this causes an 8-byte read-modify-write
on a 4-byte field, corrupting the adjacent is_pad_wakeup. So change
wakeup_pads to unsigned long and reorder to avoid wasting words.

And fix the enable/disable path unconditionally sets/clears the
wakeup_pads bit even when enable_irq_wake()/disable_irq_wake() fails.
Only update the bit on success.

Fixes: f60c9eac54 ("gpio: mxc: enable pad wakeup on i.MX8x platforms")
Assisted-by: LLM
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Link: https://patch.msgid.link/20261013-gpio-mxc-cleanup-v7-3-c4d769587d3e@nxp.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
2026-10-15 14:21:15 +02:00
Peng Fan
b7719c575d gpio: mxc: fix both_edges bit operations
gpio_set_irq_type() can be called concurrently for different pins on
the same port.  The IRQ core serializes per irq descriptor, but
different pins have different descriptors, so on SMP systems two
concurrent gpio_set_irq_type() calls for pins on the same port run
without mutual exclusion.

The read-modify-write of port->both_edges is performed outside the
port-wide scoped_guard(gpio_generic_lock_irqsave) section, so
concurrent updates for different pins can overwrite each other,
causing missed interrupts or stuck IRQ lines on dual-edge triggered
pins.

The original uniprocessor MXC SoCs were not affected; the race
became reachable on multi-core i.MX7 and i.MX8 SoCs that reuse this
driver.

Convert both_edges from u32 to unsigned long and use set_bit(),
clear_bit(), and test_bit() to make the modifications atomic.

Fixes: 910862ec09 ("mxc: emulate GPIO interrupt on both-edges")
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Link: https://patch.msgid.link/20261013-gpio-mxc-cleanup-v7-2-c4d769587d3e@nxp.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
2026-10-15 14:21:15 +02:00
Peng Fan
38d44f78f0 gpio: mxc: fix race between chained IRQ handler install and probe completion
mxc_update_irq_chained_handler() is called before the IRQ domain, the
generic IRQ chip, and the port list entry are set up. If an interrupt
arrives in that window:

 - mx3_gpio_irq_handler() calls generic_handle_domain_irq() with
   port->domain still NULL.
 - mx2_gpio_irq_handler() walks mxc_gpio_ports, but the port has not
   been added to the list yet.

Additionally, if any of the subsequent probe steps
(gpio_generic_chip_init(), devm_gpiochip_add_data(),
irq_domain_create_legacy(), or mxc_gpio_init_gc()) fail, the error
paths never unregister the chained handler, leaving a dangling handler
that points at freed memory.

Move the handler installation after all its dependencies are ready and
after list_add_tail(), so the handler is never live while the data
structures it touches are incomplete, and is never installed if probe
fails.

Fixes: 5f6d1998ad ("gpio: mxc: release the parent IRQ in runtime suspend")
Assisted-by: LLM
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Link: https://patch.msgid.link/20261013-gpio-mxc-cleanup-v7-1-c4d769587d3e@nxp.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
2026-10-15 14:21:14 +02:00
Kent Gibson
c28846ca1a gpiolib: fix memory leak in gpiod_set_array_value_complex() on error paths
A drive-by review by Sashiko reports that, after a failed call to
gpiochip_set_multiple(), gpiod_set_array_value() returns abruptly,
bypassing the freeing of possibly alloced bitmaps, potentially leaking
memory. It is an unlikely error path, but is possible.

Defer the return code check until after the bitmap_free() block.

Fixes: 9b40731275 ("gpiolib: rework the wrapper around gpio_chip::set_multiple()")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/linux-gpio/sashiko-outbox-168233@kernel.org/
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Link: https://patch.msgid.link/20261015025749.47039-1-warthog618@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
2026-10-15 14:10:38 +02:00
Bartosz Golaszewski
851bb4a429 gpio: kunit: fix GPIO device reference leak with __free()
KUnit aborts the test thread immediately using kthread_exit() so the
variable annotated with __free() never really goes out of scope and the
associated callback is not called. Schedule a kunit action instead.

Fixes: a05cfd98c5 ("gpio: kunit: add test cases for software node hogs")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20261013-gpio-kunit-plat-lookup-v3-0-3907f913e964%40oss.qualcomm.com?part=1
Link: https://patch.msgid.link/20261014-gpio-kunit-autofree-leak-fix-v1-1-5bfa7be0eb1f@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
2026-10-15 14:06:25 +02:00
Bartosz Golaszewski
cf73c3fc03 gpio: shared: gracefully handle no-device lookup of shared GPIOs
We use platform lookup tables for shared GPIOs. This mechanism needs a
struct device to work so fwnode-based lookup with no device associated
currently causes a NULL-pointer deference.

Adding this functionality will require a larger rework and it has never
worked anyway so add a check that allows the kernel to gracefully handle
this situation with an error ahead of implementing that functionality as
a new feature.

Cc: stable@vger.kernel.org
Reported-by: Abel Vesa <abelvesa@kernel.org>
Fixes: a060b8c511 ("gpiolib: implement low-level, shared GPIO support")
Link: https://patch.msgid.link/20261014-gpio-shared-fwnode-lookup-v4-2-2253ad645fd6@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
2026-10-15 14:05:28 +02:00
Bartosz Golaszewski
bd22f7e635 gpio: shared: fix use-after-free bug when adding shared proxies
The GPIO lookup table can stay alive for longer than the kobject whose
name string's address we're assigning to lookup->dev_id. Fix a potential
UAF by duplicating the string.

Cc: stable@vger.kernel.org
Fixes: a060b8c511 ("gpiolib: implement low-level, shared GPIO support")
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20261014-gpio-shared-fwnode-lookup-v4-1-2253ad645fd6@oss.qualcomm.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
2026-10-15 14:05:28 +02:00
Jérémy Jean
7b16eb9110 net/sched: fix use-after-free in __tcf_action_put()
__tcf_action_put() decrements the reference count before decrementing the
binding count. Another thread can free the action between these operations,
causing the binding-count update to access freed memory. KASAN reports it
as:

  BUG: KASAN: slab-use-after-free in __tcf_action_put+0x327/0x340
  Write of size 4 at addr ff11000000d46420 by task tc-put-pause/64

Hold the action IDR mutex across both counter updates and IDR removal,
keeping cleanup outside the lock.

Fixes: 16af606739 ("net: sched: implement reference counted action release")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20261008181348.527035-2-Jeremy.Jean@oss.cyber.gouv.fr
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 13:00:02 +02:00
Joas Antonio dos Santos
8070ed578b calipso: keep BIG TCP payload_len in calipso_skbuff_setattr()
calipso_skbuff_setattr() adjusts payload_len by the length of the
option it inserts or resizes:

	payload = ntohs(ip6_hdr->payload_len);
	ip6_hdr->payload_len = htons(payload + len_delta);

GRO can build BIG TCP packets larger than IPV6_MAXPLEN, and stores
payload_len == 0 for them; ipv6_payload_len() then falls back to
skb->len.  For such a packet forwarded to a destination mapped to
CALIPSO, the code above writes len_delta (or 65536 + len_delta when
shrinking) into payload_len, and ipv6_payload_len() no longer falls
back to skb->len.  nf_tables, conntrack and sch_cake rely on it.

The same arithmetic also wraps when a packet grows past IPV6_MAXPLEN,
and a BIG TCP packet that shrinks below IPV6_MAXPLEN should get its
real length back.

Set payload_len from the skb length with ipv6_set_payload_len(), which
stores 0 above IPV6_MAXPLEN and the real length otherwise, as
ipv6_gro_complete() does.  The network header was just reset to
skb->data, so skb->len - sizeof(*ip6_hdr) is the payload length.

Tested on one kernel (arm64, QEMU) with SELinux permissive, a minimal
mdp-generated policy (network_peer_controls=1), "netlabelctl calipso
add pass doi:16" and a NetLabel mapping of fd00:2::/64 to CALIPSO
DOI 16.  calipso_skbuff_setattr() was called through
netlbl_skbuff_setattr() from a test-only debugfs hook (not part of
this patch) adding a level-only label; payload_len after the call:

  case                         before fix   after fix   real length
  1000, unlabeled                    1016        1016          1016
  70000 GSO, payload_len 0             16           0         70016
  65530 GSO, grows past MAXPLEN        10           0         65546
  65540 GSO with a 24 byte hop
  header, shrinks below MAXPLEN     65528       65532         65532
  1000 with a 24 byte hop header      992         992           992

(0 means ipv6_payload_len() returns the real length.)  On the forward
path, with a client injecting unlabeled UDP through a router to a
server, the router adds the CALIPSO option and the server delivers all
datagrams (Udp6InDatagrams 5, Ip6InTruncatedPkts 0) with this patch.

Fixes: 81fbc81213 ("ipv6/gro: insert temporary HBH/jumbo header")
Suggested-by: Eric Dumazet <edumazet@kernel.org>
Suggested-by: Wang Zhan <wang.zhan@smartx.com>
Signed-off-by: Joas Antonio dos Santos <joasantonio108@gmail.com>
Assisted-by: Claude:claude-opus-5-5
Reviewed-by: Wang Zhan <wang.zhan@smartx.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Link: https://patch.msgid.link/179156155963.36253.400481753322266658@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 12:50:03 +02:00
Breno Leitao
1c1e8c24d5 MAINTAINERS: add Gustavo Luiz Duarte as netconsole reviewer
Gustavo has been the most active netconsole reviewer, let's add him
to the MAINTAINERS file.

Add an R: entry so get_maintainer.pl Cc's Gustavo on netconsole patches.

Signed-off-by: Breno Leitao <leitao@debian.org>
Acked-by: Gustavo Luiz Duarte <gustavold@gmail.com>
Link: https://patch.msgid.link/20261009-netcon_main-v1-1-6d298ab5a0cd@debian.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 12:20:02 +02:00
Nicolai Buchwitz
89771ce4f8 net: bcmgenet: unshare the skb before writing the control block
bcmgenet stores first_cb, last_cb and bytes_sent in the skb control
block and reads them back on completion to free the skb and credit BQL.
ether_setup() leaves IFF_TX_SKB_SHARING set, so the stack can resubmit
a shared skb that is still in the ring. The next transmit overwrites
last_cb, so the earlier slots complete without crediting their bytes
and BQL stalls the queue until the watchdog resets it.

Unshare the skb before writing the control block.

Reproduce with pktgen in clone_skb mode, which hands the driver the same
skb while earlier copies are still in the ring:

  modprobe pktgen
  pg=/proc/net/pktgen
  echo "add_device eth0" > $pg/kpktgend_0
  echo "dst_mac AA:BB:CC:DD:EE:FF" > $pg/eth0
  echo "dst 192.0.2.1" > $pg/eth0
  echo "clone_skb 8" > $pg/eth0
  echo "count 0" > $pg/eth0
  echo start > $pg/pgctrl &
  sleep 5
  echo stop > $pg/pgctrl
  wait
  cat /sys/class/net/eth0/queues/tx-0/byte_queue_limits/inflight

inflight stays nonzero on the now idle queue. clone_skb 0 leaves it at
zero.

Fixes: f48bed16a7 ("net: bcmgenet: Free skb after last Tx frag")
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20261009-nb-genet-shared-skb-net-v1-1-c6d0a841977d@tipi-net.de
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 12:03:14 +02:00
Paolo Abeni
052b8920dd Merge branch 'net-move-setting-of-netops-to-fix-crash'
David Yang says:

====================
net: Move setting of netops to fix crash

Commit ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev()
locking assertion") put a netdev_need_ops_lock() check on the
phy_attach_direct() path, in phy_link_topo_add_phy(). With
CONFIG_NET_SHAPER enabled netdev_need_ops_lock() reads
dev->netdev_ops->net_shaper_ops, so any driver that connects a PHY
before assigning ndev->netdev_ops now dies with a NULL pointer
dereference at probe time. The breakage showed up in v7.3-rc1.

ibm/emac was hit first and fixed by commit 7c9f391ec8 ("net: emac:
move setting of netops to fix crash"). These ten patches apply the
same one-line move to the remaining in-tree drivers whose probe path
attaches a PHY before filling in netdev_ops:

  1. hisilicon/hisi_femac   (crash reproduced on hardware)
  2. hisilicon/hip04
  3. actions/owl-emac
  4. adi/adin1140
  5. marvell/mv643xx_eth
  6. amd/au1000_eth
  7. ethoc
  8. aeroflex/greth
  9. ti/icssm-prueth
 10. microchip/lan865x      (attach happens inside oa_tc6_init())

Only patch 1 was reproduced and verified on hardware; patches 2-10
were found by source inspection and are neither build nor boot
tested.

Note that ti/netcp_ethss and cavium/thunder_bgx attach a PHY to
netdevs that never get a netdev_ops at all (dummy netdevs), so they
cannot be fixed by reordering and are not addressed here.
====================

Link: https://patch.msgid.link/20261008022656.3592191-1-mmyangfl@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:26 +02:00
David Yang
2a3f6d2a9a microchip: lan865x: move setting of netops to fix crash
lan865x_probe() assigns netdev_ops only after oa_tc6_init(), which
connects the internal MAC-PHY through phy_connect_direct().
phy_attach_direct() -> phy_link_topo_add_phy() reads dev->netdev_ops
through netdev_need_ops_lock() since the commit in question, so probing
crashes with a NULL pointer dereference when CONFIG_NET_SHAPER is
enabled.

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20261008022656.3592191-11-mmyangfl@gmail.com
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:22 +02:00
David Yang
955bb7cf68 net: ti: icssm-prueth: Move setting of netops to fix crash
icssm_prueth_netdev_init() calls of_phy_get_and_connect() before
ndev->netdev_ops is assigned. phy_attach_direct() ->
phy_link_topo_add_phy() reads dev->netdev_ops through
netdev_need_ops_lock() since the commit in question, so probing crashes
with a NULL pointer dereference when CONFIG_NET_SHAPER is enabled.

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20261008022656.3592191-10-mmyangfl@gmail.com
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:21 +02:00
David Yang
d71483f071 net: ethernet: aeroflex: move setting of netops to fix crash
greth_of_probe() calls greth_mdio_init(), which connects the PHY,
before dev->netdev_ops is assigned. phy_attach_direct() ->
phy_link_topo_add_phy() reads dev->netdev_ops through
netdev_need_ops_lock() since the commit in question, so probing crashes
with a NULL pointer dereference when CONFIG_NET_SHAPER is enabled.

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Acked-by: Andreas Larsson <andreas@gaisler.com>
Link: https://patch.msgid.link/20261008022656.3592191-9-mmyangfl@gmail.com
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:21 +02:00
David Yang
c9f8ce62a5 net: ethoc: move setting of netops to fix crash
ethoc_probe() calls ethoc_mdio_probe(), which connects the PHY,
before netdev->netdev_ops is assigned. phy_attach_direct() ->
phy_link_topo_add_phy() reads dev->netdev_ops through
netdev_need_ops_lock() since the commit in question, so probing crashes
with a NULL pointer dereference when CONFIG_NET_SHAPER is enabled.

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261008022656.3592191-8-mmyangfl@gmail.com
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:21 +02:00
David Yang
beabbafdd0 net: au1000: move setting of netops to fix crash
au1000_probe() calls au1000_mii_probe(), which connects the PHY,
before dev->netdev_ops is assigned. phy_attach_direct() ->
phy_link_topo_add_phy() reads dev->netdev_ops through
netdev_need_ops_lock() since the commit in question, so probing crashes
with a NULL pointer dereference when CONFIG_NET_SHAPER is enabled.

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20261008022656.3592191-7-mmyangfl@gmail.com
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:21 +02:00
David Yang
a3eef3d2cc net: mv643xx: move setting of netops to fix crash
mv643xx_eth_probe() connects the PHY before dev->netdev_ops is
assigned. phy_attach_direct() -> phy_link_topo_add_phy() reads
dev->netdev_ops through netdev_need_ops_lock() since the commit in
question, so probing crashes with a NULL pointer dereference when
CONFIG_NET_SHAPER is enabled.

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261008022656.3592191-6-mmyangfl@gmail.com
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:21 +02:00
David Yang
ea1565cbf0 net: ethernet: adi: Move setting of netops to fix crash
adin1140_probe() calls adin1140_phy_init(), which connects the PHY,
before netdev->netdev_ops is assigned. phy_attach_direct() ->
phy_link_topo_add_phy() reads dev->netdev_ops through
netdev_need_ops_lock() since the commit in question, so probing crashes
with a NULL pointer dereference when CONFIG_NET_SHAPER is enabled.

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Ciprian Regus <ciprian.regus@analog.com>
Link: https://patch.msgid.link/20261008022656.3592191-5-mmyangfl@gmail.com
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:21 +02:00
David Yang
c2c4824319 net: ethernet: actions: Move setting of netops to fix crash
owl_emac_probe() calls owl_emac_phy_init(), which connects the PHY,
before netdev->netdev_ops is assigned. phy_attach_direct() ->
phy_link_topo_add_phy() reads dev->netdev_ops through
netdev_need_ops_lock() since the commit in question, so probing crashes
with a NULL pointer dereference when CONFIG_NET_SHAPER is enabled.

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20261008022656.3592191-4-mmyangfl@gmail.com
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:21 +02:00
David Yang
0d9342701f net: hisilicon: hip04_eth: Move setting of netops to fix crash
hip04_mac_probe() calls of_phy_connect() before ndev->netdev_ops is
assigned. phy_attach_direct() -> phy_link_topo_add_phy() reads
dev->netdev_ops through netdev_need_ops_lock() since the commit in
question, so probing crashes with a NULL pointer dereference when
CONFIG_NET_SHAPER is enabled.

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20261008022656.3592191-3-mmyangfl@gmail.com
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:21 +02:00
David Yang
444889dfa2 net: hisilicon: hisi_femac: Move setting of netops to fix crash
hisi_femac_drv_probe() connects the PHY before dev->netdev_ops is
assigned. phy_attach_direct() -> phy_link_topo_add_phy() reads
dev->netdev_ops through netdev_need_ops_lock() since the commit in
question, so probing crashes with a NULL pointer dereference when
CONFIG_NET_SHAPER is enabled.

  phy_link_topo_add_phy from phy_attach_direct+0xec/0x37c
  of_phy_get_and_connect from hisi_femac_drv_probe+0x1f4/0x558
  Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

Assign netdev_ops before the PHY attach, as was done for emac in commit
7c9f391ec8 ("net: emac: move setting of netops to fix crash").

Fixes: ded86da4bb ("net: ethtool: relax ethnl_req_get_phydev() locking assertion")
Signed-off-by: David Yang <mmyangfl@gmail.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Jijie Shao <shaojijie@huawei.com>
Link: https://patch.msgid.link/20261008022656.3592191-2-mmyangfl@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:39:21 +02:00
Kyle Zeng
f88bb3606e netlink: avoid hashing the network namespace pointer
The netlink rhashtable key includes a raw struct net pointer and a
user-controlled port ID. Both /proc/net/netlink and socket diagnostics
expose the table's bucket order. By binding and rebinding chosen
NETLINK_USERSOCK port IDs, an unprivileged reader can distinguish equal
buckets and recover the low bits of the Jenkins hash. Its 32-bit seed
and the limited set of kernel-image slides can then be searched offline
to recover the address of init_net.

Use the namespace's unique, non-address net_cookie in the comparison
key instead. It is assigned before the per-net initializers run and
remains unchanged for the namespace's lifetime. The lookup key and
object hash are still built by netlink_compare_arg_init(), keeping
lookup, insertion, removal and rehashing consistent while preserving
namespace separation. Neither public table walker needs to change.

Reading the socket's namespace cookie in netlink_compare() is safe
under RCU, including during namespace teardown. netlink_release()
removes the socket from the hash table and defers its final put with
call_rcu(). cleanup_net() runs the per-net exit methods and waits for
outstanding RCU callbacks with rcu_barrier() before freeing namespace
storage.

Unlike ns.ns_id, net_cookie is also available and initialized during
setup_net() in older stable kernels, making the change straightforward
to backport to v5.15 and later.

Fixes: c428ecd1a2 ("netlink: Move namespace into hash key")
Assisted-by: LLM
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261008011359.63727-2-kylebot@openai.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-15 10:27:45 +02:00
Wei Liu
dbc393f6f0 MAINTAINERS: drop KY from Hyper-V maintainers list
KY has retired from Microsoft.

Signed-off-by: Wei Liu <wei.liu@kernel.org>
2026-10-15 00:58:57 -07:00
Linus Torvalds
9fee1f650a workqueue: Fixes for v7.3-rc7
- Fix a NULL dereference in the check for whether the current task is
   running a memory reclaim work item when called from a kworker outside work
   item execution.
 -----BEGIN PGP SIGNATURE-----
 
 iIQEABYKACwWIQTfIjM1kS57o3GsC/uxYfJx3gVYGQUCatAC5g4cdGpAa2VybmVs
 Lm9yZwAKCRCxYfJx3gVYGbrsAP9YS8OZT8k1JxG55H34VWKbUia0ojydA/uGGhPp
 Sx/QNAD/erdd7pJr7MRCRbSTkk5nHmz+yjvpBgv+FTVf+16UCgI=
 =3vxA
 -----END PGP SIGNATURE-----

Merge tag 'wq-for-7.3-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq

Pull workqueue fix from Tejun Heo:

 - Fix a NULL dereference in the check for whether the current task is
   running a memory reclaim work item when called from a kworker outside
   work item execution

* tag 'wq-for-7.3-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq:
  workqueue: Fix NULL current_pwq deref in mem-reclaim helper
2026-10-14 16:11:57 -07:00
Linus Torvalds
db7afcbf9e sched_ext: Fixes for v7.3-rc7
- A task that skipped the BPF scheduler on its way back to its CPU's local
   queue could stall there until the watchdog fired, as the CPU had already
   decided to go idle.
 
 - Use-after-free of a destroyed user dispatch queue by a deferred re-enqueue
   request.
 
 - A task could be moved off a dispatch queue while the dispatching CPU was
   still running ops.dequeue() on it.
 
 - Bypass mode mishandled a sub-scheduler bypass overlapping an ancestor's,
   as across a system suspend. Descendants could leave bypass mid-teardown
   and tasks could be stranded on bypass queues.
 
 - The idle CPU selection helper could return a CPU outside the allowed CPUs
   of a pinned or migration-disabled task.
 -----BEGIN PGP SIGNATURE-----
 
 iIQEABYKACwWIQTfIjM1kS57o3GsC/uxYfJx3gVYGQUCatACow4cdGpAa2VybmVs
 Lm9yZwAKCRCxYfJx3gVYGdEvAP4tfwuDqRpiVDU/69SdALuWdObKorErLg/6uTxE
 53qODgEA4Vvao1ZtcxzF3Fd+umA13UgiJ8WBxX66XJDMaxXtiAo=
 =LtsB
 -----END PGP SIGNATURE-----

Merge tag 'sched_ext-for-7.3-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext

Pull sched_ext fixes from Tejun Heo:

 - A task that skipped the BPF scheduler on its way back to its CPU's
   local queue could stall there until the watchdog fired, as the CPU
   had already decided to go idle.

 - Use-after-free of a destroyed user dispatch queue by a deferred
   re-enqueue request.

 - A task could be moved off a dispatch queue while the dispatching CPU
   was still running ops.dequeue() on it.

 - Bypass mode mishandled a sub-scheduler bypass overlapping an
   ancestor's, as across a system suspend. Descendants could leave
   bypass mid-teardown and tasks could be stranded on bypass queues.

 - The idle CPU selection helper could return a CPU outside the allowed
   CPUs of a pinned or migration-disabled task.

* tag 'sched_ext-for-7.3-rc7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/sched_ext:
  sched_ext: Wait for SCX_OPSS_DISPATCHING before moving tasks off DSQs
  sched_ext: Rename scx_reenq_wait_dispatching() to scx_wait_dispatching()
  sched_ext: idle: Respect task affinity in restricted CPU selection
  sched_ext: Fix the bypass dispatch claim for schedulers bypassed by an ancestor
  sched_ext: Propagate every bypass depth change to the descendants
  sched_ext: Fix use-after-free of a destroyed user DSQ by a deferred reenqueue
  sched_ext: Fix stall when a task enqueued with SCX_ENQ_LAST lands back on its CPU's local DSQ
2026-10-14 15:58:16 -07:00
Linus Torvalds
e177c722b3 pci-v7.3-fixes-5
-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCgAyFiEEgMe7l+5h9hnxdsnuWYigwDrT+vwFAmrP3kgUHGJoZWxnYWFz
 QGdvb2dsZS5jb20ACgkQWYigwDrT+vzsGxAAsN2M6i1gbFHDljDAOEYJHtKevofh
 QFEiOUvlqhF/W5n5OFFIcvbnh4zeFYfZsnhkvEGl9/okCyRttUOVnzoddcL+Lep1
 ijNA1oE/G0kyZh9uh/QMgMZc2q/+sqeK/hHT11yjIjRIgI6FZ9MiiNM+0q0Z19Yu
 2E4dFS4vJxs/sIRz2xnuC3RrOgP1SpTW02GGNbPHw46rZ5XIQtUsolXSeCGF572w
 7RByICd86WPtC18IygNWnDLhCgOEX2G2whx+U1XQLKabsntG64qhTOvToJh4cxQI
 WDYPGEM/6k9ZH9CmkUBga+AqKLIyJDTMM1e/0xDTqn4ZUN5xg1jTc6Wa3iZRK0ql
 GhT5rgsOg2q32OwABNlgO0DFK13nDaHCrnkwlqVMT1aGSNqVs+hJLKOaoXuttVTb
 FsE9vWdlFa78rf02h3mX4gQOn5sbadbCZDdg8WEnv5FDV6ihjqgG/c4ZRW+0Ld0v
 hevnSsZfGzNQndBeaCMj+nHF7j5EONTmMKS5M40WtF8B+//EbTcJC5II4DpugwrC
 oAiIBNiNC6huqsFxi9YxeRKCH2geNTVdZbRMK75mpQoHS8t4+AmYed5HxBvxG4Le
 AV7y+1Xsaq1P3LJEZpJkOEs5A0za2l358Ujn9qWDJmWUDxs6irqb6eKjocD8niUO
 1iVQVjG/e9REYBA=
 =VrQ6
 -----END PGP SIGNATURE-----

Merge tag 'pci-v7.3-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci

Pull PCI fixes from Bjorn Helgaas:

 - Leave ANFE masked on Apple T2 Secure Enclave, which fixes spontaneous
   poweroff regressions on MacBookPro16,1 and likely other models with
   the T2 caused by new Advisory Non-Fatal Error support (Jason Perlow)

 - Move dw-rockchip INTx IRQ setup from rockchip_pcie_host_init(), where
   it runs after every reset, to the rockchip_pcie_probe() path to avoid
   installing new IRQ handler (which causes INTx IRQs to be lost) and
   leaking an IRQ domain on every reset; fixes a regression added this
   cycle (Shawn Lin)

* tag 'pci-v7.3-fixes-5' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci:
  PCI: dw-rockchip: Move INTx IRQ setup to probe
  PCI/AER: Keep ANFE masked on Apple T2 Secure Enclave
2026-10-14 15:50:48 -07:00
Christian Brauner
906f04fb1e
Merge patch series "namespace: a mount that copy_tree() leaves out can't take over a lock"
Christian Brauner <brauner@kernel.org> says:

Since commit c62a476693 ("move_mount: transfer MNT_LOCKED") a mount
can be moved beneath a locked mount. The lock moves from the old cover
to the new mount which takes over the job of hiding what's under it and
the old cover can be unmounted. That works as long as the new mount
stays. But the caller picks the new mount and copy_tree() leaves a
mount of a mount namespace file out of every copy made without
CL_COPY_MNT_NS_FILE, together with everything mounted on it, and never
looks at MNT_LOCKED. unshare(CLONE_NEWNS) and mount propagation make
such copies.

So a task that is root in its own user namespace gets rid of a locked
cover on a file without a race and without touching the filesystem
below it. It makes a child with a mount namespace of its own, binds the
child's /proc/<pid>/ns/mnt beneath the cover with MOVE_MOUNT_BENEATH,
which hands the lock to that bind, and calls unshare(CLONE_NEWNS). The
new mount namespace has nothing on the file. That's the usual way to
mask a single file, a bind of /dev/null or of an empty file. With a
bind of an ordinary file the file stays covered.

copy_tree() already refuses to leave out a locked unbindable mount with
-EPERM since commit df7342b240 ("mount: Don't allow copying
MNT_UNBINDABLE|MNT_LOCKED mounts"). Do the same for a locked mount of a
mount namespace file. That also covers a tree copied with
CL_COPY_MNT_NS_FILE and attached into a mount namespace of another user
namespace where lock_mnt_tree() locks it. Note that unshare(CLONE_NEWNS)
and clone(CLONE_NEWNS) fail with EPERM from such a mount namespace from
then on. The mount can't be left out and it can't be unmounted.

And refuse to move a mount of a mount namespace file beneath a locked
mount in the first place. Otherwise the task ends up with a mount it
can't unmount and an unshare() that fails for good.

* patches from https://patch.msgid.link/20261014-work-namei-locked-mnt_ns_file-v1-0-24035bd5d8e9@kernel.org:
  selftests/filesystems: test that a mntns file can't take over a lock
  namespace: a mount that copy_tree() leaves out can't take over a lock

Link: https://patch.msgid.link/20261014-work-namei-locked-mnt_ns_file-v1-0-24035bd5d8e9@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:06 +02:00
Christian Brauner
a7064be65f
Merge patch series "fs: don't let idle threads pin the initramfs"
Christian Brauner <brauner@kernel.org> says:

Since v7.0 nullfs is the real rootfs and userspace can pivot_root() away
from the initramfs and unmount it. systemd does exactly that and the
initramfs is supposed to be freed afterwards. But it isn't (cf. [1]).
The unpacked initramfs stays around forever. It shows up as Unevictable
in /proc/meminfo with ramfs and as Shmem with tmpfs. In the reports
that's between 70MB and 150MB.

Two things keep it alive and neither is visible from userspace:

(1) On v7.0 to v7.2 devtmpfsd unshares a copy of the initial mount
    namespace which since nullfs contains the initramfs mount. It
    doesn't show up in /proc/<pid>/mountinfo because it's below the
    thread's root. That's already fixed in mainline by commit
    66d2faeccb ("devtmpfs: create private mount namespace").

(2) On all kernels since v7.0 the idle threads of the secondary cpus
    are forked from PID 1 and each of them gets a private copy of the
    fs_struct of PID 1 with the initramfs as root and pwd. Idle threads
    aren't on the task list so pivot_root() never moves them over to
    the new root and they never exit. With a single possible cpu there
    are no such idle threads which is why booting a VM with -smp 1
    hides it.

This series fixes (2) by letting the idle threads share init_fs like
init_task already does. The first patch turns the umh boolean of
copy_fs() into flags. The second patch is the actual fix and carries a
reproducer.

systemd could go back to emptying the initramfs when switching root like
it did before nullfs and that's what [2] does. But that only frees the
contents. The mount and the superblock stay pinned. And I don't think
userspace should have to do that. With nullfs it's supposed to be able
to just unmount the initramfs and be done with it.

We could also teach chroot_fs_refs() about idle threads. But they are
kernel threads and have no business holding a reference to the root of
userspace to begin with.

Of the stable kernels only v7.2 is affected and the backport looks
different there. PID 1 still shares init_fs with all kthreads so passing
CLONE_FS in fork_idle() is enough. It also needs 66d2faeccb which
applies cleanly.

I've tested this with the reproducer from the second patch and with a
systemd 262 initrd on 4 cpus. On vfs.fixes about 170MB stay Unevictable
after switching root and with this series they're freed. Same for the
backport on v7.2.

[1]: https://github.com/systemd/systemd/issues/43911
[2]: https://github.com/systemd/systemd/pull/44144

* patches from https://patch.msgid.link/20261013-work-fs-idle_fs-v1-0-2063d1bcb5aa@kernel.org:
  fs: let idle threads share init_fs
  fs: pass flags to copy_fs()

Link: https://patch.msgid.link/20261013-work-fs-idle_fs-v1-0-2063d1bcb5aa@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:06 +02:00
Christian Brauner
eadfe727dd
selftests/filesystems: test that a mntns file can't take over a lock
Add a case to the locked mount test:

- a bind of the mount namespace file of a grandchild moved beneath a
  locked cover must fail with EINVAL
- a bind of an ordinary file beneath it takes the lock over, the old
  cover can go and the new one can't
- the file is still covered after unshare(CLONE_NEWNS)

Link: https://patch.msgid.link/20261014-work-namei-locked-mnt_ns_file-v1-2-24035bd5d8e9@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:06 +02:00
Christian Brauner
d2bdb9b61b
fs: let idle threads share init_fs
With nullfs as the real rootfs userspace can pivot_root() away from the
initramfs and unmount it:

    chdir(rootfs);
    pivot_root(".", ".");
    umount2(".", MNT_DETACH);

That's what systemd does and the initramfs is supposed to go away at
that point together with all the memory it uses. But on every machine
with more than one possible cpu the initramfs superblock stays around
forever (cf. [1]). With ramfs as rootfs the unpacked initramfs shows up
as Unevictable in /proc/meminfo, with tmpfs as Shmem, and it is never
freed. In the reports that's between 70MB and 150MB.

The idle threads of the secondary cpus are created by fork_idle() from
smp_init(). That runs in kernel_init(), i.e., in PID 1, after
init_userspace_fs() moved PID 1 from nullfs into the initramfs.
fork_idle() doesn't pass CLONE_FS so each idle thread gets a private
copy of PID 1's fs_struct and with it a reference to the initramfs as
root and as pwd.

pivot_root() relies on chroot_fs_refs() to move everyone whose root or
pwd is the old root over to the new root. Idle threads aren't on the
task list though so chroot_fs_refs() never finds them. They never exit
either. So they keep the initramfs mount and with it the superblock
alive for good. I overlooked this when I added nullfs. Before that the
rootfs could never be unmounted anyway so it didn't matter what pinned
it.

Idle threads are kernel threads and init_task, the idle thread of the
boot cpu, already uses init_fs. So let the idle threads of the other
cpus share init_fs as well instead of copying PID 1's filesystem state.

Note that kernels before 7.3 need a different backport. There PID 1
still shares init_fs with all kthreads so passing CLONE_FS in
fork_idle() is enough. They also have a second pin: devtmpfsd unshares
a copy of the initial mount namespace, initramfs mount included. That
was fixed in commit 66d2faeccb ("devtmpfs: create private mount
namespace").

Reproducer, as /init in an initramfs together with a 128MB ballast
file, booted with root=/dev/sda to get ramfs and with -smp 4:

    // SPDX-License-Identifier: GPL-2.0
    /* initramfs /init: switch root like systemd, check the old root */
    #define _GNU_SOURCE
    #include <fcntl.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/mount.h>
    #include <sys/reboot.h>
    #include <sys/sendfile.h>
    #include <sys/stat.h>
    #include <sys/syscall.h>
    #include <sys/sysmacros.h>
    #include <unistd.h>

    static void meminfo(void)
    {
    	char line[256];
    	FILE *f = fopen("/proc/meminfo", "re");

    	while (f && fgets(line, sizeof(line), f))
    		if (!strncmp(line, "Unevictable:", 12) ||
    		    !strncmp(line, "Shmem:", 6))
    			fputs(line, stdout);
    	if (f)
    		fclose(f);
    }

    int main(int argc, char *argv[])
    {
    	struct stat st;
    	char dev[32], buf[32];
    	unsigned int maj, min;
    	int fd, in, out;
    	long r;

    	if (argc > 1) {
    		sleep(2);
    		meminfo();
    		/* ustat() only finds live superblocks */
    		r = syscall(SYS_ustat, (unsigned)atoi(argv[1]), buf);
    		printf("initramfs superblock %s\n", r ? "freed" : "pinned");
    		fflush(stdout);
    		sleep(1);
    		reboot(RB_POWER_OFF);
    	}

    	mount("proc", "/proc", "proc", 0, NULL);
    	mount("devtmpfs", "/dev", "devtmpfs", 0, NULL);
    	/* drop the fds console_on_rootfs() opened in the initramfs */
    	fd = open("/dev/console", O_RDWR);
    	dup2(fd, 0);
    	dup2(fd, 1);
    	dup2(fd, 2);
    	close(fd);
    	setvbuf(stdout, NULL, _IOLBF, 0);
    	meminfo();

    	stat("/", &st);
    	maj = major(st.st_dev);
    	min = minor(st.st_dev);
    	/* new_encode_dev(), what ustat() expects */
    	snprintf(dev, sizeof(dev), "%u",
    		 (min & 0xff) | (maj << 8) | ((min & ~0xffu) << 12));

    	mkdir("/sysroot", 0755);
    	mount("tmpfs", "/sysroot", "tmpfs", 0, NULL);
    	mkdir("/sysroot/proc", 0755);
    	mkdir("/sysroot/dev", 0755);
    	in = open("/init", O_RDONLY);
    	out = open("/sysroot/init", O_WRONLY | O_CREAT, 0755);
    	fstat(in, &st);
    	sendfile(out, in, NULL, st.st_size);
    	close(in);
    	close(out);

    	mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL);
    	mount("/proc", "/sysroot/proc", NULL, MS_BIND | MS_REC, NULL);
    	mount("/dev", "/sysroot/dev", NULL, MS_BIND | MS_REC, NULL);
    	chdir("/sysroot");
    	if (syscall(SYS_pivot_root, ".", ".") || umount2(".", MNT_DETACH))
    		perror("pivot_root");
    	execl("/init", "/init", dev, NULL);
    	return 1;
    }

Before:

    Unevictable:      131812 kB
    Shmem:                 0 kB
    Unevictable:      131812 kB
    Shmem:               792 kB
    initramfs superblock pinned

After:

    Unevictable:      131812 kB
    Shmem:                 0 kB
    Unevictable:           0 kB
    Shmem:               792 kB
    initramfs superblock freed

With -smp 1 the superblock is freed without this patch as well.

[1]: https://github.com/systemd/systemd/issues/43911

Fixes: 576ee5dfd4 ("fs: add immutable rootfs")
Link: https://patch.msgid.link/20261013-work-fs-idle_fs-v1-2-2063d1bcb5aa@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:06 +02:00
Christian Brauner
69fbe94f80
namespace: a mount that copy_tree() leaves out can't take over a lock
Since commit c62a476693 ("move_mount: transfer MNT_LOCKED") a mount
can be moved beneath a locked mount. The lock moves from the old cover
to the new mount which takes over the job of hiding what's under it and
the old cover can be unmounted. That works as long as the new mount
stays. But the caller picks the new mount and copy_tree() leaves a
mount of a mount namespace file out of every copy made without
CL_COPY_MNT_NS_FILE, together with everything mounted on it, and never
looks at MNT_LOCKED. unshare(CLONE_NEWNS) and mount propagation make
such copies.

So a task that is root in its own user namespace gets rid of a locked
cover on a file without a race and without touching the filesystem
below it. It makes a child with a mount namespace of its own, binds the
child's /proc/<pid>/ns/mnt beneath the cover with MOVE_MOUNT_BENEATH,
which hands the lock to that bind, and calls unshare(CLONE_NEWNS). The
new mount namespace has nothing on the file. That's the usual way to
mask a single file, a bind of /dev/null or of an empty file. With a
bind of an ordinary file the file stays covered.

copy_tree() already refuses to leave out a locked unbindable mount with
-EPERM since commit df7342b240 ("mount: Don't allow copying
MNT_UNBINDABLE|MNT_LOCKED mounts"). Do the same for a locked mount of a
mount namespace file. That also covers a tree copied with
CL_COPY_MNT_NS_FILE and attached into a mount namespace of another user
namespace where lock_mnt_tree() locks it. Note that unshare(CLONE_NEWNS)
and clone(CLONE_NEWNS) fail with EPERM from such a mount namespace from
then on. The mount can't be left out and it can't be unmounted.

And refuse to move a mount of a mount namespace file beneath a locked
mount in the first place. Otherwise the task ends up with a mount it
can't unmount and an unshare() that fails for good.

Chris also found a second mount that goes away by itself, a clone of an
automounted mount that shrink_submounts() took along with its parent.
Commit f78ddcc872 ("namespace: never expire a locked mount") took
care of that one.

Chris's reproducer is appended. Mode nsfile reads SECRET after the
unshare() on 7.3-rc7, with this patch the move_mount() fails with
EINVAL and the file stays covered. nsfile-control uses an ordinary file
and reads MASK both ways.

  // SPDX-License-Identifier: GPL-2.0
  /*
   * Get rid of a locked cover with MOVE_MOUNT_BENEATH.
   *
   * The "admin" (root) makes a tmpfs W:
   *     W/D         file, holds SECRET, covered by a bind of a file with MASK
   *     W/Dd/inner  file, holds SECRET, Dd is covered by a bind of a directory
   *                 whose "inner" holds MASK
   *     W/own       directory of uid 1000 with the file "mine" and the
   *                 directory "minedir", whose "inner" holds MINE
   *     W/dbg       debugfs, mode 755. dbg/tracing is an automount point
   * The "attacker" is uid 1000. It enters a new user namespace with a new mount
   * namespace, so W and both covers are locked there.
   *
   * usage: prog MODE
   *   plain      put a bind of own/mine beneath the cover of D, unmount the cover
   *   nsfile     put a bind of the mount namespace file of a child beneath the
   *              cover of D, then unshare(CLONE_NEWNS)
   *   nsfile-control    the same with a bind of own/mine
   *   shrink     put a bind of the automounted tracefs beneath the cover of Dd,
   *              unmount the cover, put a tmpfs beneath W, call umount(W), which fails
   *   shrink-control    the same with a bind of own/minedir
   * The environment variable AUTOMOUNT_DIR names another automount point for "shrink".
   */
  #define _GNU_SOURCE
  #include <errno.h>
  #include <fcntl.h>
  #include <grp.h>
  #include <sched.h>
  #include <signal.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
  #include <sys/mount.h>
  #include <sys/prctl.h>
  #include <sys/stat.h>
  #include <sys/wait.h>

  #ifndef MOVE_MOUNT_BENEATH
  #define MOVE_MOUNT_BENEATH 0x00000200
  #endif
  #define W "/run/x2"

  static void die(const char *what)
  {
  	fprintf(stderr, "FATAL %s: %s\n", what, strerror(errno));
  	exit(2);
  }

  static void put_file(const char *name, const char *content)
  {
  	int fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644);

  	if (fd < 0 || write(fd, content, strlen(content)) < 0)
  		die(name);
  	close(fd);
  }

  static void show(const char *path)
  {
  	char buf[32] = "";
  	int fd = open(path, O_RDONLY);

  	if (fd < 0) {
  		printf("attacker: open(%s) = %s\n", path, strerror(errno));
  		return;
  	}
  	if (read(fd, buf, sizeof(buf) - 1) < 0)
  		snprintf(buf, sizeof(buf), "<%s>", strerror(errno));
  	close(fd);
  	printf("attacker: read(%s) = \"%s\"%s\n", path, buf,
  	       strncmp(buf, "SECRET", 6) ? "" : "   <-- HIT");
  }

  static int say(const char *what, int ret)
  {
  	printf("attacker: %s: %s\n", what, ret ? strerror(errno) : "ok");
  	return ret;
  }

  static void write_str(const char *path, const char *s)
  {
  	int fd = open(path, O_WRONLY);

  	if (fd < 0 || write(fd, s, strlen(s)) < 0)
  		die(path);
  	close(fd);
  }

  static void mounts(void)
  {
  	if (system("grep x2 /proc/self/mountinfo"))
  		printf("attacker: no mounts listed\n");
  }

  static void admin_setup(void)
  {
  	if (unshare(CLONE_NEWNS) || mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL))
  		die("unshare");
  	mkdir(W, 0755);
  	if (mount("W", W, "tmpfs", 0, "mode=755"))
  		die("mount W");
  	if (mkdir(W "/Dd", 0755) || mkdir(W "/maskdir", 0755) || mkdir(W "/dbg", 0755) ||
  	    mkdir(W "/own", 0755) || mkdir(W "/own/minedir", 0755))
  		die("mkdir");
  	put_file(W "/D", "SECRET");
  	put_file(W "/Dd/inner", "SECRET");
  	put_file(W "/mask", "MASK");
  	put_file(W "/maskdir/inner", "MASK");
  	put_file(W "/own/mine", "MINE");
  	put_file(W "/own/minedir/inner", "MINE");
  	if (mount(W "/mask", W "/D", NULL, MS_BIND, NULL) ||
  	    mount(W "/maskdir", W "/Dd", NULL, MS_BIND, NULL))
  		die("covers");
  	if (mount("dbg", W "/dbg", "debugfs", 0, "mode=755"))
  		die("mount debugfs");
  }

  static void become_attacker(void)
  {
  	if (setgroups(0, NULL) || setresgid(1000, 1000, 1000) ||
  	    setresuid(1000, 1000, 1000) || prctl(PR_SET_DUMPABLE, 1))
  		die("drop to uid 1000");
  	if (unshare(CLONE_NEWUSER | CLONE_NEWNS))
  		die("unshare user and mount namespace");
  	write_str("/proc/self/setgroups", "deny");
  	write_str("/proc/self/uid_map", "0 1000 1");
  	write_str("/proc/self/gid_map", "0 1000 1");
  }

  /* clone the mount at @src and put the clone beneath the top mount at @where */
  static int beneath(const char *src, const char *where)
  {
  	char what[128];
  	int fd = open_tree(AT_FDCWD, src, OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC);
  	int ret;

  	snprintf(what, sizeof(what), "open_tree(%s, OPEN_TREE_CLONE)", src);
  	if (say(what, fd < 0))
  		return -1;
  	ret = move_mount(fd, "", AT_FDCWD, where,
  			 MOVE_MOUNT_F_EMPTY_PATH | MOVE_MOUNT_BENEATH);
  	snprintf(what, sizeof(what), "move_mount(clone, %s, MOVE_MOUNT_BENEATH)", where);
  	say(what, ret);
  	close(fd);
  	return ret;
  }

  static void do_nsfile(int control)
  {
  	char path[64] = W "/own/mine";
  	int pfd[2];
  	pid_t pid;
  	char c;

  	if (pipe(pfd))
  		die("pipe");
  	pid = fork();
  	if (pid < 0)
  		die("fork");
  	if (!pid) {
  		if (unshare(CLONE_NEWNS) || write(pfd[1], "g", 1) != 1)
  			die("child");
  		pause();
  		exit(0);
  	}
  	if (read(pfd[0], &c, 1) != 1)
  		die("sync");
  	if (!control)
  		snprintf(path, sizeof(path), "/proc/%d/ns/mnt", pid);
  	beneath(path, W "/D");
  	mounts();
  	say("unshare(CLONE_NEWNS)", unshare(CLONE_NEWNS));
  	show(W "/D");
  	mounts();
  	kill(pid, SIGKILL);
  	waitpid(pid, NULL, 0);
  }

  static void do_shrink(int control)
  {
  	const char *automount = getenv("AUTOMOUNT_DIR");
  	int fd, mfd;

  	if (!automount)
  		automount = W "/dbg/tracing";
  	beneath(control ? W "/own/minedir" : automount, W "/Dd");
  	say("umount2(Dd, 0), the old cover", umount2(W "/Dd", 0));
  	say("umount2(Dd, 0), the mount that was put beneath", umount2(W "/Dd", 0));
  	show(W "/Dd/inner");
  	say("umount2(W, 0)", umount2(W, 0));
  	fd = fsopen("tmpfs", FSOPEN_CLOEXEC);
  	if (fd < 0 || fsconfig(fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0))
  		die("fsopen tmpfs");
  	mfd = fsmount(fd, FSMOUNT_CLOEXEC, 0);
  	if (mfd < 0)
  		die("fsmount");
  	say("move_mount(new tmpfs, W, MOVE_MOUNT_BENEATH)",
  	    move_mount(mfd, "", AT_FDCWD, W, MOVE_MOUNT_F_EMPTY_PATH | MOVE_MOUNT_BENEATH));
  	close(mfd);
  	mounts();
  	say("umount2(W, 0)", umount2(W, 0));
  	show(W "/Dd/inner");
  	mounts();
  }

  int main(int argc, char **argv)
  {
  	const char *mode = argc > 1 ? argv[1] : "plain";

  	setvbuf(stdout, NULL, _IOLBF, 0);
  	admin_setup();
  	become_attacker();

  	show(W "/D");
  	show(W "/Dd/inner");
  	say("umount2(D, MNT_DETACH)", umount2(W "/D", MNT_DETACH));
  	say("umount2(Dd, MNT_DETACH)", umount2(W "/Dd", MNT_DETACH));

  	if (!strcmp(mode, "plain")) {
  		beneath(W "/own/mine", W "/D");
  		show(W "/D");
  		say("umount2(D, MNT_DETACH), the old cover", umount2(W "/D", MNT_DETACH));
  		show(W "/D");
  		say("umount2(D, MNT_DETACH), the mount that was put beneath",
  		    umount2(W "/D", MNT_DETACH));
  		show(W "/D");
  		mounts();
  	} else if (!strncmp(mode, "nsfile", 6)) {
  		do_nsfile(!strcmp(mode, "nsfile-control"));
  	} else {
  		do_shrink(!strcmp(mode, "shrink-control"));
  	}
  	return 0;
  }

Fixes: c62a476693 ("move_mount: transfer MNT_LOCKED")
Reported-by: Chris Mason <mason@kernel.org>
Cc: stable@vger.kernel.org # v7.1+
Link: https://patch.msgid.link/20261014-work-namei-locked-mnt_ns_file-v1-1-24035bd5d8e9@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:06 +02:00
Christian Brauner
98b6cf102b
namei: test for a negative dentry the way traverse_mounts() does
lookup_fast_for_open() only hands an O_CREAT open a cached dentry if
it's positive. Otherwise the open goes on to lookup_open(), which takes
the directory lock and creates the file. It tests for that with
!dentry->d_inode, but traverse_mounts() later decides with the type in
d_flags. And when a dentry is instantiated __d_set_inode_and_type()
stores ->d_inode first and only then releases the type into ->d_flags.

So a refwalk that took its reference to a negative dentry right before
another task instantiates it can find ->d_inode already set in
lookup_fast_for_open(), go on to step_into(), and still find the
negative type in traverse_mounts(). The open then fails with -ENOENT,
which an O_CREAT open must never do. rcuwalk doesn't get that far, the
d_seq check in step_into() catches the instantiation.

Use d_is_negative() so both look at the type. While the type is still
negative the open takes lookup_open() and waits for the directory lock
like any other O_CREAT open of a negative dentry.

On its own the window is a couple of instructions in the creating task,
so it takes an interrupt or a preempted vcpu in exactly the right spot.
I haven't caught it without help in about 600 million racing O_CREAT
opens.

The debug patch below stalls the creating task between the two stores
for names starting with "ocrace", the way an interrupt landing there
would. The reproducer below opens "ocrace" with O_CREAT through
symlinks on a strictatime tmpfs: following them updates their atime,
which drops the walk out of rcuwalk, so the name is always looked up in
refwalk. With

  echo 20 > /proc/sys/fs/ocrace_instantiate_us
  ./ocreat_enoent -t 60

on a KASAN kernel open() failed with -ENOENT 43 times in 4.9 million
calls. With this patch it never failed in 4.8 million calls. Tracing
step_into_slowpath() during such a run, each of the 98 -ENOENTs it
returned came right after the same task had entered it with a dentry
that was still typed negative.

  // SPDX-License-Identifier: GPL-2.0
  /*
   * ocreat_enoent: open(O_CREAT) racing the creation of the same name.
   *
   * Writers unlink "ocrace" and create it again. Readers open it with
   * O_CREAT through a symlink of their own on a strictatime tmpfs.
   * Following the symlink updates its atime, which drops the walk out of
   * rcu mode, so the name is always looked up in refwalk. An O_CREAT open
   * must never fail with ENOENT.
   *
   * -p arms a cpu-clock perf timer with that period in ns on every writer,
   * so that interrupts land at random points in it.
   *
   *   usage: ocreat_enoent [-t secs] [-w writers] [-r readers] [-p ns]
   */
  #define _GNU_SOURCE
  #include <errno.h>
  #include <fcntl.h>
  #include <pthread.h>
  #include <stdatomic.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <sys/mount.h>
  #include <sys/stat.h>
  #include <sys/syscall.h>
  #include <unistd.h>
  #include <linux/perf_event.h>

  #define DIR "/tmp/oc"

  static atomic_int stop;
  static atomic_long opens, creates, enoent, other;
  static long period;

  static void die(const char *what)
  {
  	fprintf(stderr, "FATAL %s: %s\n", what, strerror(errno));
  	exit(2);
  }

  static void *writer(void *arg)
  {
  	(void)arg;
  	if (period) {
  		struct perf_event_attr attr = {
  			.type = PERF_TYPE_SOFTWARE,
  			.size = sizeof(attr),
  			.config = PERF_COUNT_SW_CPU_CLOCK,
  			.sample_period = period,
  		};

  		if (syscall(SYS_perf_event_open, &attr, 0, -1, -1, 0) < 0)
  			die("perf_event_open");
  	}
  	while (!atomic_load(&stop)) {
  		int fd;

  		unlink(DIR "/ocrace");
  		fd = open(DIR "/ocrace", O_CREAT | O_RDWR | O_CLOEXEC, 0644);
  		if (fd >= 0)
  			close(fd);
  		atomic_fetch_add(&creates, 1);
  	}
  	return NULL;
  }

  static void *reader(void *arg)
  {
  	char lnk[64];

  	snprintf(lnk, sizeof(lnk), DIR "/lnk.%ld", (long)arg);
  	while (!atomic_load(&stop)) {
  		int fd = open(lnk, O_CREAT | O_RDWR | O_CLOEXEC, 0644);

  		if (fd >= 0)
  			close(fd);
  		else if (errno == ENOENT)
  			atomic_fetch_add(&enoent, 1);
  		else
  			atomic_fetch_add(&other, 1);
  		atomic_fetch_add(&opens, 1);
  	}
  	return NULL;
  }

  int main(int argc, char **argv)
  {
  	int secs = 60, nw = 4, nr = 12, c, n = 0;
  	pthread_t t[256];

  	while ((c = getopt(argc, argv, "t:w:r:p:")) != -1) {
  		switch (c) {
  		case 't': secs = atoi(optarg); break;
  		case 'w': nw = atoi(optarg); break;
  		case 'r': nr = atoi(optarg); break;
  		case 'p': period = atol(optarg); break;
  		default: return 2;
  		}
  	}
  	if (nw + nr > 256)
  		return 2;
  	mkdir(DIR, 0755);
  	if (mount("oc", DIR, "tmpfs", MS_STRICTATIME, "mode=0755"))
  		die("tmpfs");
  	for (long i = 0; i < nr; i++) {
  		char lnk[64];

  		snprintf(lnk, sizeof(lnk), DIR "/lnk.%ld", i);
  		if (symlink("ocrace", lnk))
  			die("symlink");
  	}
  	for (long i = 0; i < nw; i++)
  		if (pthread_create(&t[n++], NULL, writer, NULL))
  			die("writer");
  	for (long i = 0; i < nr; i++)
  		if (pthread_create(&t[n++], NULL, reader, (void *)i))
  			die("reader");
  	sleep(secs);
  	atomic_store(&stop, 1);
  	for (int i = 0; i < n; i++)
  		pthread_join(t[i], NULL);
  	printf("%ds: %ld opens, %ld creates, ENOENT %ld, other errors %ld\n",
  	       secs, atomic_load(&opens), atomic_load(&creates),
  	       atomic_load(&enoent), atomic_load(&other));
  	umount2(DIR, MNT_DETACH);
  	return atomic_load(&enoent) ? 1 : 0;
  }

  diff --git a/fs/dcache.c b/fs/dcache.c
  --- a/fs/dcache.c
  +++ b/fs/dcache.c
  @@ -32,9 +32,13 @@
   #include <linux/bit_spinlock.h>
   #include <linux/rculist_bl.h>
   #include <linux/list_lru.h>
  +#include <linux/delay.h>
   #include "internal.h"
   #include "mount.h"

  +/* debug: stall "ocrace*" names between ->d_inode and the type */
  +static int sysctl_ocrace_instantiate_us;
  +
   #include <asm/runtime-const.h>

   /*
  @@ -200,6 +204,13 @@
   }

   static const struct ctl_table fs_dcache_sysctls[] = {
  +	{
  +		.procname	= "ocrace_instantiate_us",
  +		.data		= &sysctl_ocrace_instantiate_us,
  +		.maxlen		= sizeof(int),
  +		.mode		= 0644,
  +		.proc_handler	= proc_dointvec,
  +	},
   	{
   		.procname	= "dentry-state",
   		.data		= &dentry_stat,
  @@ -405,6 +416,10 @@
   	unsigned flags;

   	dentry->d_inode = inode;
  +	/* debug: an interrupt landing right here */
  +	if (unlikely(READ_ONCE(sysctl_ocrace_instantiate_us)) &&
  +	    !strncmp(dentry->d_name.name, "ocrace", 6))
  +		udelay(READ_ONCE(sysctl_ocrace_instantiate_us));
   	flags = READ_ONCE(dentry->d_flags);
   	flags &= ~DCACHE_ENTRY_TYPE;
   	flags |= type_flags;

Fixes: e747e15156 ("fs: try an opportunistic lookup for O_CREAT opens too")
Cc: stable@vger.kernel.org # v6.12+
Link: https://patch.msgid.link/20261012-work-namei-ocreate-v1-1-c7883b17ee28@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:05 +02:00
Christian Brauner
9cd0df397a
fs: pass flags to copy_fs()
Turn the umh boolean into a flags argument. Idle threads need their own
case in copy_fs() as well and that's nicer than a second boolean.

No functional changes.

Link: https://patch.msgid.link/20261013-work-fs-idle_fs-v1-1-2063d1bcb5aa@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:05 +02:00
Guanglei Zhu
99ae7dc439
ovl: reject lowerdir ending with unescaped backslash
In ovl_parse_param_split_lowerdirs() a backslash consumes the
character that follows it.  When the backslash is the last character
of the lowerdir value, it consumes the NUL terminator: the loop exits
normally and the backslash is kept in the output, so the lowerdir is
passed downstream with a trailing backslash and the mount fails later
with a confusing ENOENT from path lookup.

A trailing unescaped backslash escapes nothing, so reject it with
EINVAL.

Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Link: https://patch.msgid.link/20261012095538.938789-1-zhugl3@xiaopeng.com
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:05 +02:00
Kyle Zeng
36ebddca56
fsnotify: prevent mark additions during connector teardown
fsnotify_destroy_marks() keeps a reference to its current mark while it
drops conn->lock to destroy the mark. This stabilizes the forward-walk
cursor, but does not prevent a new mark from being inserted before it.
For example, an inotify watch re-added after IN_IGNORED sorts before the
old, detached mark for the same group. The walk can miss the replacement
and then detach the entire connector from the object.

The replacement is still on its group's marks_list and, for inotify, in
the watch IDR. The group mutex no longer protects the connector's object
from disappearing. An unprivileged fdinfo read racing the final detach
can consequently call igrab(NULL):

  BUG: KASAN: null-ptr-deref in igrab+0x24/0x100
  Write of size 4 at addr 0000000000000148
  Call Trace:
   igrab+0x24/0x100
   inotify_show_fdinfo+0x1dc/0x5e0
   seq_show+0x397/0x690

Set a DESTROYING flag under conn->lock before starting the walk, and
reject new marks on that connector with -ENOENT. The existing add-mark
error paths undo the temporary group-list entry and the backend's watch
allocation. Do not wait for teardown while holding the group mutex,
which the destroyer needs. Once the old connector is detached, an add
can install a fresh connector as before.

This closes the insertion race for all object types using the common
connector teardown, without changing the mark reference or SRCU lifetime
rules.

Fixes: 6b3f05d24d ("fsnotify: Detach mark from object list when last reference is dropped")
Cc: stable@vger.kernel.org
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:05 +02:00
Christian Brauner
40d38f58fc
Merge patch series "fs: drop the smp_mb()s that mnt_get_count() made redundant"
Christian Brauner <brauner@kernel.org> says:

mntput_no_expire_slowpath() and do_umount() both have an smp_mb()
between taking mount_lock and summing up the reference count. They pair
with the smp_mb() in __legitimize_mnt(). The walker increments the count
and then re-reads the seqcount. The unmounter writes the seqcount when
it takes mount_lock and then sums up the count. They must not both miss
each other's store. That's store buffering and it needs a full barrier
on both sides.

Since 7eb84d54fa ("fs: don't let a migrating task hide its reference
from do_umount()"), which is in mainline now, mnt_get_count() has an
smp_mb() between summing up the puts and the gets. In program order it
sits after the seqcount write and before the loads of the gets. That's
the barrier the walker needs. The outer ones don't order anything on
top of it that anyone relies on. So drop them.

I ran into this while getting rid of the grace period in
namespace_unlock(). It doesn't depend on that work so I'm sending it on
its own.

A reproducer can't exercise this. The pairing is store buffering with a
full barrier on both sides, which is exactly
tools/memory-model/litmus-tests/SB+fencembonceonces.litmus: the
walker's increment is the store to x and its re-read of the seqcount
the load of y, the seqcount write in lock_mount_hash() is the store to
y and the loads of the gets in mnt_get_count() the load of x. I had two
litmus tests cut from fs/namespace.c in the series for this. Andrea
pointed out that once the seqlock and the lock are peeled off that's
all that's left of them, so I dropped them. They and their runs under
the AArch64, POWER, RISC-V, MIPS and ARM models and with klitmus7 on
x86 are in

    https://github.com/brauner/linux-formal
    kernel/mount/gp-on-demand-proposal/litmus/

* patches from https://patch.msgid.link/20261011-work-mount-fixes-5-v1-0-a9b9a8ecf565@kernel.org:
  fs: drop the smp_mb()s that mnt_get_count() made redundant

Link: https://patch.msgid.link/20261011-work-mount-fixes-5-v1-0-a9b9a8ecf565@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:05 +02:00