commonlib/bsd/string: Fix pointer overflow for strnlen()

When `maxlen` is large (such as SIZE_MAX), the `end` pointer will
overflow, causing strnlen() to incorrectly return 0.

To not make the implementation over-complicated, fix the problem by
using a counter.

BUG=b:359951393
TEST=make unit-tests -j
BRANCH=none

Change-Id: Ic9d983b11391f5e05c2bceb262682aced5206f94
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/83914
Reviewed-by: Julius Werner <jwerner@chromium.org>
Reviewed-by: Karthik Ramasubramanian <kramasub@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Mario Scheithauer <mario.scheithauer@siemens.com>
This commit is contained in:
Yu-Ping Wu 2024-08-15 10:17:38 +08:00 committed by Julius Werner
parent 0b2f9c9582
commit 078a5a0e7c
2 changed files with 7 additions and 6 deletions

View File

@ -15,12 +15,10 @@ size_t strlen(const char *str)
size_t strnlen(const char *str, size_t maxlen)
{
const char *ptr = str;
const char *end = str + maxlen + 1;
while (*ptr++ && ptr < end)
;
return ptr - str - 1;
size_t len = 0;
while (*str++ && len < maxlen)
len++;
return len;
}
char *strcat(char *dst, const char *src)

View File

@ -23,6 +23,9 @@ static void test_strlen(void **state)
static void test_strnlen(void **state)
{
/* maxlen is SIZE_MAX */
assert_int_equal(8, strnlen("coreboot", SIZE_MAX));
/* maxlen larger than string len */
assert_int_equal(8, strnlen("coreboot", 100));