- Fix denial of service vulnerability in mjson library (CVE-2025-11230)
Resolves: RHEL-126665
This commit is contained in:
parent
7b357ee235
commit
66b59faded
@ -0,0 +1,86 @@
|
||||
From: Willy Tarreau <w@1wt.eu>
|
||||
Date: Mon, 29 Sep 2025 16:34:11 +0000 (+0200)
|
||||
Subject: BUG/CRITICAL: mjson: fix possible DoS when parsing numbers
|
||||
X-Git-Tag: v2.4.30~6
|
||||
X-Git-Url: http://git.haproxy.org/?p=haproxy-2.4.git;a=commitdiff_plain;h=2b278798cbdf4a8596149b5769ca98b325acc535;hp=d258af5a33893e52504431a46b5ab50a807280b5
|
||||
|
||||
BUG/CRITICAL: mjson: fix possible DoS when parsing numbers
|
||||
|
||||
Mjson comes with its own strtod() implementation for portability
|
||||
reasons and probably also because many generic strtod() versions as
|
||||
provided by operating systems do not focus on resource preservation
|
||||
and may call malloc(), which is not welcome in a parser.
|
||||
|
||||
The strtod() implementation used here apparently originally comes from
|
||||
https://gist.github.com/mattn/1890186 and seems to have purposely
|
||||
omitted a few parts that were considered as not needed in this context
|
||||
(e.g. skipping white spaces, or setting errno). But when subject to the
|
||||
relevant test cases of the designated file above, the current function
|
||||
provides the same results.
|
||||
|
||||
The aforementioned implementation uses pow() to calculate exponents,
|
||||
but mjson authors visibly preferred not to introduce a libm dependency
|
||||
and replaced it with an iterative loop in O(exp) time. The problem is
|
||||
that the exponent is not bounded and that this loop can take a huge
|
||||
amount of time. There's even an issue already opened on mjson about
|
||||
this: https://github.com/cesanta/mjson/issues/59. In the case of
|
||||
haproxy, fortunately, the watchdog will quickly stop a runaway process
|
||||
but this remains a possible denial of service.
|
||||
|
||||
A first approach would consist in reintroducing pow() like in the
|
||||
original implementation, but if haproxy is built without Lua nor
|
||||
51Degrees, -lm is not used so this will not work everywhere.
|
||||
|
||||
Anyway here we're dealing with integer exponents, so an easy alternate
|
||||
approach consists in simply using shifts and squares, to compute the
|
||||
exponent in O(log(exp)) time. Not only it doesn't introduce any new
|
||||
dependency, but it turns out to be even faster than the generic pow()
|
||||
(85k req/s per core vs 83.5k on the same machine).
|
||||
|
||||
This must be backported as far as 2.4, where mjson was introduced.
|
||||
|
||||
Many thanks to Oula Kivalo for reporting this issue.
|
||||
|
||||
CVE-2025-11230 was assigned to this issue.
|
||||
|
||||
(cherry picked from commit 06675db4bf234ed17e14305f1d59259d2fe78b06)
|
||||
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
|
||||
---
|
||||
|
||||
diff --git a/src/mjson.c b/src/mjson.c
|
||||
index 73b7a57..2a4106b 100644
|
||||
--- a/src/mjson.c
|
||||
+++ b/src/mjson.c
|
||||
@@ -767,11 +767,13 @@ static double mystrtod(const char *str, char **end) {
|
||||
|
||||
/* exponential part */
|
||||
if ((*p == 'E') || (*p == 'e')) {
|
||||
+ double exp, f;
|
||||
int i, e = 0, neg = 0;
|
||||
p++;
|
||||
if (*p == '-') p++, neg++;
|
||||
if (*p == '+') p++;
|
||||
while (is_digit(*p)) e = e * 10 + *p++ - '0';
|
||||
+ i = e;
|
||||
if (neg) e = -e;
|
||||
#if 0
|
||||
if (d == 2.2250738585072011 && e == -308) {
|
||||
@@ -785,8 +787,16 @@ static double mystrtod(const char *str, char **end) {
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
- for (i = 0; i < e; i++) d *= 10;
|
||||
- for (i = 0; i < -e; i++) d /= 10;
|
||||
+ /* calculate f = 10^i */
|
||||
+ exp = 10;
|
||||
+ f = 1;
|
||||
+ while (i > 0) {
|
||||
+ if (i & 1) f *= exp;
|
||||
+ exp *= exp;
|
||||
+ i >>= 1;
|
||||
+ }
|
||||
+ if (e > 0) d *= f;
|
||||
+ else if (e < 0) d /= f;
|
||||
a = p;
|
||||
} else if (p > str && !is_digit(*(p - 1))) {
|
||||
a = str;
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
Name: haproxy
|
||||
Version: 2.8.14
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Summary: HAProxy reverse proxy for high availability environments
|
||||
|
||||
License: GPLv2+
|
||||
@ -21,6 +21,7 @@ Source3: %{name}.logrotate
|
||||
Source4: %{name}.sysconfig
|
||||
Source5: %{name}.sysusers
|
||||
Source6: halog.1
|
||||
Patch0: RHEL-126665-CVE-2025-11230-fix-denial-of-service-vulnerability-in-mjson-library.patch
|
||||
|
||||
BuildRequires: gcc
|
||||
BuildRequires: lua-devel
|
||||
@ -50,6 +51,7 @@ availability environments. Indeed, it can:
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%autopatch -p1
|
||||
|
||||
%build
|
||||
make %{?_smp_mflags} CPU="generic" TARGET="linux-glibc" USE_OPENSSL=1 USE_PCRE2=1 USE_SLZ=1 USE_LUA=1 USE_CRYPT_H=1 USE_SYSTEMD=1 USE_LINUX_TPROXY=1 USE_GETADDRINFO=1 USE_PROMEX=1 ADDINC="%{build_cflags}" ADDLIB="%{build_ldflags}"
|
||||
@ -131,6 +133,10 @@ echo "d /var/lib/haproxy 0755 root root - -" > %{buildroot}%{_tmpfilesdir}/%{nam
|
||||
%{_tmpfilesdir}/%{name}.conf
|
||||
|
||||
%changelog
|
||||
* Thu Nov 6 2025 Oyvind Albrigtsen <oalbrigt@redhat.com> - 2.8.14-3
|
||||
- Fix denial of service vulnerability in mjson library (CVE-2025-11230)
|
||||
Resolves: RHEL-126665
|
||||
|
||||
* Tue Oct 21 2025 Oyvind Albrigtsen <oalbrigt@redhat.com> - 2.8.14-2
|
||||
- Add tmpfiles.d file to make systemd-tmpfiles create/set correct
|
||||
ownership/permissions of /var/lib/haproxy
|
||||
|
||||
Loading…
Reference in New Issue
Block a user