Merge pull request #757 from c3h2-ctf/big

json_object_from_fd_ex: fail if file is too large
This commit is contained in:
Eric Hawicz
2022-07-31 14:27:32 -04:00
committed by GitHub
2 changed files with 23 additions and 4 deletions

View File

@@ -101,15 +101,22 @@ struct json_object *json_object_from_fd_ex(int fd, int in_depth)
if (!tok) if (!tok)
{ {
_json_c_set_last_err( _json_c_set_last_err(
"json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n", depth, "json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n",
strerror(errno)); depth, strerror(errno));
printbuf_free(pb); printbuf_free(pb);
return NULL; return NULL;
} }
while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) while ((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0)
{ {
printbuf_memappend(pb, buf, ret); if (printbuf_memappend(pb, buf, ret) < 0)
{
_json_c_set_last_err("json_object_from_fd_ex: error reading fd %d: %s\n",
fd, strerror(errno));
json_tokener_free(tok);
printbuf_free(pb);
return NULL;
}
} }
if (ret < 0) if (ret < 0)
{ {

View File

@@ -15,6 +15,7 @@
#include "config.h" #include "config.h"
#include <errno.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -56,6 +57,8 @@ struct printbuf *printbuf_new(void)
* *
* If the current size is large enough, nothing is changed. * If the current size is large enough, nothing is changed.
* *
* If extension failed, errno is set to indicate the error.
*
* Note: this does not check the available space! The caller * Note: this does not check the available space! The caller
* is responsible for performing those calculations. * is responsible for performing those calculations.
*/ */
@@ -68,7 +71,10 @@ static int printbuf_extend(struct printbuf *p, int min_size)
return 0; return 0;
/* Prevent signed integer overflows with large buffers. */ /* Prevent signed integer overflows with large buffers. */
if (min_size > INT_MAX - 8) if (min_size > INT_MAX - 8)
{
errno = EFBIG;
return -1; return -1;
}
if (p->size > INT_MAX / 2) if (p->size > INT_MAX / 2)
new_size = min_size + 8; new_size = min_size + 8;
else { else {
@@ -77,7 +83,7 @@ static int printbuf_extend(struct printbuf *p, int min_size)
new_size = min_size + 8; new_size = min_size + 8;
} }
#ifdef PRINTBUF_DEBUG #ifdef PRINTBUF_DEBUG
MC_DEBUG("printbuf_memappend: realloc " MC_DEBUG("printbuf_extend: realloc "
"bpos=%d min_size=%d old_size=%d new_size=%d\n", "bpos=%d min_size=%d old_size=%d new_size=%d\n",
p->bpos, min_size, p->size, new_size); p->bpos, min_size, p->size, new_size);
#endif /* PRINTBUF_DEBUG */ #endif /* PRINTBUF_DEBUG */
@@ -92,7 +98,10 @@ int printbuf_memappend(struct printbuf *p, const char *buf, int size)
{ {
/* Prevent signed integer overflows with large buffers. */ /* Prevent signed integer overflows with large buffers. */
if (size < 0 || size > INT_MAX - p->bpos - 1) if (size < 0 || size > INT_MAX - p->bpos - 1)
{
errno = EFBIG;
return -1; return -1;
}
if (p->size <= p->bpos + size + 1) if (p->size <= p->bpos + size + 1)
{ {
if (printbuf_extend(p, p->bpos + size + 1) < 0) if (printbuf_extend(p, p->bpos + size + 1) < 0)
@@ -112,7 +121,10 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
offset = pb->bpos; offset = pb->bpos;
/* Prevent signed integer overflows with large buffers. */ /* Prevent signed integer overflows with large buffers. */
if (len < 0 || offset < -1 || len > INT_MAX - offset) if (len < 0 || offset < -1 || len > INT_MAX - offset)
{
errno = EFBIG;
return -1; return -1;
}
size_needed = offset + len; size_needed = offset + len;
if (pb->size < size_needed) if (pb->size < size_needed)
{ {