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 <[email protected]> --- 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

