Skip to content

Commit a1a32de

Browse files
Wer-Wolfrafaeljw
authored andcommitted
ACPI: battery: Fix buffer overread if not NUL-terminated
If a buffer containing ASCII characters is not NUL-terminated (which is perfectly legal according to the ACPI specification), the ACPI battery driver might not honor its length. Fix this by limiting the amount of data to be copied to the buffer length while also using strscpy() to make sure that the resulting string is always NUL-terminated. Also replace strncpy() vs strscpy(). Signed-off-by: Armin Wolf <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent f2ac14b commit a1a32de

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

drivers/acpi/battery.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -437,16 +437,25 @@ static int extract_package(struct acpi_battery *battery,
437437
element = &package->package.elements[i];
438438
if (offsets[i].mode) {
439439
u8 *ptr = (u8 *)battery + offsets[i].offset;
440+
u32 len = 32;
440441

441-
if (element->type == ACPI_TYPE_STRING ||
442-
element->type == ACPI_TYPE_BUFFER)
443-
strscpy(ptr, element->string.pointer, 32);
444-
else if (element->type == ACPI_TYPE_INTEGER) {
445-
strncpy(ptr, (u8 *)&element->integer.value,
446-
sizeof(u64));
447-
ptr[sizeof(u64)] = 0;
448-
} else
442+
switch (element->type) {
443+
case ACPI_TYPE_BUFFER:
444+
if (len > element->buffer.length + 1)
445+
len = element->buffer.length + 1;
446+
447+
fallthrough;
448+
case ACPI_TYPE_STRING:
449+
strscpy(ptr, element->string.pointer, len);
450+
451+
break;
452+
case ACPI_TYPE_INTEGER:
453+
strscpy(ptr, (u8 *)&element->integer.value, sizeof(u64) + 1);
454+
455+
break;
456+
default:
449457
*ptr = 0; /* don't have value */
458+
}
450459
} else {
451460
int *x = (int *)((u8 *)battery + offsets[i].offset);
452461
*x = (element->type == ACPI_TYPE_INTEGER) ?

0 commit comments

Comments
 (0)