#1148364 riscv64: strnlen() returns a truncated length for very large count, breaking ACPI name resolution (AE_AML_NAME_NOT_FOUND flood at boot)

#1148364#5
Date:
2026-09-19 08:49:01 UTC
From:
To:
Dear maintainers,

arch/riscv/lib/strnlen.S has an integer-overflow bug: for a very large `count` (in practice `(size_t)-1`) the address computation `s + count` wraps around 2^64, the loop bound becomes smaller than the start address, and strnlen() returns a length derived only from the first machine word(typically 8).  The same wrap exists in the byte-loop fallback.

This silently breaks any call site that the compiler lowers to `strnlen(p, SIZE_MAX)`, which GCC does when expanding strlen()/strcat() (or their fortified forms).  The most visible victim is ACPICA:

  drivers/acpi/acpica/exnames.c, acpi_ex_name_segment():
      strcat(name_string, char_buf);

is compiled to `memcpy(dest + strnlen(dest, SIZE_MAX), src, ...)`.  As soon as an accumulating ACPI name exceeds 8 characters, each following 4-byte
NameSeg is written at offset 8 and clobbers the previous segment.

Observed on a SpacemiT V100 (riscv64, rv64gc + Zbb) running 7.1.13+deb14-riscv64.  During early boot, from ~9 s to ~38 s after boot, hundreds of ACPI errors are logged.  Two distinct name-resolution failures
repeat: one per PCI root port (\_SB.PCxx.RP0.PCID._STA) and one for the generic-event devices (\_SB.GHP0/_SB.GHP1._CRS).

Representative error chains (timestamps kept; addresses shown because no_hash_pointers was enabled for capture — a plain boot prints (____ptrval____) instead):

    [    9.200960] ACPI Warning: Invalid character(s) in name (0x00000054) ffffbb810477b50b, repaired: [T___] (20251212/utstring-171)
    [    9.200975] ACPI Warning: Invalid character(s) in name (0x00000000) ffffbb810477b510, repaired: [____] (20251212/utstring-171)
    [    9.200992] Failure resolving symbol [\_SB.PSTA.T._], AE_AML_NAME_NOT_FOUND (20251212/dsutils-548)
    [    9.201045] ACPI Error: Aborting method \_SB.PC00.RP0.PCID._STA due to previous error (AE_AML_NAME_NOT_FOUND) (20251212/psparse-529)
    [    9.227771] Method execution failed \_SB.PC00.RP0.PCID._STA due to previous error (AE_AML_NAME_NOT_FOUND) (20251212/uteval-68)

    [   22.031086] ACPI Warning: Invalid character(s) in name (0x00000042) ffffbb8105fc65db, repaired: [B___] (20251212/utstring-171)
    [   22.031103] Failure resolving symbol [\_SB.SGS.B], AE_AML_NAME_NOT_FOUND (20251212/dsutils-548)
    [   22.031149] ACPI Error: Aborting method \_SB.GHP0._CRS due to previous error (AE_AML_NAME_NOT_FOUND) (20251212/psparse-529)
    [   22.095501] Method execution failed \_SB.GHP0._CRS due to previous error (AE_AML_NAME_NOT_FOUND) (20251212/uteval-68)

These lines repeat for each of the 16 PCI root ports that have an RP0 (PC00-PC05, PC0A-PC0F, PC10-PC14) and for GHP0/GHP1.  Counts from one capture (ACPICA debug enabled, counts are timing-dependent; a plain boot
shows the same pattern, roughly 300 "Failure resolving symbol" lines):

    Failure resolving symbol [\_SB.PSTA.T._]     285
    Failure resolving symbol [\_SB.SGS.B]         14
    Invalid character(s) in name (0x00000054)    285   ('T')
    Invalid character(s) in name (0x00000000)    285   (NUL)
    Invalid character(s) in name (0x00000042)     14   ('B')
    Aborting method \_SB.PC00/01/.../14.RP0.PCID._STA    (26/26/25/25/25/12...)
    Aborting method \_SB.GHP0._CRS                  7
    Aborting method \_SB.GHP1._CRS                  7

