[Devel] [PATCH vz10 v3] lib/zlib: use atomic GCOV counters to prevent crash in inflate_fast

Vasileios Almpanis vasileios.almpanis at virtuozzo.com
Fri Mar 27 12:38:34 MSK 2026


Reviewed-by: Vasileios Almpanis <vasileios.almpanis.virtuozzo.com>

On 3/26/26 6:50 PM, Konstantin Khorenko wrote:
> GCC's GCOV instrumentation can merge global branch counters with loop
> induction variables as an optimization.  In inflate_fast(), the inner
> copy loops get transformed so that the GCOV counter value is loaded
> multiple times to compute the loop base address, start index, and end
> bound.  Since GCOV counters are global (not per-CPU), concurrent
> execution on different CPUs causes the counter to change between loads,
> producing inconsistent values 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
>
> At the crash point, the compiler generated three loads from the same
> global GCOV counter (__gcov0.inflate_fast+216) to compute base, start,
> and end for an indexed loop.  Another CPU modified the counter between
> loads, making the values inconsistent — the write went 3.4 MB past a
> 65 KB buffer.
>
> 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 avoid unnecessary
> overhead in the rest of the kernel.
>
> https://virtuozzo.atlassian.net/browse/VSTOR-127788
>
> Feature: fix selftests
> Signed-off-by: Konstantin Khorenko <khorenko at 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 \


More information about the Devel mailing list