diff options
author | Alex Elder <elder@linaro.org> | 2021-10-01 18:23:31 -0500 |
---|---|---|
committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2021-10-04 12:35:07 -0500 |
commit | 789c4e9d23e3a8e9f30573a12b2e38a9484ecf77 (patch) | |
tree | 42674f5f251621e12a0ed41e2bed0f9c3bb148f1 | |
parent | 72d16876583aa82a05865e4e213a475e962ad134 (diff) |
parser: avoid token buffer overflow
Define TOKEN_BUF_SIZE as the size of the buffer used when parsing
tokens. Define TOKEN_BUF_MIN as the minimum size of the token
buffer; the size comes from what's necessary to represent a maximal
64-bit octal value.
Add checks in yylex() to avoid exhausting the token buffer on
pathological input. Use the minimum buffer size to NUL-terminate
the buffer for a message if the token name is too long.
Signed-off-by: Alex Elder <elder@linaro.org>
Message-Id: <20211001232338.769309-28-elder@linaro.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-rw-r--r-- | parser.c | 13 | ||||
-rw-r--r-- | tests/very_long_token.qmi | 18 |
2 files changed, 30 insertions, 1 deletions
@@ -27,6 +27,9 @@ __p; \ }) +#define TOKEN_BUF_SIZE 128 /* TOKEN_BUF_MIN or more */ +#define TOKEN_BUF_MIN 24 /* Enough for a 64-bit octal number */ + const char *qmi_package; struct list_head qmi_consts = LIST_INIT(qmi_consts); @@ -177,7 +180,7 @@ static struct token yylex() struct token token = {}; unsigned long long num; int (*isvalid)(int); - char buf[128]; + char buf[TOKEN_BUF_SIZE]; char *p = buf; int base; char ch; @@ -187,6 +190,10 @@ static struct token yylex() if (isalpha(ch)) { do { + if (p - buf == sizeof(buf)) { + buf[TOKEN_BUF_MIN] = '\0'; + yyerror("token too long: \"%s...\"", buf); + } *p++ = ch; ch = input(); } while (isalnum(ch) || ch == '_'); @@ -240,6 +247,10 @@ static struct token yylex() } do { + if (p - buf == sizeof(buf)) { + buf[TOKEN_BUF_MIN] = '\0'; + yyerror("number too long: \"%s...\"", buf); + } *p++ = ch; ch = input(); } while (isvalid(ch)); diff --git a/tests/very_long_token.qmi b/tests/very_long_token.qmi new file mode 100644 index 0000000..abe08f1 --- /dev/null +++ b/tests/very_long_token.qmi @@ -0,0 +1,18 @@ +package test_but_this_is_a_super_long_name_because_we_are_testing_parsing_a_token_that_is_bigger_than_the_size_of_the_input_buffer_its_very_very_bad_you_see; + +struct qmi_result { + u16 result; + u16 error; +}; + +request test_request { + required u8 test_number = 0x12; +} = 0x23; + +response test_response { + required qmi_result r = 2; +} = 043; + +indication test_indication { + optional u64 value = 0x99; +} = 0x7; |