Skip to content

Commit

Permalink
ACPI: battery: Fix buffer overread if not NUL-terminated
Browse files Browse the repository at this point in the history
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 <W_Armin@gmx.de>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  • Loading branch information
Armin Wolf authored and Rafael J. Wysocki committed Jan 30, 2023
1 parent f2ac14b commit a1a32de
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions drivers/acpi/battery.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,16 +437,25 @@ static int extract_package(struct acpi_battery *battery,
element = &package->package.elements[i];
if (offsets[i].mode) {
u8 *ptr = (u8 *)battery + offsets[i].offset;
u32 len = 32;

if (element->type == ACPI_TYPE_STRING ||
element->type == ACPI_TYPE_BUFFER)
strscpy(ptr, element->string.pointer, 32);
else if (element->type == ACPI_TYPE_INTEGER) {
strncpy(ptr, (u8 *)&element->integer.value,
sizeof(u64));
ptr[sizeof(u64)] = 0;
} else
switch (element->type) {
case ACPI_TYPE_BUFFER:
if (len > element->buffer.length + 1)
len = element->buffer.length + 1;

fallthrough;
case ACPI_TYPE_STRING:
strscpy(ptr, element->string.pointer, len);

break;
case ACPI_TYPE_INTEGER:
strscpy(ptr, (u8 *)&element->integer.value, sizeof(u64) + 1);

break;
default:
*ptr = 0; /* don't have value */
}
} else {
int *x = (int *)((u8 *)battery + offsets[i].offset);
*x = (element->type == ACPI_TYPE_INTEGER) ?
Expand Down

0 comments on commit a1a32de

Please sign in to comment.