sudo_lbuf_expand: check for possible integer overflow

The numeric fields in struct sudo_lbuf are now unsigned so that
wraparound is defined, this make the overflow checks simpler.
Problem deteced by oss-fuzz using the fuzz_sudoers fuzzer.
This commit is contained in:
Todd C. Miller
2023-01-03 20:02:01 -07:00
parent 6b80ab74ea
commit 13df52889f
2 changed files with 24 additions and 16 deletions

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2007, 2010, 2011, 2013-2015 * Copyright (c) 2007, 2010, 2011, 2013-2015, 2023
* Todd C. Miller <Todd.Miller@sudo.ws> * Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@@ -27,11 +27,11 @@ struct sudo_lbuf {
int (*output)(const char *); int (*output)(const char *);
char *buf; char *buf;
const char *continuation; const char *continuation;
int indent; unsigned int indent;
int len; unsigned int len;
int size; unsigned int size;
short cols; unsigned short cols;
short error; unsigned short error;
}; };
typedef int (*sudo_lbuf_output_t)(const char *); typedef int (*sudo_lbuf_output_t)(const char *);

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2007-2015 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 2007-2015, 2023 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -64,17 +64,23 @@ sudo_lbuf_destroy_v1(struct sudo_lbuf *lbuf)
} }
static bool static bool
sudo_lbuf_expand(struct sudo_lbuf *lbuf, int extra) sudo_lbuf_expand(struct sudo_lbuf *lbuf, unsigned int extra)
{ {
debug_decl(sudo_lbuf_expand, SUDO_DEBUG_UTIL); debug_decl(sudo_lbuf_expand, SUDO_DEBUG_UTIL);
if (lbuf->len + extra + 1 >= lbuf->size) { if (lbuf->len + extra + 1 <= lbuf->len) {
char *new_buf; sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
int new_size = lbuf->size; "integer overflow updating lbuf->len");
lbuf->error = 1;
debug_return_bool(false);
}
do { if (lbuf->len + extra + 1 > lbuf->size) {
new_size += 256; unsigned int new_size = lbuf->len + extra + 1;
} while (lbuf->len + extra + 1 >= new_size); char *new_buf;
/* Round new_size up to the next multiple of 256. */
new_size = (new_size + 255) & ~255;
if ((new_buf = realloc(lbuf->buf, new_size)) == NULL) { if ((new_buf = realloc(lbuf->buf, new_size)) == NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unable to allocate memory"); "unable to allocate memory");
@@ -94,10 +100,11 @@ sudo_lbuf_expand(struct sudo_lbuf *lbuf, int extra)
bool bool
sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...) sudo_lbuf_append_quoted_v1(struct sudo_lbuf *lbuf, const char *set, const char *fmt, ...)
{ {
int len, saved_len = lbuf->len; unsigned int saved_len = lbuf->len;
bool ret = false; bool ret = false;
const char *cp, *s; const char *cp, *s;
va_list ap; va_list ap;
int len;
debug_decl(sudo_lbuf_append_quoted, SUDO_DEBUG_UTIL); debug_decl(sudo_lbuf_append_quoted, SUDO_DEBUG_UTIL);
if (sudo_lbuf_error(lbuf)) if (sudo_lbuf_error(lbuf))
@@ -152,10 +159,11 @@ done:
bool bool
sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...) sudo_lbuf_append_v1(struct sudo_lbuf *lbuf, const char *fmt, ...)
{ {
int len, saved_len = lbuf->len; unsigned int saved_len = lbuf->len;
bool ret = false; bool ret = false;
va_list ap; va_list ap;
const char *s; const char *s;
int len;
debug_decl(sudo_lbuf_append, SUDO_DEBUG_UTIL); debug_decl(sudo_lbuf_append, SUDO_DEBUG_UTIL);
if (sudo_lbuf_error(lbuf)) if (sudo_lbuf_error(lbuf))