[PATCH gnupg v5] Disable CPU speculation-related misfeatures

Guido Trentalancia guido at trentalancia.com
Sun Jul 6 22:03:56 CEST 2025


Same as v4, but avoiding possible build failures on non-linux systems.

common: Disable CPU speculation-related misfeatures

* configure.ac: add a new L1D Cache flushing option
(--enable-l1d-cache-flushing) to fix CVE-2020-0550
and check for sys/prctl.h on Linux systems

* common/init.c (early_system_init): Disable CPU
speculation-related misfeatures which are in fact
vulnerabilities causing data leaks:

 - Speculative Store Bypass (always disabled)
 - Indirect Branch Speculation (always disabled)
 - Flush L1D Cache on context switch out of the
   task (use the --enable-l1d-cache-flushing
   configure option to mitigate the vulnerability)

For further information see the kernel documentation:
Documentation/userspace-api/spec_ctrl.rst
Documentation/admin-guide/hw-vuln/l1d_flush.rst

Signed-off-by: Guido Trentalancia <guido at trentalancia.com>

diff -pru a/common/init.c b/common/init.c
--- a/common/init.c	2025-05-25 15:43:45.871984100 +0200
+++ b/common/init.c	2025-07-06 18:24:18.564538076 +0200
@@ -29,6 +29,10 @@
 
 #include <config.h>
 
+#if defined(__linux__)
+# include <sys/prctl.h>
+#endif
+
 #ifdef HAVE_W32_SYSTEM
 # if _WIN32_WINNT < 0x0600
 #   define _WIN32_WINNT 0x0600  /* Required for SetProcessDEPPolicy.  */
@@ -132,6 +136,29 @@ writestring_via_estream (int mode, const
 void
 early_system_init (void)
 {
+#if defined(__linux__)
+
+/* Disable CPU speculation-related misfeatures which are in
+ * fact vulnerabilities causing data leaks: see the kernel
+ * documentation: Documentation/userspace-api/spec_ctrl.rst
+ *
+ * - Speculative Store Bypass
+ * - Indirect Branch Speculation
+ * - Flush L1D Cache on context switch out of the task
+ */
+#ifdef PR_SPEC_STORE_BYPASS
+  prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0);
+#endif
+
+#ifdef PR_SPEC_INDIRECT_BRANCH
+  prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH, PR_SPEC_FORCE_DISABLE, 0, 0);
+#endif
+
+#if defined(ENABLE_L1D_CACHE_FLUSH) && defined(PR_SPEC_L1D_FLUSH)
+  prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_L1D_FLUSH, PR_SPEC_ENABLE, 0, 0);
+#endif
+
+#endif /* __linux__ */
 }
 
 
