Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:jq
User: [email protected]
Usertags: pu

Cherry-pick upstream security patches.

[ Reason ]

Fix the following security vulnerabilities:

* CVE-2026-32316
* CVE-2026-33947
* CVE-2026-33948
* CVE-2026-39956
* CVE-2026-39979
* CVE-2026-40164

[ Impact ]

Security vulnerabilities

[ Tests ]

Test by upstream unit tests.

[ Risks ]

The code changes are all small, with clear intentions.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]

The following are original upstream patches:

* https://github.com/jqlang/jq/commit/e47e56d226519635768e6aab2f38f0ab037c09e5
* https://github.com/jqlang/jq/commit/fb59f1491058d58bdc3e8dd28f1773d1ac690a1f
* https://github.com/jqlang/jq/commit/6374ae0bcdfe33a18eb0ae6db28493b1f34a0a5b
* https://github.com/jqlang/jq/commit/fdf8ef0f0810e3d365cdd5160de43db46f57ed03
* https://github.com/jqlang/jq/commit/2f09060afab23fe9390cce7cb860b10416e1bf5f
* https://github.com/jqlang/jq/commit/0c7d133c3c7e37c00b6d46b658a02244fdd3c784

[ Other info ]

-- 
ChangZhuo Chen (陳昌倬)
callsign: BU2HG
email: [email protected]
fingerprint = BA04 346D C2E1 FE63 C790 8793 CC65 B0CD EC27 5D5B
diff -Nru jq-1.7.1/debian/changelog jq-1.7.1/debian/changelog
--- jq-1.7.1/debian/changelog	2025-07-08 00:16:39.000000000 +0800
+++ jq-1.7.1/debian/changelog	2026-04-17 17:08:56.000000000 +0800
@@ -1,3 +1,15 @@
+jq (1.7.1-6+deb13u2) trixie; urgency=medium
+
+  * Cherry-pick upstream commit for the following:
+    * CVE-2026-32316
+    * CVE-2026-33947
+    * CVE-2026-33948
+    * CVE-2026-39956
+    * CVE-2026-39979
+    * CVE-2026-40164
+
+ -- ChangZhuo Chen (陳昌倬) <[email protected]>  Fri, 17 Apr 2026 17:08:56 +0800
+
 jq (1.7.1-6+deb13u1) trixie; urgency=medium
 
   * Cherry-pick upstream commit for CVE-2025-48060.
