| From 7443e951a20f46bd0cc954681a304926a72610da Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 26 Jul 2022 23:51:48 +0100 |
| Subject: ARM: findbit: fix overflowing offset |
| |
| From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> |
| |
| [ Upstream commit ec85bd369fd2bfaed6f45dd678706429d4f75b48 ] |
| |
| When offset is larger than the size of the bit array, we should not |
| attempt to access the array as we can perform an access beyond the |
| end of the array. Fix this by changing the pre-condition. |
| |
| Using "cmp r2, r1; bhs ..." covers us for the size == 0 case, since |
| this will always take the branch when r1 is zero, irrespective of |
| the value of r2. This means we can fix this bug without adding any |
| additional code! |
| |
| Tested-by: Guenter Roeck <linux@roeck-us.net> |
| Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| arch/arm/lib/findbit.S | 16 ++++++++-------- |
| 1 file changed, 8 insertions(+), 8 deletions(-) |
| |
| diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S |
| index b5e8b9ae4c7d..7fd3600db8ef 100644 |
| --- a/arch/arm/lib/findbit.S |
| +++ b/arch/arm/lib/findbit.S |
| @@ -40,8 +40,8 @@ ENDPROC(_find_first_zero_bit_le) |
| * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) |
| */ |
| ENTRY(_find_next_zero_bit_le) |
| - teq r1, #0 |
| - beq 3b |
| + cmp r2, r1 |
| + bhs 3b |
| ands ip, r2, #7 |
| beq 1b @ If new byte, goto old routine |
| ARM( ldrb r3, [r0, r2, lsr #3] ) |
| @@ -81,8 +81,8 @@ ENDPROC(_find_first_bit_le) |
| * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset) |
| */ |
| ENTRY(_find_next_bit_le) |
| - teq r1, #0 |
| - beq 3b |
| + cmp r2, r1 |
| + bhs 3b |
| ands ip, r2, #7 |
| beq 1b @ If new byte, goto old routine |
| ARM( ldrb r3, [r0, r2, lsr #3] ) |
| @@ -115,8 +115,8 @@ ENTRY(_find_first_zero_bit_be) |
| ENDPROC(_find_first_zero_bit_be) |
| |
| ENTRY(_find_next_zero_bit_be) |
| - teq r1, #0 |
| - beq 3b |
| + cmp r2, r1 |
| + bhs 3b |
| ands ip, r2, #7 |
| beq 1b @ If new byte, goto old routine |
| eor r3, r2, #0x18 @ big endian byte ordering |
| @@ -149,8 +149,8 @@ ENTRY(_find_first_bit_be) |
| ENDPROC(_find_first_bit_be) |
| |
| ENTRY(_find_next_bit_be) |
| - teq r1, #0 |
| - beq 3b |
| + cmp r2, r1 |
| + bhs 3b |
| ands ip, r2, #7 |
| beq 1b @ If new byte, goto old routine |
| eor r3, r2, #0x18 @ big endian byte ordering |
| -- |
| 2.35.1 |
| |