mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
PCI/sysfs: Pass the device name length in UTF-16 code units
Currently, dsm_label_utf16s_to_utf8s() passes the ACPI buffer length to
utf16s_to_utf8s() unchanged. The Device Name _DSM may return the device
name as a buffer holding a UTF-16 string, and the ACPI length counts bytes
while the converter counts wchar_t elements. The converter therefore
receives a count twice the number of code units the buffer holds, and that
count is its only bound on the input.
A NUL code unit ends the conversion early, so a name that carries one is
converted correctly and the error stays hidden. ACPICA zeroes the entire
result allocation, and the padding placed after the buffer supplies that
NUL for most lengths. Lengths that leave no padding, or a single byte of
it, do not, and the conversion then runs up to its own length in bytes past
the end of the allocation. The bytes beyond the allocation are decoded
into the "label" attribute, which is world readable.
Divide the buffer length by the size of wchar_t so that the converter
receives a count of code units. The division truncates, so the converter
is never told to read more bytes than the buffer holds, including for an
odd length.
Reaching the out of bounds read needs firmware that returns the name as a
buffer and omits the terminator.
Fixes: 6058989bad ("PCI: Export ACPI _DSM provided firmware instance number and string name to sysfs")
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260814070522.2327975-5-kwilczynski@kernel.org
This commit is contained in:
parent
1832dc1579
commit
af5ca2d751
|
|
@ -144,7 +144,7 @@ static int dsm_label_utf16s_to_utf8s(union acpi_object *obj, char *buf)
|
|||
int len;
|
||||
|
||||
len = utf16s_to_utf8s((const wchar_t *)obj->buffer.pointer,
|
||||
obj->buffer.length,
|
||||
obj->buffer.length / sizeof(wchar_t),
|
||||
UTF16_LITTLE_ENDIAN,
|
||||
buf, PAGE_SIZE - 1);
|
||||
buf[len++] = '\n';
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user