Skip to contentSkip to conversation

nvmet: filter newlines from user input

PATCH Superseded Sagi Grimberg 3 participants 4 messages Jun 6, 2018

Subsystems (2)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Sagi Grimberg

author maintainer
#0 lore raw

PATCH v2 1/1 nvmet: filter newlines from user input

We should avoid consuming the newlines in traddr, trsvcid and device_path. Add minimal processing to make sure they are gone.

Signed-off-by Sagi Grimberg <sagi at grimberg.me>

---
Changes from v1:
- use sscanf instead of kstrdup+strsep for traddr and trsvcid

 drivers/nvme/target/configfs.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)
drivers/nvme/target/configfs.c +18 -6
index fd93c6a122d5..ad57c2cd40a1 100644
@@ -126,6 +126,7 @@ static ssize_t nvmet_addr_traddr_store(struct config_item *item,
 		const char *page, size_t count)
 {
 	struct nvmet_port *port = to_nvmet_port(item);
+	int ret;
 
 	if (count > NVMF_TRADDR_SIZE) {
 		pr_err("Invalid value '%s' for traddr\n", page);
@@ -137,8 +138,12 @@ static ssize_t nvmet_addr_traddr_store(struct config_item *item,
 		pr_err("Disable the address before modifying\n");
 		return -EACCES;
 	}
-	return snprintf(port->disc_addr.traddr,
-			sizeof(port->disc_addr.traddr), "%s", page);
+
+	ret = sscanf(page, "%s\n", port->disc_addr.traddr);
+	if (ret < 1)
+		return -EINVAL;
+
+	return count;
 }
 
 CONFIGFS_ATTR(nvmet_, addr_traddr);
@@ -213,6 +218,7 @@ static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
 		const char *page, size_t count)
 {
 	struct nvmet_port *port = to_nvmet_port(item);
+	int ret;
 
 	if (count > NVMF_TRSVCID_SIZE) {
 		pr_err("Invalid value '%s' for trsvcid\n", page);
@@ -223,8 +229,12 @@ static ssize_t nvmet_addr_trsvcid_store(struct config_item *item,
 		pr_err("Disable the address before modifying\n");
 		return -EACCES;
 	}
-	return snprintf(port->disc_addr.trsvcid,
-			sizeof(port->disc_addr.trsvcid), "%s", page);
+
+	ret = sscanf(page, "%s\n", port->disc_addr.trsvcid);
+	if (ret < 1)
+		return -EINVAL;
+
+	return count;
 }
 
 CONFIGFS_ATTR(nvmet_, addr_trsvcid);
@@ -303,6 +313,7 @@ static ssize_t nvmet_ns_device_path_store(struct config_item *item,
 {
 	struct nvmet_ns *ns = to_nvmet_ns(item);
 	struct nvmet_subsys *subsys = ns->subsys;
+	char *s;
 	int ret;
 
 	mutex_lock(&subsys->lock);
@@ -313,10 +324,11 @@ static ssize_t nvmet_ns_device_path_store(struct config_item *item,
 	kfree(ns->device_path);
 
 	ret = -ENOMEM;
-	ns->device_path = kstrdup(page, GFP_KERNEL);
-	if (!ns->device_path)
+	s = kstrdup(page, GFP_KERNEL);
+	if (!s)
 		goto out_unlock;
 
+	ns->device_path = strsep(&s, "\n");
 	mutex_unlock(&subsys->lock);
 	return count;
 
Signature · 1 line
2.14.1
#1 lore raw

PATCH v2 1/1 nvmet: filter newlines from user input

Looks good,
Reviewed-by: Johannes Thumshirn <jthumshirn at suse.de>

Signature · 6 lines
Johannes Thumshirn                                          Storage
jthumshirn at suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N?rnberg
GF: Felix Imend?rffer, Jane Smithard, Graham Norton
HRB 21284 (AG N?rnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850
#2 lore raw

PATCH v2 1/1 nvmet: filter newlines from user input

In reply to Sagi Grimberg

drivers/nvme/target/configfs.c static ssize_t nvmet_addr_traddr_store(struct config_item *item, · line 146

Quoted 5 lines
drivers/nvme/target/configfs.c +5 -0
+	ret = sscanf(page, "%s\n", port->disc_addr.traddr);
+	if (ret < 1)
+		return -EINVAL;
+
+	return count;

I think this should be:

	if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1))
		return -EINVAL;
	return count;

Same for the other instances.

drivers/nvme/target/configfs.c static ssize_t nvmet_ns_device_path_store(struct config_item *item, · line 331

Quoted 8 lines
drivers/nvme/target/configfs.c +3 -2
 	ret = -ENOMEM;
-	ns->device_path = kstrdup(page, GFP_KERNEL);
-	if (!ns->device_path)
+	s = kstrdup(page, GFP_KERNEL);
+	if (!s)
 		goto out_unlock;
 
+	ns->device_path = strsep(&s, "\n");

I'd just go for something like

	ns->device_path = kstrndup(page, strcspn(page, "\n"), GFP_KERNEL);
author maintainer
#3 lore raw

PATCH v2 1/1 nvmet: filter newlines from user input

Quoted 22 lines

drivers/nvme/target/configfs.c static ssize_t nvmet_addr_traddr_store(struct config_item *item, · line 146

Quoted 6 lines
drivers/nvme/target/configfs.c +5 -0
+	ret = sscanf(page, "%s\n", port->disc_addr.traddr);
+	if (ret < 1)
+		return -EINVAL;
+
+	return count;

I think this should be:

	if (sscanf(page, "%s\n", port->disc_addr.traddr) != 1))
		return -EINVAL;
	return count;

Same for the other instances.

Quoted 7 lines
  	ret = -ENOMEM;
drivers/nvme/target/configfs.c +2 -2
-	ns->device_path = kstrdup(page, GFP_KERNEL);
-	if (!ns->device_path)
+	s = kstrdup(page, GFP_KERNEL);
+	if (!s)
  		goto out_unlock;
Quoted 6 lines

drivers/nvme/target/configfs.c static ssize_t nvmet_ns_device_path_store(struct config_item *item, · line 331

Quoted 1 line
drivers/nvme/target/configfs.c +1 -0
+	ns->device_path = strsep(&s, "\n");

I'd just go for something like

	ns->device_path = kstrndup(page, strcspn(page, "\n"), GFP_KERNEL);

Thanks for the suggestions. sending v3