[PATCH gnupg v4] Disable CPU speculation-related misfeatures

Guido Trentalancia guido at trentalancia.com
Sun Jul 6 21:50:52 CEST 2025


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



More information about the Gnupg-devel mailing list