diff -Nru jq-1.7.1/debian/patches/CVE-2026-33947.patch jq-1.7.1/debian/patches/CVE-2026-33947.patch
--- jq-1.7.1/debian/patches/CVE-2026-33947.patch	1970-01-01 08:00:00.000000000 +0800
+++ jq-1.7.1/debian/patches/CVE-2026-33947.patch	2026-04-17 17:08:56.000000000 +0800
@@ -0,0 +1,97 @@
+From: =?utf-8?b?IkNoYW5nWmh1byBDaGVuICjpmbPmmIzlgKwpIg==?=
+ <[email protected]>
+Date: Fri, 17 Apr 2026 09:03:54 +0800
+Subject: CVE-2026-33947
+
+Origin: https://github.com/jqlang/jq/commit/fb59f1491058d58bdc3e8dd28f1773d1ac690a1f
+---
+ src/jv_aux.c  | 21 +++++++++++++++++++++
+ tests/jq.test | 25 +++++++++++++++++++++++++
+ 2 files changed, 46 insertions(+)
+
+diff --git a/src/jv_aux.c b/src/jv_aux.c
+index bbe1c0d..0855053 100644
+--- a/src/jv_aux.c
++++ b/src/jv_aux.c
+@@ -376,6 +376,10 @@ static jv jv_dels(jv t, jv keys) {
+   return t;
+ }
+ 
++#ifndef MAX_PATH_DEPTH
++#define MAX_PATH_DEPTH (10000)
++#endif
++
+ jv jv_setpath(jv root, jv path, jv value) {
+   if (jv_get_kind(path) != JV_KIND_ARRAY) {
+     jv_free(value);
+@@ -383,6 +387,12 @@ jv jv_setpath(jv root, jv path, jv value) {
+     jv_free(path);
+     return jv_invalid_with_msg(jv_string("Path must be specified as an array"));
+   }
++  if (jv_array_length(jv_copy(path)) > MAX_PATH_DEPTH) {
++    jv_free(value);
++    jv_free(root);
++    jv_free(path);
++    return jv_invalid_with_msg(jv_string("Path too deep"));
++  }
+   if (!jv_is_valid(root)){
+     jv_free(value);
+     jv_free(path);
+@@ -434,6 +444,11 @@ jv jv_getpath(jv root, jv path) {
+     jv_free(path);
+     return jv_invalid_with_msg(jv_string("Path must be specified as an array"));
+   }
++  if (jv_array_length(jv_copy(path)) > MAX_PATH_DEPTH) {
++    jv_free(root);
++    jv_free(path);
++    return jv_invalid_with_msg(jv_string("Path too deep"));
++  }
+   if (!jv_is_valid(root)) {
+     jv_free(path);
+     return root;
+@@ -511,6 +526,12 @@ jv jv_delpaths(jv object, jv paths) {
+       jv_free(elem);
+       return err;
+     }
++    if (jv_array_length(jv_copy(elem)) > MAX_PATH_DEPTH) {
++      jv_free(object);
++      jv_free(paths);
++      jv_free(elem);
++      return jv_invalid_with_msg(jv_string("Path too deep"));
++    }
+     jv_free(elem);
+   }
+   if (jv_array_length(jv_copy(paths)) == 0) {
+diff --git a/tests/jq.test b/tests/jq.test
+index b36e591..e1deba0 100644
+--- a/tests/jq.test
++++ b/tests/jq.test
+@@ -2123,3 +2123,28 @@ try ltrimstr("x") catch "x", try rtrimstr("x") catch "x" | "ok"
+ {"hey":[]}
+ "ok"
+ "ok"
++
++# regression test for CVE-2026-33947
++setpath([range(10000) | 0]; 0) | flatten
++null
++[0]
++
++try setpath([range(10001) | 0]; 0) catch .
++null
++"Path too deep"
++
++getpath([range(10000) | 0])
++null
++null
++
++try getpath([range(10001) | 0]) catch .
++null
++"Path too deep"
++
++delpaths([[range(10000) | 0]])
++null
++null
++
++try delpaths([[range(10001) | 0]]) catch .
++null
++"Path too deep"
diff -Nru jq-1.7.1/debian/patches/CVE-2026-33948.patch jq-1.7.1/debian/patches/CVE-2026-33948.patch
--- jq-1.7.1/debian/patches/CVE-2026-33948.patch	1970-01-01 08:00:00.000000000 +0800
+++ jq-1.7.1/debian/patches/CVE-2026-33948.patch	2026-04-17 17:08:56.000000000 +0800
@@ -0,0 +1,45 @@
+From: =?utf-8?b?IkNoYW5nWmh1byBDaGVuICjpmbPmmIzlgKwpIg==?=
+ <[email protected]>
+Date: Fri, 17 Apr 2026 09:05:55 +0800
+Subject: CVE-2026-33948
+
+Origin: https://github.com/jqlang/jq/commit/6374ae0bcdfe33a18eb0ae6db28493b1f34a0a5b
+---
+ src/util.c   | 8 +-------
+ tests/shtest | 6 ++++++
+ 2 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/src/util.c b/src/util.c
+index de44fa6..422a8b8 100644
+--- a/src/util.c
++++ b/src/util.c
+@@ -311,13 +311,7 @@ static int jq_util_input_read_more(jq_util_input_state *state) {
+       if (p != NULL)
+         state->current_line++;
+ 
+-      if (p == NULL && state->parser != NULL) {
+-        /*
+-         * There should be no NULs in JSON texts (but JSON text
+-         * sequences are another story).
+-         */
+-        state->buf_valid_len = strlen(state->buf);
+-      } else if (p == NULL && feof(state->current_input)) {
++      if (p == NULL && feof(state->current_input)) {
+         size_t i;
+ 
+         /*
+diff --git a/tests/shtest b/tests/shtest
+index 14aafbf..544506a 100755
+--- a/tests/shtest
++++ b/tests/shtest
+@@ -614,4 +614,10 @@ $VALGRIND $Q $JQ . <<\NUM
+ -10E-1000000001
+ NUM
+ 
++# CVE-2026-33948: No NUL truncation in the JSON parser
++if printf '{}\x00{}' | $JQ >/dev/null 2> /dev/null; then
++  printf 'Error expected but jq exited successfully\n' 1>&2
++  exit 1
++fi
++
+ exit 0
diff -Nru jq-1.7.1/debian/patches/CVE-2026-39956.patch jq-1.7.1/debian/patches/CVE-2026-39956.patch
--- jq-1.7.1/debian/patches/CVE-2026-39956.patch	1970-01-01 08:00:00.000000000 +0800
+++ jq-1.7.1/debian/patches/CVE-2026-39956.patch	2026-04-17 17:08:56.000000000 +0800
@@ -0,0 +1,50 @@
+From: =?utf-8?b?IkNoYW5nWmh1byBDaGVuICjpmbPmmIzlgKwpIg==?=
+ <[email protected]>
+Date: Fri, 17 Apr 2026 09:06:40 +0800
+Subject: CVE-2026-39956
+
+Origin: https://github.com/jqlang/jq/commit/fdf8ef0f0810e3d365cdd5160de43db46f57ed03
+---
+ src/builtin.c | 8 ++++++++
+ tests/jq.test | 9 +++++++++
+ 2 files changed, 17 insertions(+)
+
+diff --git a/src/builtin.c b/src/builtin.c
+index 902490d..3cb8eb7 100644
+--- a/src/builtin.c
++++ b/src/builtin.c
+@@ -1212,6 +1212,14 @@ static jv f_string_explode(jq_state *jq, jv a) {
+ }
+ 
+ static jv f_string_indexes(jq_state *jq, jv a, jv b) {
++  if (jv_get_kind(a) != JV_KIND_STRING) {
++    jv_free(b);
++    return type_error(a, "cannot be searched, as it is not a string");
++  }
++  if (jv_get_kind(b) != JV_KIND_STRING) {
++    jv_free(a);
++    return type_error(b, "is not a string");
++  }
+   return jv_string_indexes(a, b);
+ }
+ 
+diff --git a/tests/jq.test b/tests/jq.test
+index e1deba0..d731513 100644
+--- a/tests/jq.test
++++ b/tests/jq.test
+@@ -1333,6 +1333,15 @@ split("")
+ "xababababax"
+ [1,7,[1,3,5,7]]
+ 
++# _strindices is used by indices/1 but is callable
++try _strindices("abc") catch .
++123
++"number (123) cannot be searched, as it is not a string"
++
++try _strindices(123) catch .
++"abc"
++"number (123) is not a string"
++
+ indices(1)
+ [0,1,1,2,3,4,1,5]
+ [1,2,6]
diff -Nru jq-1.7.1/debian/patches/CVE-2026-39979.patch jq-1.7.1/debian/patches/CVE-2026-39979.patch
--- jq-1.7.1/debian/patches/CVE-2026-39979.patch	1970-01-01 08:00:00.000000000 +0800
+++ jq-1.7.1/debian/patches/CVE-2026-39979.patch	2026-04-17 17:08:56.000000000 +0800
@@ -0,0 +1,25 @@
+From: =?utf-8?b?IkNoYW5nWmh1byBDaGVuICjpmbPmmIzlgKwpIg==?=
+ <[email protected]>
+Date: Fri, 17 Apr 2026 09:07:31 +0800
+Subject: CVE-2026-39979
+
+Origin: https://github.com/jqlang/jq/commit/2f09060afab23fe9390cce7cb860b10416e1bf5f
+---
+ src/jv_parse.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/jv_parse.c b/src/jv_parse.c
+index 9755b8a..84a847f 100644
+--- a/src/jv_parse.c
++++ b/src/jv_parse.c
+@@ -890,8 +890,9 @@ jv jv_parse_sized_custom_flags(const char* string, int length, int flags) {
+ 
+   if (!jv_is_valid(value) && jv_invalid_has_msg(jv_copy(value))) {
+     jv msg = jv_invalid_get_msg(value);
+-    value = jv_invalid_with_msg(jv_string_fmt("%s (while parsing '%s')",
++    value = jv_invalid_with_msg(jv_string_fmt("%s (while parsing '%.*s')",
+                                               jv_string_value(msg),
++                                              length,
+                                               string));
+     jv_free(msg);
+   }
diff -Nru jq-1.7.1/debian/patches/CVE-2026-40164.patch jq-1.7.1/debian/patches/CVE-2026-40164.patch
--- jq-1.7.1/debian/patches/CVE-2026-40164.patch	1970-01-01 08:00:00.000000000 +0800
+++ jq-1.7.1/debian/patches/CVE-2026-40164.patch	2026-04-17 17:08:56.000000000 +0800
@@ -0,0 +1,83 @@
+From: =?utf-8?b?IkNoYW5nWmh1byBDaGVuICjpmbPmmIzlgKwpIg==?=
+ <[email protected]>
+Date: Fri, 17 Apr 2026 09:07:50 +0800
+Subject: CVE-2026-40164
+
+Origin: https://github.com/jqlang/jq/commit/0c7d133c3c7e37c00b6d46b658a02244fdd3c784
+---
+ configure.ac |  2 ++
+ src/jv.c     | 34 ++++++++++++++++++++++++++++++++--
+ 2 files changed, 34 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 4c9feae..841ba1b 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -124,6 +124,8 @@ AC_CHECK_MEMBER([struct tm.tm_gmtoff], [AC_DEFINE([HAVE_TM_TM_GMT_OFF],1,[Define
+ AC_CHECK_MEMBER([struct tm.__tm_gmtoff], [AC_DEFINE([HAVE_TM___TM_GMT_OFF],1,[Define to 1 if the system has the __tm_gmt_off field in struct tm])],
+                 [], [[#include <time.h>]])
+ AC_FIND_FUNC([setlocale], [c], [#include <locale.h>], [0,0])
++AC_FIND_FUNC([arc4random], [c], [#include <stdlib.h>], [])
++AC_FIND_FUNC([getentropy], [c], [#include <unistd.h>], [0, 0])
+ 
+ dnl Figure out if we have the pthread functions we actually need
+ AC_FIND_FUNC_NO_LIBS([pthread_key_create], [], [#include <pthread.h>], [NULL, NULL])
+diff --git a/src/jv.c b/src/jv.c
+index c8e0c51..10a861f 100644
+--- a/src/jv.c
++++ b/src/jv.c
+@@ -40,6 +40,10 @@
+ #include <limits.h>
+ #include <math.h>
+ #include <float.h>
++#include <time.h>
++#include <unistd.h>
++#include <fcntl.h>
++#include <pthread.h>
+ 
+ #include "jv_alloc.h"
+ #include "jv.h"
+@@ -1170,7 +1174,33 @@ static jv jvp_string_append(jv string, const char* data, uint32_t len) {
+   }
+ }
+ 
+-static const uint32_t HASH_SEED = 0x432A9843;
++static uint32_t hash_seed;
++static pthread_once_t hash_seed_once = PTHREAD_ONCE_INIT;
++
++static void jvp_hash_seed_init(void) {
++  uint32_t seed;
++#if defined(HAVE_ARC4RANDOM)
++  seed = arc4random();
++#elif defined(HAVE_GETENTROPY)
++  if (getentropy(&seed, sizeof(seed)) != 0)
++    seed = (uint32_t)getpid() ^ (uint32_t)time(NULL);
++#else
++  int fd = open("/dev/urandom", O_RDONLY);
++  if (fd >= 0) {
++    if (read(fd, &seed, sizeof(seed)) != 4)
++      seed = (uint32_t)getpid() ^ (uint32_t)time(NULL);
++    close(fd);
++  } else {
++    seed = (uint32_t)getpid() ^ (uint32_t)time(NULL);
++  }
++#endif
++  hash_seed = seed;
++}
++
++static uint32_t jvp_hash_seed(void) {
++  pthread_once(&hash_seed_once, jvp_hash_seed_init);
++  return hash_seed;
++}
+ 
+ static uint32_t rotl32 (uint32_t x, int8_t r){
+   return (x << r) | (x >> (32 - r));
+@@ -1189,7 +1219,7 @@ static uint32_t jvp_string_hash(jv jstr) {
+   int len = (int)jvp_string_length(str);
+   const int nblocks = len / 4;
+ 
+-  uint32_t h1 = HASH_SEED;
++  uint32_t h1 = jvp_hash_seed();
+ 
+   const uint32_t c1 = 0xcc9e2d51;
+   const uint32_t c2 = 0x1b873593;
diff -Nru jq-1.7.1/debian/patches/series jq-1.7.1/debian/patches/series
--- jq-1.7.1/debian/patches/series	2025-07-08 00:16:39.000000000 +0800
+++ jq-1.7.1/debian/patches/series	2026-04-17 17:08:56.000000000 +0800
@@ -7,3 +7,8 @@
 CVE-2024-53427.patch
 CVE-2024-23337.patch
 CVE-2025-48060.patch
+CVE-2026-33947.patch
+CVE-2026-33948.patch
+CVE-2026-39956.patch
+CVE-2026-39979.patch
+CVE-2026-40164.patch

Attachment: signature.asc
Description: PGP signature

Reply via email to