The reference in the platform SSDT `\_SB.PC00.RP0.STAT` is built as
`\_SB.PSTAT` (hence the corrupted log name `\_SB.PSTA.T._`), and
`\_SB.SMSI._GSB` as `\_SB.SGS.B`, so acpi_ns_lookup() fails on the second
name segment.  The same firmware + ACPI tables work fine on Ubuntu 7.0.0
and with userspace acpiexec, so the tables and ACPICA logic are correct.

REPRODUCTION

On the running kernel, a module that calls the exported strnlen() directly:

    static size_t (*p_strnlen)(const char *, size_t);
    static char big[64];                 /* 63 x 'A' + NUL, @ 0xffffffff067fb010 */

    p_strnlen(big, 1000);       /* -> 63   correct */
    p_strnlen(big, 1UL << 32);  /* ->  8   WRONG (expected 63) */
    p_strnlen(big, 1UL << 60);  /* ->  8   WRONG */
    p_strnlen(big, (size_t)-1); /* ->  8   WRONG */

The measured threshold matches the wrap model exactly: with s = 0xffffffff067fb010, the first overflowing count is 2^64 - s =
0xf9804ff0 (~4.19e9); 2^32 = 0x100000000 just exceeds it, 1000 does not.

Calling the running kernel's acpi_ex_get_name_string() with the exact AML bytes from the SSDT reproduces the corruption (status=AE_OK, full length):

    input  5c 2f 04 _SB_ PC00 RP0_ STAT 0a  ->  \/\x04_SB_PSTAT   (len 19)
    input  5c 2f 03 _SB_ SMSI _GSB 0a       ->  \/\x03_SB_S_GSB    (len 15)

CAUSE

arch/riscv/lib/strnlen.S:

    /* Aligned boundary.  Use the address of the last valid byte
     * (s + count - 1) to avoid loading a word past the count
     * boundary in the loop below.  count == 0 is handled above.
     */
    add     t4, a0, a1          # wraps for huge count
    addi    t4, t4, -1
    andi    t4, t4, -SZREG
    ...
    bgeu    t0, t4, 2f          # bails out with first-word-only result

and the byte-loop fallback:

    add     t2, a0, a1          # wraps for huge count

The "last valid byte" optimization did not guard against the address wrap.

Thanks,

This message and any attachment are confidential and may be privileged or otherwise protected from disclosure. If you are not an intended recipient of this message, please delete it and any attachment from your system and notify the sender immediately by reply e-mail. Unintended recipients should not use, copy, disclose or take any action based on this message or any information contained in this message. Emails cannot be guaranteed to be secure or error free as they can be intercepted, amended, lost or destroyed, and you should take full responsibility for security checking.

本邮件及其任何附件具有保密性质,并可能受其他保护或不允许被披露给第三方。如阁下误收到本邮件,敬请立即以回复电子邮件的方式通知发件人,并将本邮件及其任何附件从阁下系统中予以删除。如阁下并非本邮件写明之收件人,敬请切勿使用、复制、披露本邮件或其任何内容,亦请切勿依本邮件或其任何内容而采取任何行动。电子邮件无法保证是一种安全和不会出现任何差错的通信方式,可能会被拦截、修改、丢失或损坏,收件人需自行负责做好安全检查。

#1148364#10
Date:
2026-09-19 09:50:04 UTC
From:
To:
control: forwarded -1 https://lore.kernel.org/all/20260915152656708z04s4oSYY2BGj34F36RZa@zte.com.cn/
control: forcemerge -1 1148365

Hi,

The issue has been reported upstream with a patch [1], but it is still
under review. If you can test it and send a Tested-by: that would help
the patch to get accepted faster.

It will get added to the debian kernel once it get fixed upstream.

Regards
Aurelien

[1] https://lore.kernel.org/all/20260915152656708z04s4oSYY2BGj34F36RZa@zte.com.cn/