diff options
author | Claire Jensen <cjense@google.com> | 2021-06-17 19:43:25 +0000 |
---|---|---|
committer | Steven Rostedt (VMware) <rostedt@goodmis.org> | 2021-06-22 17:35:22 -0400 |
commit | 5fe6b476c7298b525f5b30ef192dd78578ac6e40 (patch) | |
tree | bff542d2982261d5d6fce5209b55a917fb743c3e | |
parent | 17aeb3190272c9c2897746a7ca37b2eb084cabf3 (diff) | |
download | libtraceevent-5fe6b476c7298b525f5b30ef192dd78578ac6e40.tar.gz |
libtraceevent: Add eof checks
Added checking for __read_char() and peek_char() to make sure value is not
at end of file.
This issue was found while fuzz testing. One of the test cases created an
infinite loop because __read_token had reached end of file. Checking was
added to all cases where this may occur.
Link: https://lore.kernel.org/linux-trace-devel/20210617194326.2107129-1-cjense@google.com
Signed-off-by: Claire Jensen <cjense@google.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
-rw-r--r-- | src/event-parse.c | 62 |
1 files changed, 48 insertions, 14 deletions
diff --git a/src/event-parse.c b/src/event-parse.c index 9915cb4..ac11887 100644 --- a/src/event-parse.c +++ b/src/event-parse.c @@ -1155,17 +1155,16 @@ static enum tep_event_type force_token(const char *str, char **tok); static enum tep_event_type __read_token(char **tok) { char buf[BUFSIZ]; - int ch, last_ch, quote_ch, next_ch; + int ch, last_ch, quote_ch, next_ch, read_ch, peek_ch; int i = 0; int tok_size = 0; enum tep_event_type type; *tok = NULL; - - ch = __read_char(); + ch = __read_char(); if (ch < 0) - return TEP_EVENT_NONE; + goto out_eof_error; type = get_type(ch); if (type == TEP_EVENT_NONE) @@ -1184,9 +1183,15 @@ static enum tep_event_type __read_token(char **tok) case TEP_EVENT_OP: switch (ch) { case '-': - next_ch = peek_char(); + peek_ch = peek_char(); + if (peek_ch < 0) + goto out_eof_error; + next_ch = peek_ch; if (next_ch == '>') { - buf[i++] = __read_char(); + read_ch = __read_char(); + if (read_ch < 0) + goto out_eof_error; + buf[i++] = read_ch; break; } /* fall through */ @@ -1197,9 +1202,14 @@ static enum tep_event_type __read_token(char **tok) case '<': last_ch = ch; ch = peek_char(); + if (ch < 0) + goto out_eof_error; if (ch != last_ch) goto test_equal; - buf[i++] = __read_char(); + read_ch = __read_char(); + if (read_ch < 0) + goto out_eof_error; + buf[i++] = read_ch; switch (last_ch) { case '>': case '<': @@ -1219,10 +1229,17 @@ static enum tep_event_type __read_token(char **tok) return type; test_equal: - ch = peek_char(); - if (ch == '=') - buf[i++] = __read_char(); - goto out; + peek_ch = peek_char(); + if (peek_ch < 0) + goto out_eof_error; + ch = peek_ch; + if (ch == '=') { + read_ch = __read_char(); + if (read_ch < 0) + goto out_eof_error; + buf[i++] = read_ch; + goto out; + } case TEP_EVENT_DQUOTE: case TEP_EVENT_SQUOTE: @@ -1242,6 +1259,8 @@ static enum tep_event_type __read_token(char **tok) } last_ch = ch; ch = __read_char(); + if(ch < 0) + goto out_eof_error; buf[i++] = ch; /* the '\' '\' will cancel itself */ if (ch == '\\' && last_ch == '\\') @@ -1259,6 +1278,8 @@ static enum tep_event_type __read_token(char **tok) do { ch = __read_char(); + if(ch < 0) + return TEP_EVENT_NONE; } while (isspace(ch)); if (ch == '"') goto concat; @@ -1273,7 +1294,13 @@ static enum tep_event_type __read_token(char **tok) break; } - while (get_type(peek_char()) == type) { + while (1) { + peek_ch = peek_char(); + if (peek_ch < 0) + goto out_eof_error; + if (get_type(peek_ch) != type) + break; + if (i == (BUFSIZ - 1)) { buf[i] = 0; tok_size += BUFSIZ; @@ -1282,8 +1309,10 @@ static enum tep_event_type __read_token(char **tok) return TEP_EVENT_NONE; i = 0; } - ch = __read_char(); - buf[i++] = ch; + read_ch = __read_char(); + if (read_ch < 0) + goto out_eof_error; + buf[i++] = read_ch; } out: @@ -1316,6 +1345,11 @@ static enum tep_event_type __read_token(char **tok) } return type; + +out_eof_error: + free(*tok); + *tok = NULL; + return TEP_EVENT_NONE; } static enum tep_event_type force_token(const char *str, char **tok) |