libjson-c: backport security fixes
This backports upstream fixes for the out of bounds write vulnerability in json-c. It was reported and patches in this upstream PR: https://github.com/json-c/json-c/pull/592 Addresses CVE-2020-12762 Signed-off-by: Robert Marko <robert.marko@sartura.hr> Signed-off-by: Luka Perkov <luka.perkov@sartura.hr> [bump PKG_RELEASE] Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
		 Robert Marko
					Robert Marko
				
			
				
					committed by
					
						 Jo-Philipp Wich
						Jo-Philipp Wich
					
				
			
			
				
	
			
			
			 Jo-Philipp Wich
						Jo-Philipp Wich
					
				
			
						parent
						
							2308644b0c
						
					
				
				
					commit
					bc0288b768
				
			| @@ -0,0 +1,86 @@ | ||||
| From d07b91014986900a3a75f306d302e13e005e9d67 Mon Sep 17 00:00:00 2001 | ||||
| From: Tobias Stoeckmann <tobias@stoeckmann.org> | ||||
| Date: Mon, 4 May 2020 19:47:25 +0200 | ||||
| Subject: [PATCH] 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. | ||||
| --- | ||||
|  linkhash.c |  7 +++++-- | ||||
|  printbuf.c | 19 ++++++++++++++++--- | ||||
|  2 files changed, 21 insertions(+), 5 deletions(-) | ||||
|  | ||||
| --- a/linkhash.c | ||||
| +++ b/linkhash.c | ||||
| @@ -579,9 +579,12 @@ int lh_table_insert_w_hash(struct lh_tab | ||||
|  { | ||||
|  	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; | ||||
|   | ||||
| --- a/printbuf.c | ||||
| +++ b/printbuf.c | ||||
| @@ -15,6 +15,7 @@ | ||||
|   | ||||
|  #include "config.h" | ||||
|   | ||||
| +#include <limits.h> | ||||
|  #include <stdio.h> | ||||
|  #include <stdlib.h> | ||||
|  #include <string.h> | ||||
| @@ -65,9 +66,16 @@ static int printbuf_extend(struct printb | ||||
|  	if (p->size >= min_size) | ||||
|  		return 0; | ||||
|   | ||||
| -	new_size = p->size * 2; | ||||
| -	if (new_size < min_size + 8) | ||||
| -		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", | ||||
| @@ -82,6 +90,9 @@ static int printbuf_extend(struct printb | ||||
|   | ||||
|  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) | ||||
|        return -1; | ||||
| @@ -98,6 +109,9 @@ int printbuf_memset(struct printbuf *pb, | ||||
|   | ||||
|  	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