* [PATCH] Input: i8042 - replace strlcat() with seq_buf and scnprintf()
@ 2026-07-07 6:04 Ian Bridges
0 siblings, 0 replies; only message in thread
From: Ian Bridges @ 2026-07-07 6:04 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, linux-kernel, linux-hardening
In preparation for removing the strlcat() API[1], replace its uses in
i8042-acpipnpio.h.
i8042_pnp_id_to_string() accumulates a variable number of PNP ids in
a loop, which is what seq_buf is for. The kbd and aux probe functions
build a name from at most three parts that are all known up front, so
the whole construction becomes a single scnprintf() there.
Link: https://github.com/KSPP/linux/issues/370 [1]
Signed-off-by: Ian Bridges <icb@fastmail.org>
---
scnprintf() is used rather than snprintf() because the name buffers
tolerate truncation by design and the builtin snprintf() triggers
-Wformat-truncation at W=1 for it. The output is unchanged in all
cases.
The possible truncation predates the patch. The name buffers hold 32
bytes, which is 31 characters plus a terminator. A full entry is a
7 character PNP id, a ':' separator, and up to 49 characters of PNP
device name, or 57 characters in the worst case. That leaves 23
characters for the device name, so a BIOS name longer than that is
cut short in the i8042 PNP console line. The old and the new code
truncate at the same point and produce the same bytes. Enlarging the
buffers would be a visible behavior change and is left for a separate
patch.
The patch was tested as follows:
- An x86_64 build of drivers/input/serio/i8042.o at W=1 produces no
warnings.
- A userspace comparison of the old and new construction ran with
randomized PNP id chains, device names, and buffer sizes. The
outputs were byte-identical in every case.
- Base and patched kernels were booted in QEMU, whose PS/2
controller exposes PNP0303 and PNP0F13 devices. The serio
firmware_id sysfs strings and the PS/2 controller console line are
identical before and after the change.
drivers/input/serio/i8042-acpipnpio.h | 27 ++++++++++++++-------------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h
index 412f82d7a303..9ecb0eed48c4 100644
--- a/drivers/input/serio/i8042-acpipnpio.h
+++ b/drivers/input/serio/i8042-acpipnpio.h
@@ -3,6 +3,7 @@
#define _I8042_ACPIPNPIO_H
#include <linux/acpi.h>
+#include <linux/seq_buf.h>
#ifdef CONFIG_X86
#include <asm/x86_init.h>
@@ -1479,17 +1480,21 @@ static char i8042_pnp_aux_name[32];
static void i8042_pnp_id_to_string(struct pnp_id *id, char *dst, int dst_size)
{
- strscpy(dst, "PNP:", dst_size);
+ struct seq_buf sb;
+
+ seq_buf_init(&sb, dst, dst_size);
+ seq_buf_printf(&sb, "PNP:");
while (id) {
- strlcat(dst, " ", dst_size);
- strlcat(dst, id->id, dst_size);
+ seq_buf_printf(&sb, " %s", id->id);
id = id->next;
}
}
static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
{
+ const char *name = pnp_dev_name(dev);
+
if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
i8042_pnp_data_reg = pnp_port_start(dev,0);
@@ -1499,11 +1504,8 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
if (pnp_irq_valid(dev,0))
i8042_pnp_kbd_irq = pnp_irq(dev, 0);
- strscpy(i8042_pnp_kbd_name, did->id, sizeof(i8042_pnp_kbd_name));
- if (strlen(pnp_dev_name(dev))) {
- strlcat(i8042_pnp_kbd_name, ":", sizeof(i8042_pnp_kbd_name));
- strlcat(i8042_pnp_kbd_name, pnp_dev_name(dev), sizeof(i8042_pnp_kbd_name));
- }
+ scnprintf(i8042_pnp_kbd_name, sizeof(i8042_pnp_kbd_name), "%s%s%s",
+ did->id, strlen(name) ? ":" : "", name);
i8042_pnp_id_to_string(dev->id, i8042_kbd_firmware_id,
sizeof(i8042_kbd_firmware_id));
i8042_kbd_fwnode = dev_fwnode(&dev->dev);
@@ -1517,6 +1519,8 @@ static int i8042_pnp_kbd_probe(struct pnp_dev *dev, const struct pnp_device_id *
static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *did)
{
+ const char *name = pnp_dev_name(dev);
+
if (pnp_port_valid(dev, 0) && pnp_port_len(dev, 0) == 1)
i8042_pnp_data_reg = pnp_port_start(dev,0);
@@ -1526,11 +1530,8 @@ static int i8042_pnp_aux_probe(struct pnp_dev *dev, const struct pnp_device_id *
if (pnp_irq_valid(dev, 0))
i8042_pnp_aux_irq = pnp_irq(dev, 0);
- strscpy(i8042_pnp_aux_name, did->id, sizeof(i8042_pnp_aux_name));
- if (strlen(pnp_dev_name(dev))) {
- strlcat(i8042_pnp_aux_name, ":", sizeof(i8042_pnp_aux_name));
- strlcat(i8042_pnp_aux_name, pnp_dev_name(dev), sizeof(i8042_pnp_aux_name));
- }
+ scnprintf(i8042_pnp_aux_name, sizeof(i8042_pnp_aux_name), "%s%s%s",
+ did->id, strlen(name) ? ":" : "", name);
i8042_pnp_id_to_string(dev->id, i8042_aux_firmware_id,
sizeof(i8042_aux_firmware_id));
--
2.47.3
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-07 6:04 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-07 6:04 [PATCH] Input: i8042 - replace strlcat() with seq_buf and scnprintf() Ian Bridges
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox