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:
@@ -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 *);
|
||||||
|
@@ -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))
|
||||||
|
Reference in New Issue
Block a user