Thanks for the feedback Jeff, I have now created a v15 patch which follows...
common: Disable CPU speculative execution 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 speculative execution security vulnerabilities potentially 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.rst Documentation/admin-guide/hw-vuln/l1d_flush.rst Signed-off-by: Guido Trentalancia <gu...@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-09 13:39:44.036998821 +0200 @@ -29,6 +29,16 @@ #include <config.h> +#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) +# include <sys/prctl.h> +#endif + +#if defined(ENABLE_L1D_CACHE_FLUSH) +# include "util.h" +# include "sysutils.h" +# include <signal.h> +#endif + #ifdef HAVE_W32_SYSTEM # if _WIN32_WINNT < 0x0600 # define _WIN32_WINNT 0x0600 /* Required for SetProcessDEPPolicy. */ @@ -128,10 +136,69 @@ writestring_via_estream (int mode, const } +#ifdef ENABLE_L1D_CACHE_FLUSH +#define SIGBUS_ERROR "Fatal: Level 1 Data Cache flushing requires the \"nosmt\" boot parameter.\n" +void sigbus_handler (int signo) +{ + if (signo == SIGBUS) + { + write (STDOUT_FILENO, SIGBUS_ERROR, strlen(SIGBUS_ERROR)); + 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; + + if (sigaction (SIGBUS, &new_action, &old_action) == -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"); + } + + gnupg_sleep (1); + if (sigaction (SIGBUS, &old_action, NULL) == -1) + { + printf ("Warning: cannot restore previous action on SIGBUS.\n"); + } +#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. # On Thu, 10/07/2025 at 13.51 -0400, Jeffrey Walton wrote: > On Thu, Jul 10, 2025 at 11:15 AM Guido Trentalancia via Gnupg-devel > <gnupg-devel@gnupg.org> wrote: > > > > [...] > > I have switched to simple printf() calls in a new v13 patch, which > > is also my last attempt to fix this. > > You cannot use printf in a signal handler. It is _not_ AS-Safe. See > the signal-safety(7) man page, like > <https://man7.org/linux/man-pages/man7/signal-safety.7.html>. > > Jeff _______________________________________________ Gnupg-devel mailing list Gnupg-devel@gnupg.org https://lists.gnupg.org/mailman/listinfo/gnupg-devel