public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Konstantin Khorenko <khorenko@virtuozzo.com>
To: Peter Oberparleiter <oberpar@linux.ibm.com>,
	Mikhail Zaslonko <zaslonko@linux.ibm.com>
Cc: Steffen Klassert <steffen.klassert@secunet.com>,
	Herbert Xu <herbert@gondor.apana.org.au>,
	Masahiro Yamada <masahiroy@kernel.org>,
	Josh Poimboeuf <jpoimboe@kernel.org>,
	Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>,
	Pavel Tikhomirov <ptikhomirov@virtuozzo.com>,
	linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
	Konstantin Khorenko <khorenko@virtuozzo.com>
Subject: [PATCH 1/1] lib/zlib: use atomic GCOV counters to prevent crash in inflate_fast
Date: Mon, 30 Mar 2026 16:32:55 +0200	[thread overview]
Message-ID: <20260330143256.306326-2-khorenko@virtuozzo.com> (raw)
In-Reply-To: <20260330143256.306326-1-khorenko@virtuozzo.com>

GCC's GCOV instrumentation can merge global branch counters with loop
induction variables as an optimization. In inflate_fast(), the inner
copy loops can be transformed so that GCOV counter values participate
in computing loop addresses and bounds. Since GCOV counters are global
(not per-CPU), concurrent execution on different CPUs causes the counter
to change mid-computation, producing inconsistent address calculations
and out-of-bounds memory writes.

The crash manifests during IPComp (IP Payload Compression) processing
when inflate_fast() runs concurrently on multiple CPUs:

  BUG: unable to handle page fault for address: ffffd0a3c0902ffa
  RIP: inflate_fast+1431
  Call Trace:
   zlib_inflate
   __deflate_decompress
   crypto_comp_decompress
   ipcomp_decompress [xfrm_ipcomp]
   ipcomp_input [xfrm_ipcomp]
   xfrm_input

In one observed case, the compiler merged a global GCOV counter with the
loop induction variable that also indexed stores. Another CPU modified
the counter between the setup and iteration phases, causing a write
3.4 MB past the end of a 65 KB buffer.

The kernel already uses -fno-tree-loop-im for GCOV builds (commit
2b40e1ea76d4) to prevent a different optimization issue. That flag
prevents GCC from hoisting loop-invariant memory operations but does
NOT prevent the IVopts pass from merging counters with induction
variables.

Add -fprofile-update=atomic to zlib Makefiles. This tells GCC that
GCOV counters may be concurrently accessed, causing counter updates to
use atomic instructions (lock addq) instead of plain load/store.
This prevents the compiler from merging counters with loop induction
variables. The flag is scoped to zlib only to minimize performance
overhead from atomic operations in the rest of the kernel.

Signed-off-by: Konstantin Khorenko <khorenko@virtuozzo.com>
Reviewed-by: Vasileios Almpanis <vasileios.almpanis@virtuozzo.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 lib/zlib_deflate/Makefile | 6 ++++++
 lib/zlib_dfltcc/Makefile  | 6 ++++++
 lib/zlib_inflate/Makefile | 7 +++++++
 3 files changed, 19 insertions(+)

diff --git a/lib/zlib_deflate/Makefile b/lib/zlib_deflate/Makefile
index 2622e03c0b942..dc0b3e5660e9e 100644
--- a/lib/zlib_deflate/Makefile
+++ b/lib/zlib_deflate/Makefile
@@ -7,6 +7,12 @@
 # decompression code.
 #
 
+# Force atomic GCOV counter updates to prevent GCC from merging global
+# counters with loop induction variables (see lib/zlib_inflate/Makefile).
+ifdef CONFIG_GCOV_KERNEL
+ccflags-y += -fprofile-update=atomic
+endif
+
 obj-$(CONFIG_ZLIB_DEFLATE) += zlib_deflate.o
 
 zlib_deflate-objs := deflate.o deftree.o deflate_syms.o
diff --git a/lib/zlib_dfltcc/Makefile b/lib/zlib_dfltcc/Makefile
index 66e1c96387c40..fb08749d2ee7b 100644
--- a/lib/zlib_dfltcc/Makefile
+++ b/lib/zlib_dfltcc/Makefile
@@ -6,6 +6,12 @@
 # This is the code for s390 zlib hardware support.
 #
 
+# Force atomic GCOV counter updates to prevent GCC from merging global
+# counters with loop induction variables (see lib/zlib_inflate/Makefile).
+ifdef CONFIG_GCOV_KERNEL
+ccflags-y += -fprofile-update=atomic
+endif
+
 obj-$(CONFIG_ZLIB_DFLTCC) += zlib_dfltcc.o
 
 zlib_dfltcc-objs := dfltcc.o dfltcc_deflate.o dfltcc_inflate.o
diff --git a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile
index 27327d3e9f541..8707c649adda5 100644
--- a/lib/zlib_inflate/Makefile
+++ b/lib/zlib_inflate/Makefile
@@ -14,6 +14,13 @@
 # uncompression can be done without blocking on allocation).
 #
 
+# Force atomic GCOV counter updates to prevent GCC from merging global
+# counters with loop induction variables — concurrent inflate_fast()
+# execution on multiple CPUs causes out-of-bounds writes otherwise.
+ifdef CONFIG_GCOV_KERNEL
+ccflags-y += -fprofile-update=atomic
+endif
+
 obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o
 
 zlib_inflate-objs := inffast.o inflate.o infutil.o \
-- 
2.43.0


  reply	other threads:[~2026-03-30 14:33 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-30 14:32 [PATCH 0/1] lib/zlib: fix GCOV-induced crashes from concurrent inflate_fast() Konstantin Khorenko
2026-03-30 14:32 ` Konstantin Khorenko [this message]
2026-04-01  9:44   ` [PATCH 1/1] lib/zlib: use atomic GCOV counters to prevent crash in inflate_fast Peter Oberparleiter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260330143256.306326-2-khorenko@virtuozzo.com \
    --to=khorenko@virtuozzo.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=jpoimboe@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=masahiroy@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=oberpar@linux.ibm.com \
    --cc=ptikhomirov@virtuozzo.com \
    --cc=steffen.klassert@secunet.com \
    --cc=vasileios.almpanis@virtuozzo.com \
    --cc=zaslonko@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox