mirror of
https://github.com/json-c/json-c.git
synced 2026-03-19 13:09:07 +08:00
Fix integer overflows.
The data structures linkhash and printbuf are limited to 2 GB in size due to a signed integer being used to track their current size. If too much data is added, then size variable can overflow, which is an undefined behaviour in C programming language. Assuming that a signed int overflow just leads to a negative value, like it happens on many sytems (Linux i686/amd64 with gcc), then printbuf is vulnerable to an out of boundary write on 64 bit systems.
This commit is contained in:
@@ -580,9 +580,12 @@ int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v, con
|
||||
{
|
||||
unsigned long n;
|
||||
|
||||
if (t->count >= t->size * LH_LOAD_FACTOR)
|
||||
if (lh_table_resize(t, t->size * 2) != 0)
|
||||
if (t->count >= t->size * LH_LOAD_FACTOR) {
|
||||
/* Avoid signed integer overflow with large tables. */
|
||||
int new_size = INT_MAX / 2 < t->size ? t->size * 2 : INT_MAX;
|
||||
if (t->size == INT_MAX || lh_table_resize(t, new_size) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
n = h % t->size;
|
||||
|
||||
|
||||
19
printbuf.c
19
printbuf.c
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -65,10 +66,16 @@ static int printbuf_extend(struct printbuf *p, int min_size)
|
||||
|
||||
if (p->size >= min_size)
|
||||
return 0;
|
||||
|
||||
new_size = p->size * 2;
|
||||
if (new_size < min_size + 8)
|
||||
/* Prevent signed integer overflows with large buffers. */
|
||||
if (min_size > INT_MAX - 8)
|
||||
return -1;
|
||||
if (p->size > INT_MAX / 2)
|
||||
new_size = min_size + 8;
|
||||
else {
|
||||
new_size = p->size * 2;
|
||||
if (new_size < min_size + 8)
|
||||
new_size = min_size + 8;
|
||||
}
|
||||
#ifdef PRINTBUF_DEBUG
|
||||
MC_DEBUG("printbuf_memappend: realloc "
|
||||
"bpos=%d min_size=%d old_size=%d new_size=%d\n",
|
||||
@@ -83,6 +90,9 @@ static int printbuf_extend(struct printbuf *p, int min_size)
|
||||
|
||||
int printbuf_memappend(struct printbuf *p, const char *buf, int size)
|
||||
{
|
||||
/* Prevent signed integer overflows with large buffers. */
|
||||
if (size > INT_MAX - p->bpos - 1)
|
||||
return -1;
|
||||
if (p->size <= p->bpos + size + 1)
|
||||
{
|
||||
if (printbuf_extend(p, p->bpos + size + 1) < 0)
|
||||
@@ -100,6 +110,9 @@ int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
|
||||
|
||||
if (offset == -1)
|
||||
offset = pb->bpos;
|
||||
/* Prevent signed integer overflows with large buffers. */
|
||||
if (len > INT_MAX - offset)
|
||||
return -1;
|
||||
size_needed = offset + len;
|
||||
if (pb->size < size_needed)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user