This repository has been archived by the owner on Feb 16, 2024. It is now read-only.
forked from openwrt/openwrt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This backports upstream fixes for the out of bounds write vulnerability in json-c. It was reported and patches in this upstream PR: json-c/json-c#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, rebase patches on top of json-c 0.12] Signed-off-by: Jo-Philipp Wich <jo@mein.io> (backported from commit d071916)
- Loading branch information
Showing
4 changed files
with
117 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
package/libs/libjson-c/patches/001-Prevent-division-by-zero-in-linkhash.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
From 77d935b7ae7871a1940cd827e850e6063044ec45 Mon Sep 17 00:00:00 2001 | ||
From: Tobias Stoeckmann <tobias@stoeckmann.org> | ||
Date: Mon, 4 May 2020 19:46:45 +0200 | ||
Subject: [PATCH 2/2] Prevent division by zero in linkhash. | ||
|
||
If a linkhash with a size of zero is created, then modulo operations | ||
are prone to division by zero operations. | ||
|
||
Purely protective measure against bad usage. | ||
--- | ||
linkhash.c | 3 +++ | ||
1 file changed, 3 insertions(+) | ||
|
||
--- a/linkhash.c | ||
+++ b/linkhash.c | ||
@@ -10,6 +10,7 @@ | ||
* | ||
*/ | ||
|
||
+#include <assert.h> | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
@@ -431,6 +432,8 @@ struct lh_table* lh_table_new(int size, | ||
int i; | ||
struct lh_table *t; | ||
|
||
+ /* Allocate space for elements to avoid divisions by zero. */ | ||
+ assert(size > 0); | ||
t = (struct lh_table*)calloc(1, sizeof(struct lh_table)); | ||
if(!t) lh_abort("lh_table_new: calloc failed\n"); | ||
t->count = 0; |
83 changes: 83 additions & 0 deletions
83
package/libs/libjson-c/patches/002-Fix-integer-overflows.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
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 | ||
@@ -498,7 +498,12 @@ int lh_table_insert(struct lh_table *t, | ||
unsigned long h, n; | ||
|
||
t->inserts++; | ||
- if(t->count >= t->size * LH_LOAD_FACTOR) lh_table_resize(t, t->size * 2); | ||
+ if(t->count >= t->size * LH_LOAD_FACTOR) { | ||
+ /* Avoid signed integer overflow with large tables. */ | ||
+ int new_size = (t->size > INT_MAX / 2) ? INT_MAX : (t->size * 2); | ||
+ if (t->size != INT_MAX) | ||
+ lh_table_resize(t, new_size); | ||
+ } | ||
|
||
h = t->hash_fn(k); | ||
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> | ||
@@ -63,7 +64,16 @@ static int printbuf_extend(struct printb | ||
if (p->size >= min_size) | ||
return 0; | ||
|
||
- new_size = json_max(p->size * 2, 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", | ||
@@ -78,6 +88,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; | ||
@@ -94,6 +107,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) | ||
{ |