parse_hw_handler() builds the hw_handler parameter string in a buffer
sized with

        len = 4;

plus one byte per argument.  Those four bytes were meant for the decimal
form of the parameter count, three digits plus the terminating NUL.
dm_read_arg_group() accepts up to 1024 arguments and the count written is
'hw_argc - 1', so a count of 1000 or more needs four digits plus the NUL
and sprintf() writes one byte past the allocation.

Size the buffer from the actual string length instead.

Fixes: 2bfd2e1337f0 ("[SCSI] scsi_dh: Use scsi_dh_set_params() in multipath.")
Cc: [email protected]
Signed-off-by: Shao Mingyin <[email protected]>
---
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index ae9318f5f21b..2f871a23a8cb 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1085,8 +1085,9 @@ static int parse_hw_handler(struct dm_arg_set *as, struct 
multipath *m)
 
        if (hw_argc > 1) {
                char *p;
-               int i, j, len = 4;
+               int i, j, len;
 
+               len = snprintf(NULL, 0, "%d", hw_argc - 1) + 1;
                for (i = 0; i <= hw_argc - 2; i++)
                        len += strlen(as->argv[i]) + 1;
                p = m->hw_handler_params = kzalloc(len, GFP_KERNEL);

Reply via email to