From ac88c1f6730e73771dc36b9fd83804e7aa15941a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 17 Jun 2019 08:18:18 -0700 Subject: [PATCH] scsi: Restrict user space SCSI device state changes to "running" and "offline" The ability to modify the SCSI device state was introduced by commit 638127e579a4 ("[PATCH] Fix error handler offline behaviour"; v2.6.12). That same commit introduced the following device states: { SDEV_CREATED, "created" }, { SDEV_RUNNING, "running" }, { SDEV_CANCEL, "cancel" }, { SDEV_DEL, "deleted" }, { SDEV_QUIESCE, "quiesce" }, { SDEV_OFFLINE, "offline" }, The SDEV_BLOCK state was introduced later to avoid that an FC cable pull would immediately result in an I/O error (commit 1094e682310e; "[PATCH] suspending I/Os to a device"; v2.6.12). That same patch introduced the ability to set the SDEV_BLOCK state from user space. I'm not sure whether that ability was introduced on purpose or accidentally. Since there is agreement that only writing "running" or "offline" into the SCSI sysfs device state attribute makes sense, restrict sysfs writes to these values. This patch makes sure that SDEV_BLOCK is only used for its original purpose, namely to allow transport drivers and LLDs to block further .queuecommand() calls while transport layer or adapter recovery is in progress. Note: a web search for "/sys/class/scsi_device" AND "device/state" revealed several storage configuration guides. The instructions I found in these guides tell users to write the value "running" or "offline" in the SCSI device state sysfs attribute and no other values. [mkp: typo] Cc: Christoph Hellwig Cc: Ming Lei Cc: Hannes Reinecke Cc: Johannes Thumshirn Cc: James Smart Cc: Ewan D. Milne Cc: Laurence Oberman Signed-off-by: Bart Van Assche Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/scsi_sysfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index ff0aea7..8b4fc2d 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -767,8 +767,13 @@ store_state_field(struct device *dev, struct device_attribute *attr, break; } } - if (!state) + switch (state) { + case SDEV_RUNNING: + case SDEV_OFFLINE: + break; + default: return -EINVAL; + } mutex_lock(&sdev->state_mutex); ret = scsi_device_set_state(sdev, state); -- 2.7.4