parport: Proper fix for array out-of-bounds access
commit 02ac3a9ef3a18b58d8f3ea2b6e46de657bf6c4f9 upstream.
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: ab11dac93d2d ("dev/parport: fix the array out-of-bounds risk")
Cc: stable@vger.kernel.org
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20240920103318.19271-1-tiwai@suse.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
20cc2b146a
commit
8aadef73ba
@@ -51,12 +51,12 @@ static int do_active_device(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(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(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;
|
||||||
@@ -156,7 +156,7 @@ static int do_hardware_irq(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;
|
||||||
@@ -184,7 +184,7 @@ static int do_hardware_dma(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;
|
||||||
@@ -216,7 +216,7 @@ static int do_hardware_modes(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);
|
||||||
|
|||||||
Reference in New Issue
Block a user