From c2abde56b29ffb15b68237e6731c55024fea9eae Mon Sep 17 00:00:00 2001 From: "gao.rui@zte.com.cn" Date: Wed, 19 Aug 2026 16:18:21 +0800 Subject: [PATCH] riscv: lib: Fix address overflow due to large count values in strnlen ZBB path Hi all, This patch fixes an issue in the RISC-V ZBB optimized strnlen implementation. Problem description: When using the ZBB optimized strnlen implementation, passing very large count values (such as SIZE_MAX) can cause address overflow and return incorrect results. This issue was observed in device-mapper tests: sh-5.2# dmsetup create testname9 --table "0 8 zero" sh-5.2# cat /sys/block/dm-*/dm/name testname sh-5.2# dmsetup remove testname9 The overflow in strnlen caused failures in string handling during device-mapper operations. Patch summary: - Explicitly introduce the strnlen_generic label. - Simplify the generic implementation loop. - Add fallback logic in strnlen_zbb to redirect to the generic path when a0 + a1 overflows. This ensures correct behavior for large count values and SIZE_MAX cases. Fixes: 5ba15d419fab ("riscv: lib: add strnlen() implementation") Signed-off-by: Gao Rui Signed-off-by: Linux RISC-V bot --- arch/riscv/lib/strnlen.S | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/arch/riscv/lib/strnlen.S b/arch/riscv/lib/strnlen.S index 53afa7b5b314d9..29665aa983d19b 100644 --- a/arch/riscv/lib/strnlen.S +++ b/arch/riscv/lib/strnlen.S @@ -17,6 +17,7 @@ SYM_FUNC_START(strnlen) __ALTERNATIVE_CFG("nop", "j strnlen_zbb", 0, RISCV_ISA_EXT_ZBB, IS_ENABLED(CONFIG_RISCV_ISA_ZBB) && IS_ENABLED(CONFIG_TOOLCHAIN_HAS_ZBB)) +strnlen_generic: /* * Returns @@ -27,15 +28,17 @@ SYM_FUNC_START(strnlen) * a1 - Max length of string * * Clobbers - * t0, t1, t2 + * t0, t1 */ - addi t1, a0, -1 - add t2, a0, a1 + mv t1, a0 + 1: - addi t1, t1, 1 - beq t1, t2, 2f + beqz a1, 2f + addi a1, a1, -1 lbu t0, 0(t1) - bnez t0, 1b + beqz t0, 2f + addi t1, t1, 1 + j 1b 2: sub a0, t1, a0 ret @@ -73,6 +76,13 @@ strnlen_zbb: /* If maxlen is 0, return 0. */ beqz a1, 3f + /* + * Fallback to generic implementation when count is large enough to + * cause address overflow in the ZBB optimized path + */ + add t4, a0, a1 + bltu t4, a0, strnlen_generic /* a0 + a1 overflow */ + /* Number of irrelevant bytes in the first word. */ andi t2, a0, SZREG-1