[PATCH v4 00/10] nvmem: rework nvmem core and allow unbinding with active consumers

Bartosz Golaszewski posted 10 patches 3 days, 5 hours ago
drivers/nvmem/core.c      | 319 ++++++++++++++++++++++++----------------------
drivers/nvmem/internals.h |  13 +-
2 files changed, 178 insertions(+), 154 deletions(-)
[PATCH v4 00/10] nvmem: rework nvmem core and allow unbinding with active consumers
Posted by Bartosz Golaszewski 3 days, 5 hours ago
Sashiko pointed out some issues so this iteration fixes them. I'm also
Cc'ing Loic who seems to have encountered the issue of unbinding with
active consumers when working on the block nvmem provider.

Nvmem is one of the subsystems vulnerable to object life-time issues.
The memory nvmem core dereferences is owned by nvmem providers which can
be unbound at any time and even though nvmem devices themselves are
reference-counted, there's no synchronization with the provider modules.

This typically is not a problem because thanks to fw_devlink, consumers
get synchronously unbound before providers but it's enough to pass
fw_devlink=off over the command line, unbind the nvmem controller with
consumers still holding references to it and try to read/write in order
to see fireworks in the kernel log.

User-space can trigger it too if a device (for instance: i2c eeprom on a
cp2112 USB expander) is unplugged halfway through a long read.

This series proposes to use SRCU to protect nvmem against accessing
invalid memory after unbinding with active consumers and also reworks
several places in nvmem core.

The first patch is a fix that should land in v7.1, the rest is v7.2
material.

Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
---
Changes in v4:
- Restore the removed checks for the existence of reg_write/reg_read
  ops in sysfs callbacks as the attributes may be created with only a
  single operation available
- Fix potential use-after-free when decrementing the references to nvmem
  device
- Rename some local variables to better indicate their function
- Initialize the cell list before calling device_initialize() as we
  iterate over it in release path unconditionally
- Restore the nvmem != NULL check in nvmem_unregister() as sashiko
  pointed out there are users who rely on this API contract
- Don't use rcu_dereference() with SRCU as it may trigger a
  false-positive lockdep alert
- Synchronize the removal of nvmem->ops in error path in
  nvmem_register() as it's possible for it to be made available to the
  system before a subsequent failure later in the function
- Link to v3: https://patch.msgid.link/20260429-nvmem-unbind-v3-0-2a694f95395b@oss.qualcomm.com

Changes in v3:
- Add Fixes tag to patch 1
- Don't check the presence of read/write callbacks in sysfs attributes
  as these are not visible without them
- Rework mutex guards and drop unneeded helper variables
- Fix mutex guard conversion: it accidentally converted nvmem_lookup_mutex
  locks to nvmem_mutex
- Extend patch 5 to also rename __nvmem_device_get() to
  nvmem_device_match()
- Call nvmem_sysfs_remove_compat() on unregister, not release
- Split patch 7 into two: one removing the redundant kref and second
  adding SRCU
- Link to v2: https://patch.msgid.link/20260223-nvmem-unbind-v2-0-0df33a933dca@oss.qualcomm.com

Changes in v2:
- add missing SRCU struct cleanup
- improve the teardown path on error in nvmem_register()
- Link to v1: https://lore.kernel.org/r/20260116-nvmem-unbind-v1-0-7bb401ab19a8@oss.qualcomm.com

---
Bartosz Golaszewski (10):
      nvmem: core: fix use-after-free bugs in error paths
      nvmem: remove unused field from struct nvmem_device
      nvmem: return -EOPNOTSUPP to in-kernel users on missing callbacks
      nvmem: check the return value of gpiod_set_value_cansleep()
      nvmem: simplify locking with guard()
      nvmem: remove unneeded __nvmem_device_put()
      nvmem: split out the reg_read/write() callbacks out of struct nvmem_device
      nvmem: simplify nvmem_sysfs_remove_compat()
      nvmem: remove duplicated reference counting
      nvmem: protect nvmem_device::ops with SRCU

 drivers/nvmem/core.c      | 319 ++++++++++++++++++++++++----------------------
 drivers/nvmem/internals.h |  13 +-
 2 files changed, 178 insertions(+), 154 deletions(-)
---
base-commit: 7d9ebe5c8b1bd9f6ae73b47929761cd9a6287407
change-id: 20260114-nvmem-unbind-673b52fc84a0

Best regards,
-- 
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>