target: fix PR state file path truncation
authorDavid Disseldorp <ddiss@suse.de>
Wed, 18 Oct 2017 23:39:19 +0000 (01:39 +0200)
committerNicholas Bellinger <nab@linux-iscsi.org>
Sat, 4 Nov 2017 22:00:17 +0000 (15:00 -0700)
If an LIO backstore is configured with a sufficiently long Unit Serial
string, alongside a similarly long dbroot path, then a truncated
Persistent Reservation APTPL state file path will be used. This
truncation can unintentionally lead to two LUs with differing serial
numbers sharing PR state file.

Fixes: fdddf932269a ("target: use new "dbroot" target attribute")
Signed-off-by: David Disseldorp <ddiss@suse.de>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
drivers/target/target_core_pr.c

index a5449070981101aa0d7566c519a28bfad1a756c2..3d2b46472dfdc7147844afa24267284ec81ae606 100644 (file)
@@ -1973,24 +1973,21 @@ static int __core_scsi3_write_aptpl_to_file(
        struct t10_wwn *wwn = &dev->t10_wwn;
        struct file *file;
        int flags = O_RDWR | O_CREAT | O_TRUNC;
-       char path[512];
+       char *path;
        u32 pr_aptpl_buf_len;
        int ret;
        loff_t pos = 0;
 
-       memset(path, 0, 512);
-
-       if (strlen(&wwn->unit_serial[0]) >= 512) {
-               pr_err("WWN value for struct se_device does not fit"
-                       " into path buffer\n");
-               return -EMSGSIZE;
-       }
+       path = kasprintf(GFP_KERNEL, "%s/pr/aptpl_%s", db_root,
+                       &wwn->unit_serial[0]);
+       if (!path)
+               return -ENOMEM;
 
-       snprintf(path, 512, "%s/pr/aptpl_%s", db_root, &wwn->unit_serial[0]);
        file = filp_open(path, flags, 0600);
        if (IS_ERR(file)) {
                pr_err("filp_open(%s) for APTPL metadata"
                        " failed\n", path);
+               kfree(path);
                return PTR_ERR(file);
        }
 
@@ -2001,6 +1998,7 @@ static int __core_scsi3_write_aptpl_to_file(
        if (ret < 0)
                pr_debug("Error writing APTPL metadata file: %s\n", path);
        fput(file);
+       kfree(path);
 
        return (ret < 0) ? -EIO : 0;
 }