Files
buildroot/package/jq/0005-randomize-hash-seed-to-mitigate-hash-collision-DoS-attacks.patch
Thomas Perale e8191c3e17 package/jq: patch various CVEs
Fixes the following vulnerabilities by importing upstream patches:

- CVE-2026-39979: 2f09060afa

- CVE-2026-33948: 6374ae0bcd

- CVE-2026-33947: fb59f14910

- CVE-2026-32316: e47e56d226

- CVE-2026-40164: 0c7d133c3c

- CVE-2026-40612: d1a12569d9

- CVE-2026-41256: 5a015deae3

- CVE-2026-41257: 01b3cded76

- CVE-2026-43894: 9761ceb7d6

- CVE-2026-43895: 9d223f153c

- CVE-2026-43896: 532ccea608

- CVE-2026-44777: f58787c418

- CVE-2026-47770: 7122866869

- CVE-2026-49839: e987df0d46

- CVE-2026-54679: 46d1da3094

Tests were stripped out of the patches.

Signed-off-by: Thomas Perale <thomas.perale@mind.be>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
2026-07-02 08:32:30 +02:00

91 lines
3.0 KiB
Diff

From 0c7d133c3c7e37c00b6d46b658a02244fdd3c784 Mon Sep 17 00:00:00 2001
From: itchyny <itchyny@cybozu.co.jp>
Date: Mon, 13 Apr 2026 08:53:26 +0900
Subject: [PATCH] Randomize hash seed to mitigate hash collision DoS attacks
The hash function used a fixed seed, allowing attackers to craft colliding keys
and cause O(n^2) object parsing performance. Initialize the seed from a random
source at process startup to prevent the attack. This fixes CVE-2026-40164.
Co-authored-by: Asaf Meizner <asafmeizner@gmail.com>
CVE: CVE-2026-40164
Upstream: https://github.com/jqlang/jq/commit/0c7d133c3c7e37c00b6d46b658a02244fdd3c784
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
---
configure.ac | 2 ++
src/jv.c | 34 ++++++++++++++++++++++++++++++++--
2 files changed, 34 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 5dac42655a..f7067a4341 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,6 +143,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 2a62b48419..607ac174f7 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"
@@ -1206,7 +1210,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));
@@ -1225,7 +1255,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;