Commit 02ac3a9e authored by Takashi Iwai's avatar Takashi Iwai Committed by Greg Kroah-Hartman

parport: Proper fix for array out-of-bounds access

The recent fix for array out-of-bounds accesses replaced sprintf()
calls blindly with snprintf().  However, since snprintf() returns the
would-be-printed size, not the actually output size, the length
calculation can still go over the given limit.

Use scnprintf() instead of snprintf(), which returns the actually
output letters, for addressing the potential out-of-bounds access
properly.

Fixes: ab11dac9 ("dev/parport: fix the array out-of-bounds risk")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20240920103318.19271-1-tiwai@suse.deSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 7528cb0f
...@@ -51,12 +51,12 @@ static int do_active_device(const struct ctl_table *table, int write, ...@@ -51,12 +51,12 @@ static int do_active_device(const struct ctl_table *table, int write,
for (dev = port->devices; dev ; dev = dev->next) { for (dev = port->devices; dev ; dev = dev->next) {
if(dev == port->cad) { if(dev == port->cad) {
len += snprintf(buffer, sizeof(buffer), "%s\n", dev->name); len += scnprintf(buffer, sizeof(buffer), "%s\n", dev->name);
} }
} }
if(!len) { if(!len) {
len += snprintf(buffer, sizeof(buffer), "%s\n", "none"); len += scnprintf(buffer, sizeof(buffer), "%s\n", "none");
} }
if (len > *lenp) if (len > *lenp)
...@@ -87,19 +87,19 @@ static int do_autoprobe(const struct ctl_table *table, int write, ...@@ -87,19 +87,19 @@ static int do_autoprobe(const struct ctl_table *table, int write,
} }
if ((str = info->class_name) != NULL) if ((str = info->class_name) != NULL)
len += snprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str); len += scnprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str);
if ((str = info->model) != NULL) if ((str = info->model) != NULL)
len += snprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str); len += scnprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str);
if ((str = info->mfr) != NULL) if ((str = info->mfr) != NULL)
len += snprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str); len += scnprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str);
if ((str = info->description) != NULL) if ((str = info->description) != NULL)
len += snprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str); len += scnprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str);
if ((str = info->cmdset) != NULL) if ((str = info->cmdset) != NULL)
len += snprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str); len += scnprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str);
if (len > *lenp) if (len > *lenp)
len = *lenp; len = *lenp;
...@@ -128,7 +128,7 @@ static int do_hardware_base_addr(const struct ctl_table *table, int write, ...@@ -128,7 +128,7 @@ static int do_hardware_base_addr(const struct ctl_table *table, int write,
if (write) /* permissions prevent this anyway */ if (write) /* permissions prevent this anyway */
return -EACCES; return -EACCES;
len += snprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi); len += scnprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi);
if (len > *lenp) if (len > *lenp)
len = *lenp; len = *lenp;
...@@ -155,7 +155,7 @@ static int do_hardware_irq(const struct ctl_table *table, int write, ...@@ -155,7 +155,7 @@ static int do_hardware_irq(const struct ctl_table *table, int write,
if (write) /* permissions prevent this anyway */ if (write) /* permissions prevent this anyway */
return -EACCES; return -EACCES;
len += snprintf (buffer, sizeof(buffer), "%d\n", port->irq); len += scnprintf (buffer, sizeof(buffer), "%d\n", port->irq);
if (len > *lenp) if (len > *lenp)
len = *lenp; len = *lenp;
...@@ -182,7 +182,7 @@ static int do_hardware_dma(const struct ctl_table *table, int write, ...@@ -182,7 +182,7 @@ static int do_hardware_dma(const struct ctl_table *table, int write,
if (write) /* permissions prevent this anyway */ if (write) /* permissions prevent this anyway */
return -EACCES; return -EACCES;
len += snprintf (buffer, sizeof(buffer), "%d\n", port->dma); len += scnprintf (buffer, sizeof(buffer), "%d\n", port->dma);
if (len > *lenp) if (len > *lenp)
len = *lenp; len = *lenp;
...@@ -213,7 +213,7 @@ static int do_hardware_modes(const struct ctl_table *table, int write, ...@@ -213,7 +213,7 @@ static int do_hardware_modes(const struct ctl_table *table, int write,
#define printmode(x) \ #define printmode(x) \
do { \ do { \
if (port->modes & PARPORT_MODE_##x) \ if (port->modes & PARPORT_MODE_##x) \
len += snprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ len += scnprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \
} while (0) } while (0)
int f = 0; int f = 0;
printmode(PCSPP); printmode(PCSPP);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment