Skip to content

Commit ee44a1d

Browse files
andy-shevlag-linaro
authored andcommitted
leds: core: Bail out when composed name can't fit the buffer
GCC compiler complains about snprintf() calls that may potentially cut the output: drivers/leds/led-core.c:551:78: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=] drivers/leds/led-core.c:554:78: error: ‘snprintf’ output may be truncated before the last format character [-Werror=format-truncation=] ... Fix these by checking for the potential overflow. This requires to align all the branches to use the same callee, i.e. snprintf(), otherwise the code will be blown up and return different error codes for the different branches. Signed-off-by: Andy Shevchenko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Lee Jones <[email protected]>
1 parent 06d99fc commit ee44a1d

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

drivers/leds/led-core.c

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ int led_compose_name(struct device *dev, struct led_init_data *init_data,
529529
struct led_properties props = {};
530530
struct fwnode_handle *fwnode = init_data->fwnode;
531531
const char *devicename = init_data->devicename;
532+
int n;
532533

533534
if (!led_classdev_name)
534535
return -EINVAL;
@@ -542,45 +543,49 @@ int led_compose_name(struct device *dev, struct led_init_data *init_data,
542543
* Otherwise the label is prepended with devicename to compose
543544
* the final LED class device name.
544545
*/
545-
if (!devicename) {
546-
strscpy(led_classdev_name, props.label,
547-
LED_MAX_NAME_SIZE);
546+
if (devicename) {
547+
n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
548+
devicename, props.label);
548549
} else {
549-
snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
550-
devicename, props.label);
550+
n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s", props.label);
551551
}
552552
} else if (props.function || props.color_present) {
553553
char tmp_buf[LED_MAX_NAME_SIZE];
554554

555555
if (props.func_enum_present) {
556-
snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s-%d",
557-
props.color_present ? led_colors[props.color] : "",
558-
props.function ?: "", props.func_enum);
556+
n = snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s-%d",
557+
props.color_present ? led_colors[props.color] : "",
558+
props.function ?: "", props.func_enum);
559559
} else {
560-
snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s",
561-
props.color_present ? led_colors[props.color] : "",
562-
props.function ?: "");
560+
n = snprintf(tmp_buf, LED_MAX_NAME_SIZE, "%s:%s",
561+
props.color_present ? led_colors[props.color] : "",
562+
props.function ?: "");
563563
}
564+
if (n >= LED_MAX_NAME_SIZE)
565+
return -E2BIG;
566+
564567
if (init_data->devname_mandatory) {
565-
snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
566-
devicename, tmp_buf);
568+
n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
569+
devicename, tmp_buf);
567570
} else {
568-
strscpy(led_classdev_name, tmp_buf, LED_MAX_NAME_SIZE);
569-
571+
n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s", tmp_buf);
570572
}
571573
} else if (init_data->default_label) {
572574
if (!devicename) {
573575
dev_err(dev, "Legacy LED naming requires devicename segment");
574576
return -EINVAL;
575577
}
576-
snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
577-
devicename, init_data->default_label);
578+
n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s:%s",
579+
devicename, init_data->default_label);
578580
} else if (is_of_node(fwnode)) {
579-
strscpy(led_classdev_name, to_of_node(fwnode)->name,
580-
LED_MAX_NAME_SIZE);
581+
n = snprintf(led_classdev_name, LED_MAX_NAME_SIZE, "%s",
582+
to_of_node(fwnode)->name);
581583
} else
582584
return -EINVAL;
583585

586+
if (n >= LED_MAX_NAME_SIZE)
587+
return -E2BIG;
588+
584589
return 0;
585590
}
586591
EXPORT_SYMBOL_GPL(led_compose_name);

0 commit comments

Comments
 (0)