Resolves: RHEL-45756 - Varnish consumes significantly more memory

under RHEL8/9
This commit is contained in:
Luboš Uhliarik 2025-06-11 20:35:46 +02:00
parent ccfa6b1033
commit 19ddc52756
5 changed files with 294 additions and 5 deletions

1
.gitignore vendored
View File

@ -65,3 +65,4 @@ varnish-2.1.3.tar.gz
/varnish-7.6.0.tgz
/pkg-varnish-cache-7d90347.tar.gz
/varnish-7.6.1.tgz
/jemalloc-5.3.0.tar.bz2

View File

@ -0,0 +1,140 @@
diff --git a/test/unit/psset.c b/test/unit/psset.c
index 6ff7201..58b4a88 100644
--- a/test/unit/psset.c
+++ b/test/unit/psset.c
@@ -124,7 +124,7 @@ TEST_BEGIN(test_fill) {
hpdata_t pageslab;
hpdata_init(&pageslab, PAGESLAB_ADDR, PAGESLAB_AGE);
- edata_t alloc[HUGEPAGE_PAGES];
+ edata_t *alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
psset_t psset;
psset_init(&psset);
@@ -147,6 +147,8 @@ TEST_BEGIN(test_fill) {
edata_init_test(&extra_alloc);
err = test_psset_alloc_reuse(&psset, &extra_alloc, PAGE);
expect_true(err, "Alloc succeeded even though psset should be empty");
+
+ free(alloc);
}
TEST_END
@@ -157,7 +159,7 @@ TEST_BEGIN(test_reuse) {
hpdata_t pageslab;
hpdata_init(&pageslab, PAGESLAB_ADDR, PAGESLAB_AGE);
- edata_t alloc[HUGEPAGE_PAGES];
+ edata_t *alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
psset_t psset;
psset_init(&psset);
@@ -239,6 +241,8 @@ TEST_BEGIN(test_reuse) {
err = test_psset_alloc_reuse(&psset, &alloc[index_of_4], 4 * PAGE);
expect_false(err, "Should have been able to find alloc.");
edata_expect(&alloc[index_of_4], index_of_4, 4);
+
+ free(alloc);
}
TEST_END
@@ -249,7 +253,7 @@ TEST_BEGIN(test_evict) {
hpdata_t pageslab;
hpdata_init(&pageslab, PAGESLAB_ADDR, PAGESLAB_AGE);
- edata_t alloc[HUGEPAGE_PAGES];
+ edata_t *alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
psset_t psset;
psset_init(&psset);
@@ -273,6 +277,8 @@ TEST_BEGIN(test_evict) {
err = test_psset_alloc_reuse(&psset, &alloc[0], PAGE);
expect_true(err, "psset should be empty.");
+
+ free(alloc);
}
TEST_END
@@ -286,7 +292,9 @@ TEST_BEGIN(test_multi_pageslab) {
(void *)((uintptr_t)PAGESLAB_ADDR + HUGEPAGE),
PAGESLAB_AGE + 1);
- edata_t alloc[2][HUGEPAGE_PAGES];
+ edata_t* alloc[2];
+ alloc[0] = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
+ alloc[1] = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
psset_t psset;
psset_init(&psset);
@@ -336,6 +344,9 @@ TEST_BEGIN(test_multi_pageslab) {
*/
err = test_psset_alloc_reuse(&psset, &alloc[1][0], 2 * PAGE);
expect_false(err, "Allocation should have succeeded");
+
+ free(alloc[0]);
+ free(alloc[1]);
}
TEST_END
@@ -385,7 +396,7 @@ TEST_BEGIN(test_stats) {
hpdata_t pageslab;
hpdata_init(&pageslab, PAGESLAB_ADDR, PAGESLAB_AGE);
- edata_t alloc[HUGEPAGE_PAGES];
+ edata_t *alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
psset_t psset;
psset_init(&psset);
@@ -415,6 +426,8 @@ TEST_BEGIN(test_stats) {
stats_expect(&psset, 0);
psset_update_end(&psset, &pageslab);
stats_expect(&psset, 1);
+
+ free(alloc);
}
TEST_END
@@ -475,8 +488,8 @@ init_test_pageslabs(psset_t *psset, hpdata_t *pageslab,
TEST_BEGIN(test_oldest_fit) {
bool err;
- edata_t alloc[HUGEPAGE_PAGES];
- edata_t worse_alloc[HUGEPAGE_PAGES];
+ edata_t *alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
+ edata_t *worse_alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
hpdata_t pageslab;
hpdata_t worse_pageslab;
@@ -493,14 +506,19 @@ TEST_BEGIN(test_oldest_fit) {
expect_false(err, "Nonempty psset failed page allocation");
expect_ptr_eq(&pageslab, edata_ps_get(&test_edata),
"Allocated from the wrong pageslab");
+
+ free(alloc);
+ free(worse_alloc);
}
TEST_END
TEST_BEGIN(test_insert_remove) {
bool err;
hpdata_t *ps;
- edata_t alloc[HUGEPAGE_PAGES];
- edata_t worse_alloc[HUGEPAGE_PAGES];
+
+ edata_t *alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
+ edata_t *worse_alloc = (edata_t *)malloc(sizeof(edata_t) * HUGEPAGE_PAGES);
+
hpdata_t pageslab;
hpdata_t worse_pageslab;
@@ -539,6 +557,9 @@ TEST_BEGIN(test_insert_remove) {
psset_update_begin(&psset, &worse_pageslab);
err = test_psset_alloc_reuse(&psset, &alloc[HUGEPAGE_PAGES - 1], PAGE);
expect_true(err, "psset should be empty, but an alloc succeeded");
+
+ free(alloc);
+ free(worse_alloc);
}
TEST_END

View File

@ -0,0 +1,29 @@
commit 3de0c24859f4413bf03448249078169bb50bda0f
Author: divanorama <divanorama@gmail.com>
Date: Thu Sep 29 23:35:59 2022 +0200
Disable builtin malloc in tests
With `--with-jemalloc-prefix=` and without `-fno-builtin` or `-O1` both clang and gcc may optimize out `malloc` calls
whose result is unused. Comparing result to NULL also doesn't necessarily count as being used.
This won't be a problem in most client programs as this only concerns really unused pointers, but in
tests it's important to actually execute allocations.
`-fno-builtin` should disable this optimization for both gcc and clang, and applying it only to tests code shouldn't hopefully be an issue.
Another alternative is to force "use" of result but that'd require more changes and may miss some other optimization-related issues.
This should resolve https://github.com/jemalloc/jemalloc/issues/2091
diff --git a/Makefile.in b/Makefile.in
index 6809fb29..a964f07e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -458,6 +458,8 @@ $(TESTS_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c
$(TESTS_CPP_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.cpp
$(TESTS_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include
$(TESTS_CPP_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include
+$(TESTS_OBJS): CFLAGS += -fno-builtin
+$(TESTS_CPP_OBJS): CPPFLAGS += -fno-builtin
ifneq ($(IMPORTLIB),$(SO))
$(CPP_OBJS) $(C_SYM_OBJS) $(C_OBJS) $(C_JET_SYM_OBJS) $(C_JET_OBJS): CPPFLAGS += -DDLLEXPORT
endif

View File

@ -1,2 +1,3 @@
SHA512 (varnish-7.6.1.tgz) = a43ecdcc5a113b947d56a7f28d756199c82e702a0e98bbad635a5df4739c50aaf778143dee3acf57d586569b780615ed73996df71488e4f776fb515f206b7fca
SHA512 (pkg-varnish-cache-7d90347.tar.gz) = c5bf026bb50b416001d0e22e56c2774c143dab1f4658f03f1a4e6578369b71cfda5854b7d6b580c43c2ab8e68bfb9033b56734adfd29ac0fddc61fd6b1b4b0c0
SHA512 (jemalloc-5.3.0.tar.bz2) = 22907bb052096e2caffb6e4e23548aecc5cc9283dce476896a2b1127eee64170e3562fa2e7db9571298814a7a2c7df6e8d1fbe152bd3f3b0c1abec22a2de34b1

View File

@ -23,11 +23,24 @@
# Default: Use jemalloc, as adviced by upstream project
# Change to 1 to use system allocator (ie. glibc)
%if 0%{?rhel}
%bcond_without system_allocator
%if 0%{?rhel} > 9
# for rhel >= 10, use bundled jemalloc
%bcond_with system_allocator
%bcond_without bundled_jemalloc
%else
# for rhel <= 9, use system allocator
%bcond_without system_allocator
%bcond_with bundled_jemalloc
%endif
%else
%bcond_with system_allocator
# use jemalloc from repo
%bcond_with system_allocator
%bcond_with bundled_jemalloc
%endif
%define jemalloc_version 5.3.0
%define jemalloc_prefix varnish_
%if %{with system_allocator}
# use _lto_cflags if present
%else
@ -37,13 +50,20 @@
Summary: High-performance HTTP accelerator
Name: varnish
Version: 7.6.1
Release: 3%{?dist}
Release: 4%{?dist}
License: BSD-2-Clause AND (BSD-2-Clause-FreeBSD AND BSD-3-Clause AND LicenseRef-Fedora-Public-Domain AND Zlib)
URL: https://www.varnish-cache.org/
Source0: http://varnish-cache.org/_downloads/%{name}-%{version}.tgz
Source1: https://github.com/varnishcache/pkg-varnish-cache/archive/%{commit1}.tar.gz#/pkg-varnish-cache-%{shortcommit1}.tar.gz
Source2: https://github.com/jemalloc/jemalloc/releases/download/%{jemalloc_version}/jemalloc-%{jemalloc_version}.tar.bz2
# Patches:
%if %{with bundled_jemalloc}
# bundled jemalloc patch
Patch1: jemalloc-5.3.0_fno-builtin.patch
Patch2: jemalloc-5.3.0-aarch64-ts-segfault.patch
%endif
# https://bugzilla.redhat.com/show_bug.cgi?id=2364235
Patch100: varnish-7.6.1-CVE-2025-47905.patch
@ -64,6 +84,10 @@ Provides: vmod(unix)%{_isa} = %{version}-%{release}
Provides: vmod(vtc)%{_isa} = %{version}-%{release}
%endif
%if %{with bundled_jemalloc}
Provides: bundled(jemalloc)
%endif
%if 0%{?rhel} == 7
BuildRequires: python34 python34-sphinx python34-docutils
@ -74,10 +98,12 @@ BuildRequires: gcc
%if %{with system_allocator}
# use glibc
%else
%if %{without bundled_jemalloc}
%ifnarch aarch64
BuildRequires: jemalloc-devel
%endif
%endif
%endif
BuildRequires: libedit-devel
BuildRequires: make
@ -86,6 +112,11 @@ BuildRequires: pcre2-devel
BuildRequires: pkgconfig
BuildRequires: systemd-units
%if %{with bundled_jemalloc}
BuildRequires: /usr/bin/xsltproc
BuildRequires: perl-generators
%endif
# Extra requirements for the build suite
# needs haproxy2
%if 0%{?fedora} > 30 || 0%{?rhel} > 8
@ -109,8 +140,10 @@ Requires(postun): systemd-units
%if %{with system_allocator}
# use glibc
%else
%if %{without bundled_jemalloc}
Requires: jemalloc
%endif
%endif
%description
This is Varnish Cache, a high-performance HTTP accelerator.
@ -152,7 +185,55 @@ sed -i 's,rst2man-3.6,rst2man-3.4,g; s,rst2html-3.6,rst2html-3.4,g; s,phinx-buil
%patch 100 -p1 -b .CVE-2022-45060
# jemalloc
%if %{with bundled_jemalloc}
tar xjf %SOURCE2
sed -i '/^LIBPREFIX/s/@libprefix@/@libprefix@%{jemalloc_prefix}/' jemalloc*/Makefile.in
pushd jemalloc*
%patch 1 -p1 -b .jemalloc
%patch 2 -p1 -b .ts-segfault
popd
# Override PAGESIZE, bz #1545539
%ifarch %ix86 %arm x86_64 s390x riscv64
%define lg_page --with-lg-page=12
%endif
%ifarch ppc64 ppc64le aarch64
%define lg_page --with-lg-page=16
%endif
# Disable thp on systems not supporting this for now
%ifarch %ix86 %arm aarch64 s390x
%define disable_thp --disable-thp
%endif
%endif
%build
%if %{with bundled_jemalloc}
# build bundled jemalloc first
pushd jemalloc*
echo "For debugging package builders"
echo "What is the pagesize?"
getconf PAGESIZE
echo "What mm features are available?"
ls /sys/kernel/mm
ls /sys/kernel/mm/transparent_hugepage || true
cat /sys/kernel/mm/transparent_hugepage/enabled || true
echo "What kernel version and config is this?"
uname -a
%configure %{?disable_thp} %{?lg_page} --enable-prof
make %{?_smp_mflags}
popd
%endif
# varnish
%if %{with system_allocator}
export CFLAGS="%{optflags}"
%else
@ -186,6 +267,14 @@ export RST2MAN=/bin/true
# Explicit python, please
export PYTHON=%{__python}
for f in configure configure.ac; do
sed -i 's|ljemalloc|l%{jemalloc_prefix}jemalloc|g' $f
done
%if %{with bundled_jemalloc}
export LDFLAGS="$LDFLAGS -L%{_builddir}/%{name}-%{version}/jemalloc-%{jemalloc_version}/lib"
%endif
%configure LT_SYS_LIBRARY_PATH=%_libdir \
--disable-static \
--localstatedir=/var/lib \
@ -196,10 +285,13 @@ export PYTHON=%{__python}
--enable-pcre2-jit=no \
%endif
%endif
%if %{with system_allocator}
%if %{with system_allocator} || %{without bundled_jemalloc}
--with-jemalloc=no \
%endif
%if %{with bundled_jemalloc}
export LD_LIBRARY_PATH=%{_builddir}/%{name}-%{version}/jemalloc-%{jemalloc_version}/lib
%endif
%make_build
# One varnish user is enough
@ -209,23 +301,45 @@ sed -i 's,User=varnishlog,User=varnish,g;' redhat/varnishncsa.service
rm -rf doc/html/_sources
%check
# check jemalloc first
%if %{with bundled_jemalloc}
pushd jemalloc*
make %{?_smp_mflags} check
popd
%endif
# Up the stack size in tests, necessary on secondary arches
sed -i 's/thread_pool_stack 80k/thread_pool_stack 128k/g;' bin/varnishtest/tests/*.vtc
sed -i 's/file,2M/file,8M/' bin/varnishtest/tests/r04036.vtc
%if %{with bundled_jemalloc}
export LD_LIBRARY_PATH=%{_builddir}/%{name}-%{version}/jemalloc-%{jemalloc_version}/lib
%endif
# Just a hack to avoid too high load on secondary arch builders
%ifarch s390x ppc64le
# This works when ran alone, but not in the whole suite. Load and/or timing issues
rm bin/varnishtest/tests/t02014.vtc
make -j2 check
%else
#make_build check
%make_build check
%endif
%install
rm -rf %{buildroot}
# jemalloc
%if %{with bundled_jemalloc}
pushd jemalloc*
make DESTDIR=%{buildroot} install_lib %{?_smp_mflags}
find %{buildroot}%{_libdir}/ -name '*.a' -exec rm -vf {} ';'
# we don't need .pc file
rm %{buildroot}%{_libdir}/pkgconfig/jemalloc.pc
popd
%endif
# mock el7 defaults to LANG=C, which makes python3 fail when parsing utf8 text
%if 0%{?rhel} == 7
export LANG=en_US.UTF-8
@ -319,6 +433,10 @@ test -f /etc/varnish/secret || (uuidgen > /etc/varnish/secret && chmod 0600 /etc
%changelog
* Wed Jun 11 2025 Luboš Uhliarik <luhliari@redhat.com> - 7.6.1-4
- Resolves: RHEL-45756 - Varnish consumes significantly more memory
under RHEL8/9
* Tue May 20 2025 Luboš Uhliarik <luhliari@redhat.com> - 7.6.1-3
- Resolves: RHEL-89691 - varnish: request smuggling attacks (CVE-2025-47905)