[PATCH] mmc: block: check mmc_blk_get() in the sysfs callbacks
From: shao.mingyin
Date: Tue Nov 03 2026 - 06:20:20 EST
power_ro_lock_show(), power_ro_lock_store(), force_ro_show() and
force_ro_store() dereference the result of mmc_blk_get() without checking
it. mmc_blk_get() uses kref_get_unless_zero() and returns NULL once
mmc_blk_kref_release() has run; an already open sysfs attribute can still
invoke these callbacks after del_gendisk(), for example.
Other entry points in this file (mmc_blk_ioctl(),
mmc_blk_alternative_gpt_sector()) already handle a NULL return. Do the
same here.
Fixes: add710eaa886 ("mmc: boot partition ro lock support")
Signed-off-by: Shao Mingyin <shao.mingyin@xxxxxxxxxx>
---
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index a02bb2fee874..a1e942435575 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -235,9 +235,14 @@ static ssize_t power_ro_lock_show(struct device *dev,
{
int ret;
struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
- struct mmc_card *card = md->queue.card;
+ struct mmc_card *card;
int locked = 0;
+ if (!md)
+ return -EINVAL;
+
+ card = md->queue.card;
+
if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PERM_WP_EN)
locked = 2;
else if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_EN)
@@ -266,6 +271,9 @@ static ssize_t power_ro_lock_store(struct device *dev,
return count;
md = mmc_blk_get(dev_to_disk(dev));
+ if (!md)
+ return -EINVAL;
+
mq = &md->queue;
/* Dispatch locking to the block layer */
@@ -305,6 +313,9 @@ static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,
int ret;
struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+ if (!md)
+ return -EINVAL;
+
ret = sysfs_emit(buf, "%d\n",
get_disk_ro(dev_to_disk(dev)) ^
md->read_only);
@@ -319,6 +330,9 @@ static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr,
struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
unsigned long set;
+ if (!md)
+ return -EINVAL;
+
if (kstrtoul(buf, 0, &set)) {
ret = -EINVAL;
goto out;