aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClaire Jensen <cjense@google.com>2021-06-17 19:43:25 +0000
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2021-06-22 17:35:22 -0400
commit5fe6b476c7298b525f5b30ef192dd78578ac6e40 (patch)
treebff542d2982261d5d6fce5209b55a917fb743c3e
parent17aeb3190272c9c2897746a7ca37b2eb084cabf3 (diff)
downloadlibtraceevent-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.c62
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)