[PATCH] riscv: lib: Fix address overflow due to large count values in strnlen ZBB path

gao.rui at zte.com.cn gao.rui at zte.com.cn
Wed Aug 19 01:18:21 PDT 2026


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 <gao.rui at zte.com.cn>
---
 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 a8911605c248..04016e51e8b5 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

-- 
2.27.0



More information about the linux-riscv mailing list