From cc6ad155fd7b8e1ac7d80731ebde9e86c49ce2af Mon Sep 17 00:00:00 2001 From: klmengkd Date: Mon, 14 Nov 2022 19:30:16 +0800 Subject: [PATCH] add backport patch --- ...e-memory-leak-mentioned-in-issue-781.patch | 31 +++++ ...py-strings-in-json_object_set_string.patch | 67 +++++++++++ ...from_fd_ex-fail-if-file-is-too-large.patch | 111 ++++++++++++++++++ json-c.spec | 11 +- 4 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 backport-Add-test-to-check-for-the-memory-leak-mentioned-in-issue-781.patch create mode 100644 backport-Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch create mode 100644 backport-json_object_from_fd_ex-fail-if-file-is-too-large.patch diff --git a/backport-Add-test-to-check-for-the-memory-leak-mentioned-in-issue-781.patch b/backport-Add-test-to-check-for-the-memory-leak-mentioned-in-issue-781.patch new file mode 100644 index 0000000..488d9bb --- /dev/null +++ b/backport-Add-test-to-check-for-the-memory-leak-mentioned-in-issue-781.patch @@ -0,0 +1,31 @@ +From 16208fc01afcd742fd5e6736f52849ad2ec03e8f Mon Sep 17 00:00:00 2001 +From: Eric Haszlakiewicz +Date: Sun, 24 Jul 2022 18:59:26 +0000 +Subject: [PATCH] Add test to check for the memory leak mentioned in issue #781 + +Conflict:NA +Reference:https://github.com/json-c/json-c/commit/16208fc01afcd742fd5e6736f52849ad2ec03e8f + +--- + tests/test_set_value.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/tests/test_set_value.c b/tests/test_set_value.c +index f51a2a5b67..a8ebbfec79 100644 +--- a/tests/test_set_value.c ++++ b/tests/test_set_value.c +@@ -71,6 +71,14 @@ int main(int argc, char **argv) + json_object_set_string(tmp, SHORT); + assert(strcmp(json_object_get_string(tmp), SHORT) == 0); + assert(strcmp(json_object_to_json_string(tmp), "\"" SHORT "\"") == 0); ++ ++ // Set an empty string a couple times to try to trigger ++ // a case that used to leak memory. ++ json_object_set_string(tmp, ""); ++ json_object_set_string(tmp, HUGE); ++ json_object_set_string(tmp, ""); ++ json_object_set_string(tmp, HUGE); ++ + json_object_put(tmp); + printf("STRING PASSED\n"); + diff --git a/backport-Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch b/backport-Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch new file mode 100644 index 0000000..102d803 --- /dev/null +++ b/backport-Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch @@ -0,0 +1,67 @@ +From 213bb5caa11ed2182848d86c86f8e9ab4c75642a Mon Sep 17 00:00:00 2001 +From: Daniel Danzberger +Date: Sun, 24 Jul 2022 18:46:03 +0200 +Subject: [PATCH] Fix memory leak with emtpy strings in json_object_set_string + +When a json string object is updated with a bigger string, a new +malloc'ed buffer is used to store the new string and it's size is made +negative to indicate that an external buffer is in use. + +When that same json string object get's updated again with an empty +stirng (size = 0), the new external malloc'ed buffer is still used. +But the fact that the new size value is not negative removes the +indicator that the externally malloc'ed buffer is used. + +This becomes a problem when the object get's updated again with any +other string, because a new buffer will be malloced and linked to the +object while to old one won't be free'd. + +This causes a memory leak when updating a json string with +json_object_set_stirng() which has previously been updated +with an empty string. + +Example: +-- +obj = json_object_new_string("data"); +json_object_set_string(obj, "more data"); +json_object_set_string(obj, ""); +json_object_set_string(obj, "other data"); /* leaks */ +-- + +This commit fixes the issue by free'ing the external buffer when an +empty string is set and use the internal one again. + +Signed-off-by: Daniel Danzberger + +Conflict:NA +Reference:https://github.com/json-c/json-c/commit/213bb5caa11ed2182848d86c86f8e9ab4c75642a +--- + json_object.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/json_object.c b/json_object.c +index e52ca4071a..581b1e2748 100644 +--- a/json_object.c ++++ b/json_object.c +@@ -1323,11 +1323,18 @@ static int _json_object_set_string_len(json_object *jso, const char *s, size_t l + // length as int, cap length at INT_MAX. + return 0; + +- dstbuf = get_string_component_mutable(jso); + curlen = JC_STRING(jso)->len; +- if (curlen < 0) +- curlen = -curlen; ++ if (curlen < 0) { ++ if (len == 0) { ++ free(JC_STRING(jso)->c_string.pdata); ++ JC_STRING(jso)->len = curlen = 0; ++ } else { ++ curlen = -curlen; ++ } ++ } ++ + newlen = len; ++ dstbuf = get_string_component_mutable(jso); + + if ((ssize_t)len > curlen) + { diff --git a/backport-json_object_from_fd_ex-fail-if-file-is-too-large.patch b/backport-json_object_from_fd_ex-fail-if-file-is-too-large.patch new file mode 100644 index 0000000..3db53d0 --- /dev/null +++ b/backport-json_object_from_fd_ex-fail-if-file-is-too-large.patch @@ -0,0 +1,111 @@ +From 5accae04bbc727fd447c2db4c1c541a4142bd4a0 Mon Sep 17 00:00:00 2001 +From: Tobias Stoeckmann +Date: Sun, 20 Mar 2022 13:17:37 +0100 +Subject: [PATCH] json_object_from_fd_ex: fail if file is too large + +If the input file is too large to fit into a printbuf then return an +error value instead of silently truncating the parsed content. + +This introduces errno handling into printbuf to distinguish between an +input file being too large and running out of memory. + +Conflict:tests/test_util_file.expected,0.16 version has merge. +Reference:https://github.com/json-c/json-c/commit/5accae04bbc727fd447c2db4c1c541a4142bd4a0 +--- + json_util.c | 13 ++++++++++--- + printbuf.c | 14 +++++++++++++- + 2 files changed, 23 insertions(+), 4 deletions(-) + +diff --git a/json_util.c b/json_util.c +index 3e6a6c681b..e1c05c5cfd 100644 +--- a/json_util.c ++++ b/json_util.c +@@ -101,15 +101,22 @@ struct json_object *json_object_from_fd_ex(int fd, int in_depth) + if (!tok) + { + _json_c_set_last_err( +- "json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n", depth, +- strerror(errno)); ++ "json_object_from_fd_ex: unable to allocate json_tokener(depth=%d): %s\n", ++ depth, strerror(errno)); + printbuf_free(pb); + return NULL; + } + + 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) + { +diff --git a/printbuf.c b/printbuf.c +index a08f7b1582..12d3b3319d 100644 +--- a/printbuf.c ++++ b/printbuf.c +@@ -15,6 +15,7 @@ + + #include "config.h" + ++#include + #include + #include + #include +@@ -56,6 +57,8 @@ struct printbuf *printbuf_new(void) + * + * 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 + * is responsible for performing those calculations. + */ +@@ -68,7 +71,10 @@ static int printbuf_extend(struct printbuf *p, int min_size) + return 0; + /* Prevent signed integer overflows with large buffers. */ + if (min_size > INT_MAX - 8) ++ { ++ errno = EFBIG; + return -1; ++ } + if (p->size > INT_MAX / 2) + new_size = min_size + 8; + else { +@@ -77,7 +83,7 @@ static int printbuf_extend(struct printbuf *p, int min_size) + new_size = min_size + 8; + } + #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", + p->bpos, min_size, p->size, new_size); + #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. */ + if (size < 0 || size > INT_MAX - p->bpos - 1) ++ { ++ errno = EFBIG; + return -1; ++ } + if (p->size <= p->bpos + size + 1) + { + 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; + /* Prevent signed integer overflows with large buffers. */ + if (len < 0 || offset < -1 || len > INT_MAX - offset) ++ { ++ errno = EFBIG; + return -1; ++ } + size_needed = offset + len; + if (pb->size < size_needed) + { diff --git a/json-c.spec b/json-c.spec index 3301873..792a432 100644 --- a/json-c.spec +++ b/json-c.spec @@ -6,7 +6,7 @@ Name: json-c Version: 0.16 -Release: 1 +Release: 2 Summary: JSON implementation in C License: MIT @@ -15,6 +15,10 @@ Source0: %{url}/archive/%{name}-%{version}-%{reldate}.tar.gz BuildRequires: cmake gcc ninja-build +Patch6001: backport-Add-test-to-check-for-the-memory-leak-mentioned-in-issue-781.patch +Patch6002: backport-Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch +Patch6003: backport-json_object_from_fd_ex-fail-if-file-is-too-large.patch + %description JSON-C implements a reference counting object model that allows you to easily construct JSON objects in C, output them as JSON formatted @@ -101,6 +105,11 @@ end %doc %{_pkgdocdir} %changelog +* Mon Nov 14 2022 mengkanglai - 0.16-2 +- add backport-Add-test-to-check-for-the-memory-leak-mentioned-in-issue-781.patch +- add backport-Fix-memory-leak-with-emtpy-strings-in-json_object_set_string.patch +- add backport-json_object_from_fd_ex-fail-if-file-is-too-large.patch + * Sat Nov 5 2022 zhangrui - 0.16-1 - Update to 0.16