Julius Werner has submitted this change. ( https://review.coreboot.org/c/coreboot/+/83914?usp=email )
Change subject: commonlib/bsd/string: Fix pointer overflow for strnlen() ......................................................................
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 --- M src/commonlib/bsd/string.c M tests/commonlib/bsd/string-test.c 2 files changed, 7 insertions(+), 6 deletions(-)
Approvals: Karthik Ramasubramanian: Looks good to me, approved Mario Scheithauer: Looks good to me, approved build bot (Jenkins): Verified Julius Werner: Looks good to me, approved
diff --git a/src/commonlib/bsd/string.c b/src/commonlib/bsd/string.c index 16cd4b5..56670e8 100644 --- a/src/commonlib/bsd/string.c +++ b/src/commonlib/bsd/string.c @@ -15,12 +15,10 @@
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) diff --git a/tests/commonlib/bsd/string-test.c b/tests/commonlib/bsd/string-test.c index 37419f0..194177a 100644 --- a/tests/commonlib/bsd/string-test.c +++ b/tests/commonlib/bsd/string-test.c @@ -23,6 +23,9 @@
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));