From 7fd15f8e272136955f7ffc37df29fbca9ddceca1 Mon Sep 17 00:00:00 2001 From: David Rheinsberg Date: Tue, 19 Apr 2022 13:11:02 +0200 Subject: [PATCH] strnspn: fix buffer overflow Fix the strnspn and strncspn functions to use a properly sized buffer. It used to be 1 byte too short. Checking for `0xff` in a string will thus write `0xff` once byte beyond the stack space of the local buffer. Note that the public API does not allow to pass `0xff` to those functions. Therefore, this is a read-only buffer overrun, possibly causing bogus reports from the parser, but still well-defined. Reported-by: Steffen Robertz Signed-off-by: David Rheinsberg --- /subprojects/c-shquote/src/c-shquote.c | 4 ++-- /subprojects/c-shquote/src/test-private.c | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a//subprojects/c-shquote/src/c-shquote.c b//subprojects/c-shquote/src/c-shquote.c index b268906..abb55d6 100644 --- a//subprojects/c-shquote/src/c-shquote.c +++ b//subprojects/c-shquote/src/c-shquote.c @@ -85,7 +85,7 @@ int c_shquote_consume_char(char **outp, size_t c_shquote_strnspn(const char *string, size_t n_string, const char *accept) { - bool buffer[UCHAR_MAX] = {}; + bool buffer[UCHAR_MAX + 1] = {}; for ( ; *accept; ++accept) buffer[(unsigned char)*accept] = true; @@ -100,7 +100,7 @@ size_t c_shquote_strnspn(const char *string, size_t c_shquote_strncspn(const char *string, size_t n_string, const char *reject) { - bool buffer[UCHAR_MAX] = {}; + bool buffer[UCHAR_MAX + 1] = {}; if (strlen(reject) == 1) { const char *p; diff --git a//subprojects/c-shquote/src/test-private.c b//subprojects/c-shquote/src/test-private.c index 57a7250..c6afe40 100644 --- a//subprojects/c-shquote/src/test-private.c +++ b//subprojects/c-shquote/src/test-private.c @@ -148,6 +148,9 @@ static void test_strnspn(void) { len = c_shquote_strnspn("ab", 2, "bc"); c_assert(len == 0); + + len = c_shquote_strnspn("ab", 2, "\xff"); + c_assert(len == 0); } static void test_strncspn(void) { @@ -167,6 +170,9 @@ static void test_strncspn(void) { len = c_shquote_strncspn("ab", 2, "cd"); c_assert(len == 2); + + len = c_shquote_strncspn("ab", 2, "\xff"); + c_assert(len == 2); } static void test_discard_comment(void) {