[PATCH gnupg v13] Disable CPU speculation-related misfeatures
Guido Trentalancia
guido at trentalancia.com
Thu Jul 10 17:14:27 CEST 2025
On Thu, 10/07/2025 at 15.19 +0200, Werner Koch wrote:
> On Thu, 10 Jul 2025 12:41, Guido Trentalancia said:
>
> > I have tested the patch and the logging functions work as I would
> > expect. They might need to be initialized before
> > early_system_init(),
>
> That is a catch-22 - early_system_init is supposed to be the very
> first
> thing done after main(). If you want to catch errors, use abort() or
> store the the error and retrieve it after the logging has been
> enabled.
> This would be similar to the secmem handling done in GnuPG. It might
> even be useful to do the whole thing as part of the secmem thing -
> this
> is also a critical thing and we have quite some experience on how to
> get
> this right over all the components.
I have switched to simple printf() calls in a new v13 patch, which is
also my last attempt to fix this.
> > 2017, leaving the program vulnerable to data leaks for about 8
> > years !
>
> It is not the gpg or actually gpg-agent process which leaks the data
> but
> it is a properly of the CPU. If you can mount such an attack on
> highly
> sensitive data, that CPU might not be the right rig for you. In
> particular I would strongly advise not to process such secrets on a
> VM.
The three vulnerabilities have nothing to do with using a VM or "multi-
tenant systems": this is a very big misunderstanding !
This is very easy to understand by looking at the first table in https:
//msrc.microsoft.com/blog/2018/05/analysis-and-mitigation-of-
speculative-store-bypass-cve-2018-3639/
As you can see from the table, the orange areas (affected areas) are
not limited to those related to the use of Virtual Machines, the
vulnerability can be exploited at several Operating System levels
including process-to-process. So sensitive cryptographic data can be
leaked by the gpg process (or any other process dealing with encrypted
data) to any other process running in the system (not necessarily a
Virtual Machine). To make things simple to understand, the
vulnerability make it possible for a spying process to snoop on
sensitive data belonging to any other process.
Similar considerations can be made for the other two vulnerabilities.
> I would suggest to implement the whole stuff in the run-time loader
> and
> provide a way to configure which processes should do this. This way
> users can decide whether it is worth to disable these CPU-
> (mis)features
> mitigations.
>
> > That is the real problem !!
>
> The real problem is a over-complicated mitigation for a problem to be
> solved elsewhere.
If the above refers to the proposed patches, then it is just an
unfounded recrimination !
I am perfectly happy with the three simple prctl() calls that were
proposed in the initial patch on the 26th of May.
The Linux kernel documentation makes it pretty clear that the problem
needs to be tackled at the userspace level (by enabling specific kernel
fixes called "mitigations" for all cryptographic software running at
userspace level).
But just in case you prefer a patch which includes the improvements
against the several recriminations that were made, then I have prepared
a new v13 that follows. In the limited time that I can devote to this
problem, I am only interested in getting those security vulnerability
fixed by calling prctl() at the beginning of the program two or three
times, as prescribed in the Linux kernel documentation, with or without
all the introduced over-complications due to the several comments
received, so that those diseases are no longer inflicted on Linux
users.
common: Disable CPU speculative execution securityvulnerabilities (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-0550and check for sys/prctl.h on Linux
systems
* common/init.c (early_system_init): Disable CPUspeculative execution
security vulnerabilitiespotentially 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
and "nosmt l1d_flush=on" on the boot command line to mitigate the
vulnerability)
For further information see the kernel
documentation:Documentation/userspace-
api/spec_ctrl.rstDocumentation/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 202
5-05-25 15:43:45.871984100 +0200+++ b/common/init.c 2025-07-09
13:39:44.036998821 +0200@@ -29,6 +29,14 @@ #include <config.h> +#if
defined(__linux__) && defined(HAVE_SYS_PRCTL_H)+# include
<sys/prctl.h>+#endif++#if defined(ENABLE_L1D_CACHE_FLUSH)+# include
<signal.h>+#endif+ #ifdef HAVE_W32_SYSTEM # if _WIN32_WINNT < 0x0600
# define _WIN32_WINNT 0x0600 /* Required for
SetProcessDEPPolicy. */@@ -128,10 +136,68 @@ writestring_via_estream
(int mode, const } +#ifdef ENABLE_L1D_CACHE_FLUSH+void sigbus_handler
(int signo)+{+ if (signo == SIGBUS)+ {+ printf ("Fatal: Level
1 Data Cache flushing requires the \"nosmt\" boot
parameter.\n");+ exit (SIGBUS);+ }+}+#endif++ /* This function
should be the first called after main. */ void early_system_init
(void) {+#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H)++/*
Disable CPU speculative execution security vulnerabilities+ * causing
data leaks: see the Linux kernel documentation+ *
Documentation/userspace-api/spec_ctrl.rst+ *+ * - Speculative Store
Bypass (CVE-2018-3639, always+ * disabled)+ * - Indirect Branch
Speculation (CVE-2017-5715, always+ * disabled)+ * - Flush L1D Cache
on context switch out of the task (it+ * requires the "nosmt
l1d_flush=on" kernel boot parameter)+ */+#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)+ struct
sigaction old_action, new_action;++ new_action.sa_handler =
sigbus_handler;+ sigemptyset
(&new_action.sa_mask);+ new_action.sa_flags = 0;++ sigaction (SIGBUS,
NULL, &old_action);+ if (old_action.sa_handler !=
SIG_IGN)+ {+ if (sigaction (SIGBUS, &new_action, NULL) ==
-1)+ {+ printf ("Warning: cannot catch the SIGBUS
signal.\n");+ }+ }++ if (prctl (PR_SET_SPECULATION_CTRL,
PR_SPEC_L1D_FLUSH, PR_SPEC_ENABLE, 0, 0) < 0)+ {+ printf
("Warning: Level 1 Data Cache flushing requires the \"l1d_flush=on\"
boot parameter.\n");+ }++ sigaction (SIGBUS, &old_action,
NULL);+#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-08
21:32:32.674405293 +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,16 @@ 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])+ AC_CHECK_HEADERS([signal.h])+fi+++# #
Checks for header files. # AC_MSG_NOTICE([checking for header files])@@
-1322,6 +1342,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. #
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.gnupg.org/pipermail/gnupg-devel/attachments/20250710/9bf35081/attachment-0001.html>
More information about the Gnupg-devel
mailing list