diff -pru a/configure.ac b/configure.ac
--- a/configure.ac	2025-07-06 18:01:54.128546282 +0200
+++ b/configure.ac	2025-07-06 21:56:51.219048292 +0200
@@ -244,6 +244,16 @@ AC_ARG_ENABLE(selinux-support,
 AC_MSG_RESULT($selinux_support)
 
 
+# Fix security vulnerability CVE-2020-0550 by enabling
+# Level 1 Data Cache flushing on context switch.
+AC_MSG_CHECKING([whether Level 1 Data Cache is flushed on context switch])
+AC_ARG_ENABLE(l1d-cache-flushing,
+              AS_HELP_STRING([--enable-l1d-cache-flushing],
+                             [enable L1D cache flushing]),
+              l1d_cache_flushing=$enableval, l1d_cache_flushing=no)
+AC_MSG_RESULT($l1d_cache_flushing)
+
+
 AC_MSG_CHECKING([whether to allocate extra secure memory])
 AC_ARG_ENABLE(large-secmem,
               AS_HELP_STRING([--enable-large-secmem],
@@ -1313,6 +1323,15 @@ fi
 
 
 #
+# Level 1 Data Cache flushing on context switch (CVE-2020-0550)
+#
+if test "$l1d_cache_flushing" = yes ; then
+  AC_DEFINE(ENABLE_L1D_CACHE_FLUSH,1,
+          [Define to enable Layer 1 Data Cache flushing])
+fi
+
+
+#
 # Checks for header files.
 #
 AC_MSG_NOTICE([checking for header files])
@@ -1322,6 +1341,13 @@ AC_CHECK_HEADERS([unistd.h langinfo.h te
                   ucred.h sys/ucred.h sys/sysmacros.h sys/mkdev.h])
 
 
+# See whether libc supports the prctl()
+case "${host}" in
+    *-*-linux*)
+        AC_CHECK_HEADERS([sys/prctl.h])
+        ;;
+esac
+
 #
 # Checks for typedefs, structures, and compiler characteristics.
 #

On Sun, 06/07/2025 at 21.50 +0200, Guido Trentalancia via
Gnupg-devel wrote:
> The following new v4 version has been created taking into account
> more
> recent discussions on the L1 Data Cache vulnerability. It should
> cater
> to the needs of most users, while it can also be configured for
> special
> cases...
> 
> common: Disable CPU speculation-related misfeatures
> 
> * configure.ac: add a new L1D Cache flushing option
> (--enable-l1d-cache-flushing) to fix CVE-2020-0550
> and check for sys/prctl.h
> 
> * common/init.c (early_system_init): Disable CPU
> speculation-related misfeatures which are in fact
> vulnerabilities causing data leaks:
> 
>  - Speculative Store Bypass (always disabled)
>  - Indirect Branch Speculation (always disabled)
>  - Flush L1D Cache on context switch out of the
>    task (use the --enable-l1d-cache-flushing
>    configure option to mitigate the vulnerability)
> 
> For further information see the kernel documentation:
> Documentation/userspace-api/spec_ctrl.rst
> Documentation/admin-guide/hw-vuln/l1d_flush.rst
> 
> Signed-off-by: Guido Trentalancia <guido at trentalancia.com>
> 
> diff -pru a/common/init.c b/common/init.c
> --- a/common/init.c	2025-05-25 15:43:45.871984100 +0200
> +++ b/common/init.c	2025-07-06 18:24:18.564538076 +0200
> @@ -29,6 +29,10 @@
>  
>  #include <config.h>
>  
> +#if defined(__linux__)
> +# include <sys/prctl.h>
> +#endif
> +
>  #ifdef HAVE_W32_SYSTEM
>  # if _WIN32_WINNT < 0x0600
>  #   define _WIN32_WINNT 0x0600  /* Required for
> SetProcessDEPPolicy.  */
> @@ -132,6 +136,29 @@ writestring_via_estream (int mode, const
>  void
>  early_system_init (void)
>  {
> +#if defined(__linux__)
> +
> +/* Disable CPU speculation-related misfeatures which are in
> + * fact vulnerabilities causing data leaks: see the kernel
> + * documentation: Documentation/userspace-api/spec_ctrl.rst
> + *
> + * - Speculative Store Bypass
> + * - Indirect Branch Speculation
> + * - Flush L1D Cache on context switch out of the task
> + */
> +#ifdef PR_SPEC_STORE_BYPASS
> +  prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS,
> PR_SPEC_FORCE_DISABLE, 0, 0);
> +#endif
> +
> +#ifdef PR_SPEC_INDIRECT_BRANCH
> +  prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH,
> PR_SPEC_FORCE_DISABLE, 0, 0);
> +#endif
> +
> +#if defined(ENABLE_L1D_CACHE_FLUSH) && defined(PR_SPEC_L1D_FLUSH)
> +  prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_L1D_FLUSH, PR_SPEC_ENABLE,
> 0, 0);
> +#endif
> +
> +#endif /* __linux__ */
>  }
>  
>  
> diff -pru a/configure.ac b/configure.ac
> --- a/configure.ac	2025-07-06 18:01:54.128546282 +0200
> +++ b/configure.ac	2025-07-06 21:34:17.915056552 +0200
> @@ -244,6 +244,16 @@ AC_ARG_ENABLE(selinux-support,
>  AC_MSG_RESULT($selinux_support)
>  
>  
> +# Fix security vulnerability CVE-2020-0550 by enabling
> +# Level 1 Data Cache flushing on context switch.
> +AC_MSG_CHECKING([whether Level 1 Data Cache is flushed on context
> switch])
> +AC_ARG_ENABLE(l1d-cache-flushing,
> +              AS_HELP_STRING([--enable-l1d-cache-flushing],
> +                             [enable L1D cache flushing]),
> +              l1d_cache_flushing=$enableval, l1d_cache_flushing=no)
> +AC_MSG_RESULT($l1d_cache_flushing)
> +
> +
>  AC_MSG_CHECKING([whether to allocate extra secure memory])
>  AC_ARG_ENABLE(large-secmem,
>                AS_HELP_STRING([--enable-large-secmem],
> @@ -1313,13 +1323,23 @@ fi
>  
>  
>  #
> +# Level 1 Data Cache flushing on context switch (CVE-2020-0550)
> +#
> +if test "$l1d_cache_flushing" = yes ; then
> +  AC_DEFINE(ENABLE_L1D_CACHE_FLUSH,1,
> +          [Define to enable Layer 1 Data Cache flushing])
> +fi
> +
> +
> +#
>  # Checks for header files.
>  #
>  AC_MSG_NOTICE([checking for header files])
>  AC_CHECK_HEADERS([unistd.h langinfo.h termio.h locale.h \
>                    pwd.h inttypes.h signal.h sys/select.h sys/time.h
> \
>                    stdint.h signal.h termios.h \
> -                  ucred.h sys/ucred.h sys/sysmacros.h sys/mkdev.h])
> +                  ucred.h sys/ucred.h sys/sysmacros.h sys/mkdev.h \
> +                  sys/prctl.h])
>  
>  
>  #
> 
> On Sun, 06/07/2025 at 17.10 +0200, Guido Trentalancia via
> Gnupg-devel wrote:
> > Please note that Level 1 Data Cache flushing is disabled.
> > 
> > So, at the moment the corresponding vulnerability CVE-2020-0550 is
> > not
> > being addressed.
> > 
> > That specific part can be enabled at a later time with an
> > additional
> > patch, for example through a specific autoconf configure option
> > (say
> > --
> > enable-l1d-cache-flushing or --enable-fix-CVE-2020-0550).
> > 
> > Guido
> > 
> > On Sat, 05/07/2025 at 14.37 +0300, Jussi Kivilinna wrote:
> > > On 04/07/2025 17:00, Guido Trentalancia via Gnupg-devel wrote:
> > > > I have reformatted the commit log according to the gnupg coding
> > > > style
> > > > as in gnupg/doc/HACKING and created a v3 patch which follows.
> > > > 
> > > > common: Disable CPU speculation-related misfeatures
> > > > 
> > > > * common/init.c (early_system_init): Disable CPU
> > > > speculation-related misfeatures which are in fact
> > > > vulnerabilities causing data leaks:
> > > > 
> > > >   - Speculative Store Bypass
> > > >   - Indirect Branch Speculation
> > > >   - Flush L1D Cache on context switch out of the task
> > > > 
> > > > For further information see the kernel documentation:
> > > > Documentation/userspace-api/spec_ctrl.rst
> > > > 
> > > > Signed-off-by: Guido Trentalancia <guido at trentalancia.com>
> > > > 
> > > > diff -pru a/common/init.c b/common/init.c
> > > > --- a/common/init.c	2024-05-15 12:33:38.000000000 +0200
> > > > +++ b/common/init.c	2025-06-27 12:35:33.543235132 +0200
> > > > @@ -29,6 +29,10 @@
> > > >   
> > > >   #include <config.h>
> > > >   
> > > > +#if defined(__linux__)
> > > > +# include <sys/prctl.h>
> > > > +#endif
> > > > +
> > > >   #ifdef HAVE_W32_SYSTEM
> > > >   # if _WIN32_WINNT < 0x0600
> > > >   #   define _WIN32_WINNT 0x0600  /* Required for
> > > > SetProcessDEPPolicy.  */
> > > > @@ -131,6 +135,29 @@ writestring_via_estream (int mode, const
> > > >   void
> > > >   early_system_init (void)
> > > >   {
> > > > +#if defined(__linux__)
> > > > +
> > > > +/* Disable CPU speculation-related misfeatures which are in
> > > > + * fact vulnerabilities causing data leaks: see the kernel
> > > > + * documentation: Documentation/userspace-api/spec_ctrl.rst
> > > > + *
> > > > + * - Speculative Store Bypass
> > > > + * - Indirect Branch Speculation
> > > > + * - Flush L1D Cache on context switch out of the task
> > > > + */
> > > > +#ifdef PR_SPEC_STORE_BYPASS
> > > > +  prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS,
> > > > PR_SPEC_FORCE_DISABLE, 0, 0);
> > > > +#endif
> > > > +
> > > > +#ifdef PR_SPEC_INDIRECT_BRANCH
> > > > +  prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_INDIRECT_BRANCH,
> > > > PR_SPEC_FORCE_DISABLE, 0, 0);
> > > > +#endif
> > > > +
> > > > +#ifdef PR_SPEC_L1D_FLUSH
> > > > +  prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_L1D_FLUSH,
> > > > PR_SPEC_FORCE_DISABLE, 0, 0);
> > > > +#endif
> > > 
> > > There is additional documentation of PR_SET_L1D_FLUSH at
> > >    https://docs.kernel.org/admin-guide/hw-vuln/l1d_flush.html
> > > 
> > > There's few limitations that might be interesting from gnupg
> > > point
> > > of
> > > view:
> > >   - "The kernel command line allows to control the L1D flush
> > > mitigations
> > >      at boot time with the option “l1d_flush=”.
> > >       on | Enables the prctl interface, applications trying to
> > > use
> > > the prctl()
> > >       will fail with an error if l1d_flush is not enabled
> > >      By default the mechanism is disabled."
> > >   - "NOTE : The opt-in of a task for L1D flushing works only when
> > > the
> > > task’s
> > >      affinity is limited to cores running in non-SMT mode. If a
> > > task
> > > which
> > >      requested L1D flushing is scheduled on a SMT-enabled core
> > > the
> > > kernel
> > >      sends a SIGBUS to the task."
> > > 
> > > Is it really good idea to just blindly enable this like done
> > > here? Is crashing on SIGBUS acceptable behavior?
> > > 
> > > I see that there was some heated discussion on this setting in
> > > linux
> > > kernel mailing list when there was first attempt to introduce
> > > this
> > > to kernel [1]. Which makes me wonder if changing this setting is
> > > good
> > > idea at all.
> > > 
> > > -Jussi
> > > 
> > > [1] https://lore.kernel.org/lkml/CAHk-=wgXf_wQ9zrJKv2Hy4EpEbLuqty
> > > -C
> > > jb
> > > s2u00gm7XcYHBfw at mail.gmail.com/
> > > 
> > > > +
> > > > +#endif /* __linux__ */
> > > >   }
> > > >   
> > > >   
> > > > 
> > > > On Thu, 03/07/2025 at 09.24 +0200, Werner Koch wrote:
> > > > > Hi!
> > > > > 
> > > > > I and other already explained that the way you propose the
> > > > > patches is
> > > > > not acceptable:
> > > > > 
> > > > > - No autoconf macros and possibly tests to decide whether to
> > > > > use
> > > > > the
> > > > >    feature.
> > > > > 
> > > > > - No proper ChangeLog (see gnupg/doc/HACKING)
> > > > > 
> > > > > 
> > > > > 
> > > > > Shalom-Salam,
> > > > > 
> > > > >     Werner
> > > > > 
> > > > 
> > > > _______________________________________________
> > > > Gnupg-devel mailing list
> > > > Gnupg-devel at gnupg.org
> > > > https://lists.gnupg.org/mailman/listinfo/gnupg-devel
> > > 
> > > 
> > 
> > _______________________________________________
> > Gnupg-devel mailing list
> > Gnupg-devel at gnupg.org
> > https://lists.gnupg.org/mailman/listinfo/gnupg-devel
> 
> _______________________________________________
> Gnupg-devel mailing list
> Gnupg-devel at gnupg.org
> https://lists.gnupg.org/mailman/listinfo/gnupg-devel



More information about the Gnupg-devel mailing list