[PATCH gnupg v6] Disable CPU speculation-related misfeatures

Guido Trentalancia guido at trentalancia.com
Mon Jul 7 19:17:54 CEST 2025


On Mon, 07/07/2025 alle 18.36 +0200, Werner Koch wrote:
> Hi!
> 
> On Sun,  6 Jul 2025 21:50, Guido Trentalancia said:
> 
> > common: Disable CPU speculation-related misfeatures
> 
> I would prefer to keep the subject clear of an opinion.

It's not an opinion, it's a fact.

The wording is taken from the official Linux kernel documentation,
however I agree it's probably too delicate, the correct wording is
"security vulnerabilities".

> > +#if defined(__linux__)
> > +# include <sys/prctl.h>
> > +#endif
> 
> Good.  You now provide configure tests.  Please also add a general
> one
> which checks for this header.

A general check for sys/prctl.h is not needed, as such header file is
only used on Linux-specific code and it can therefore break things on
non-Linux systems.

> > +#if defined(__linux__)
> 
> And use that here ;-)
> 
> >  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])
> 
> Hey, you already got that macro.  Thus you can replace the above with
> 
>   #if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)

I can replace that, in reversed order. Please see the v6 patch below,
my last attempt at fixing this...

> and we are good.  The ifdef __linux__ here is so that we cater for
> OSes
> which have such a header for different purposes.  Using the standard
> configure test along with a ifdef in the code is a good compromise
> between readibility and regualar autoconf style.

common: Disable CPU speculation-related security
vulnerabilities (CVE-2018-3639 aka Spectre variant 4,
CVE-2017-5715 and optionally CVE-2020-0550)

* 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-07 19:02:08.478853360 +0200
@@ -29,6 +29,10 @@
 
 #include <config.h>
 
+#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H)
+# 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__) && defined(HAVE_SYS_PRCTL_H)
+
+/* Disable CPU speculation-related security vulnerabilities
+ * causing data leaks: see the Linux 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__ && HAVE_SYS_PRCTL_H */
 }
 
 
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.
 #



More information about the Gnupg-devel mailing list