summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Elder <elder@linaro.org>2021-10-01 18:23:31 -0500
committerBjorn Andersson <bjorn.andersson@linaro.org>2021-10-04 12:35:07 -0500
commit789c4e9d23e3a8e9f30573a12b2e38a9484ecf77 (patch)
tree42674f5f251621e12a0ed41e2bed0f9c3bb148f1
parent72d16876583aa82a05865e4e213a475e962ad134 (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.c13
-rw-r--r--tests/very_long_token.qmi18
2 files changed, 30 insertions, 1 deletions
diff --git a/parser.c b/parser.c
index b9c2efd..2498b79 100644
--- a/parser.c
+++ b/parser.c
@@ -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;