Message ID | 20240208084512.3803250-6-lee@kernel.org |
---|---|
State | New |
Headers | show |
Series | scsi: Replace {v}snprintf() variants with safer alternatives | expand |
On Thu, Feb 08, 2024 at 08:44:17AM +0000, Lee Jones wrote: > There is a general misunderstanding amongst engineers that {v}snprintf() > returns the length of the data *actually* encoded into the destination > array. However, as per the C99 standard {v}snprintf() really returns > the length of the data that *would have been* written if there were > enough space for it. This misunderstanding has led to buffer-overruns > in the past. It's generally considered safer to use the {v}scnprintf() > variants in their place (or even sprintf() in simple cases). So let's > do that. > > Link: https://lwn.net/Articles/69419/ > Link: https://github.com/KSPP/linux/issues/105 > Signed-off-by: Lee Jones <lee@kernel.org> > --- > Cc: Adaptec OEM Raid Solutions <aacraid@microsemi.com> > Cc: "James E.J. Bottomley" <jejb@linux.ibm.com> > Cc: "Martin K. Petersen" <martin.petersen@oracle.com> > Cc: "PMC-Sierra, Inc" <aacraid@pmc-sierra.com> > Cc: linux-scsi@vger.kernel.org > --- > drivers/scsi/aacraid/linit.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c > index 69526e2bd2e78..0e47d9c4cff23 100644 > --- a/drivers/scsi/aacraid/linit.c > +++ b/drivers/scsi/aacraid/linit.c > @@ -583,7 +583,7 @@ static ssize_t aac_show_unique_id(struct device *dev, > if (sdev_channel(sdev) == CONTAINER_CHANNEL) > memcpy(sn, aac->fsa_dev[sdev_id(sdev)].identifier, sizeof(sn)); > > - return snprintf(buf, 16 * 2 + 2, > + return scnprintf(buf, 16 * 2 + 2, > "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", > sn[0], sn[1], sn[2], sn[3], > sn[4], sn[5], sn[6], sn[7], I'm confused about this conversion and the original size argument. Isn't this also a sysfs entry? Size should be PAGE_SIZE, or it should be replaced with sysfs_emit(). -Kees > @@ -1302,13 +1302,13 @@ static ssize_t aac_show_serial_number(struct device *device, > int len = 0; > > if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0) > - len = snprintf(buf, 16, "%06X\n", > + len = scnprintf(buf, 16, "%06X\n", > le32_to_cpu(dev->adapter_info.serial[0])); > if (len && > !memcmp(&dev->supplement_adapter_info.mfg_pcba_serial_no[ > sizeof(dev->supplement_adapter_info.mfg_pcba_serial_no)-len], > buf, len-1)) > - len = snprintf(buf, 16, "%.*s\n", > + len = scnprintf(buf, 16, "%.*s\n", > (int)sizeof(dev->supplement_adapter_info.mfg_pcba_serial_no), > dev->supplement_adapter_info.mfg_pcba_serial_no); > > -- > 2.43.0.594.gd9cf4e227d-goog > >
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 69526e2bd2e78..0e47d9c4cff23 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -583,7 +583,7 @@ static ssize_t aac_show_unique_id(struct device *dev, if (sdev_channel(sdev) == CONTAINER_CHANNEL) memcpy(sn, aac->fsa_dev[sdev_id(sdev)].identifier, sizeof(sn)); - return snprintf(buf, 16 * 2 + 2, + return scnprintf(buf, 16 * 2 + 2, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X\n", sn[0], sn[1], sn[2], sn[3], sn[4], sn[5], sn[6], sn[7], @@ -1302,13 +1302,13 @@ static ssize_t aac_show_serial_number(struct device *device, int len = 0; if (le32_to_cpu(dev->adapter_info.serial[0]) != 0xBAD0) - len = snprintf(buf, 16, "%06X\n", + len = scnprintf(buf, 16, "%06X\n", le32_to_cpu(dev->adapter_info.serial[0])); if (len && !memcmp(&dev->supplement_adapter_info.mfg_pcba_serial_no[ sizeof(dev->supplement_adapter_info.mfg_pcba_serial_no)-len], buf, len-1)) - len = snprintf(buf, 16, "%.*s\n", + len = scnprintf(buf, 16, "%.*s\n", (int)sizeof(dev->supplement_adapter_info.mfg_pcba_serial_no), dev->supplement_adapter_info.mfg_pcba_serial_no);
There is a general misunderstanding amongst engineers that {v}snprintf() returns the length of the data *actually* encoded into the destination array. However, as per the C99 standard {v}snprintf() really returns the length of the data that *would have been* written if there were enough space for it. This misunderstanding has led to buffer-overruns in the past. It's generally considered safer to use the {v}scnprintf() variants in their place (or even sprintf() in simple cases). So let's do that. Link: https://lwn.net/Articles/69419/ Link: https://github.com/KSPP/linux/issues/105 Signed-off-by: Lee Jones <lee@kernel.org> --- Cc: Adaptec OEM Raid Solutions <aacraid@microsemi.com> Cc: "James E.J. Bottomley" <jejb@linux.ibm.com> Cc: "Martin K. Petersen" <martin.petersen@oracle.com> Cc: "PMC-Sierra, Inc" <aacraid@pmc-sierra.com> Cc: linux-scsi@vger.kernel.org --- drivers/scsi/aacraid/linit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)