diff --git a/plugins/sudoers/toke.c b/plugins/sudoers/toke.c index 44b297703..6717e4f9f 100644 --- a/plugins/sudoers/toke.c +++ b/plugins/sudoers/toke.c @@ -5455,9 +5455,16 @@ sudoers_trace_print(const char *msg) } #endif /* TRACELEXER */ +/* + * Custom input function that uses getdelim(3) and stores the buffer + * where the error functions can access it for better reporting. + * On success, buf is guaranteed to end in a newline and not contain + * embedded NULs. Calls YY_FATAL_ERROR on error. + */ static yy_size_t sudoers_input(char *buf, yy_size_t max_size) { + char *cp; size_t avail = sudolinebuf.len - sudolinebuf.off; /* Refill line buffer if needed. */ @@ -5470,10 +5477,18 @@ sudoers_input(char *buf, yy_size_t max_size) return 0; } + /* getdelim() can return embedded NULs, truncate if we find one. */ + cp = memchr(sudolinebuf.buf, '\0', avail); + if (cp != NULL) { + *cp++ = '\n'; + *cp = '\0'; + avail = (size_t)(cp - sudolinebuf.buf); + } + /* Add trailing newline if it is missing. */ if (sudolinebuf.buf[avail - 1] != '\n') { if (avail + 2 >= sudolinebuf.size) { - char *cp = realloc(sudolinebuf.buf, avail + 2); + cp = realloc(sudolinebuf.buf, avail + 2); if (cp == NULL) { YY_FATAL_ERROR("unable to allocate memory"); return 0; diff --git a/plugins/sudoers/toke.l b/plugins/sudoers/toke.l index e9102093f..499f3b1a8 100644 --- a/plugins/sudoers/toke.l +++ b/plugins/sudoers/toke.l @@ -1260,9 +1260,16 @@ sudoers_trace_print(const char *msg) } #endif /* TRACELEXER */ +/* + * Custom input function that uses getdelim(3) and stores the buffer + * where the error functions can access it for better reporting. + * On success, buf is guaranteed to end in a newline and not contain + * embedded NULs. Calls YY_FATAL_ERROR on error. + */ static yy_size_t sudoers_input(char *buf, yy_size_t max_size) { + char *cp; size_t avail = sudolinebuf.len - sudolinebuf.off; /* Refill line buffer if needed. */ @@ -1275,10 +1282,18 @@ sudoers_input(char *buf, yy_size_t max_size) return 0; } + /* getdelim() can return embedded NULs, truncate if we find one. */ + cp = memchr(sudolinebuf.buf, '\0', avail); + if (cp != NULL) { + *cp++ = '\n'; + *cp = '\0'; + avail = (size_t)(cp - sudolinebuf.buf); + } + /* Add trailing newline if it is missing. */ if (sudolinebuf.buf[avail - 1] != '\n') { if (avail + 2 >= sudolinebuf.size) { - char *cp = realloc(sudolinebuf.buf, avail + 2); + cp = realloc(sudolinebuf.buf, avail + 2); if (cp == NULL) { YY_FATAL_ERROR("unable to allocate memory"); return 0;