From 65bb10c34ff3734373a8b4be4e707f0494449f17 Mon Sep 17 00:00:00 2001 From: Giuliano Belinassi Date: Wed, 24 May 2023 18:03:15 -0300 Subject: [PATCH] Add Userspace Livepatch prologue into ASM functions Userspace Live Patching (ULP) refers to the process of applying patches to the libraries used by a running process, without interrupting it. In order to archive this, functions must have the NOP prologue. This prologue is included automatically when compiled with -fpatchable-function-entry, but for ASM functions this have to be included manually. This patch does this. Signed-off-by: Giuliano Belinassi --- Makeconfig | 5 +++++ config.h.in | 3 +++ config.make.in | 1 + configure | 21 +++++++++++++++++++++ configure.ac | 13 +++++++++++++ sysdeps/x86/sysdep.h | 22 ++++++++++++++++++---- sysdeps/x86_64/multiarch/strcmp-avx2.S | 5 +---- sysdeps/x86_64/multiarch/strcmp-evex.S | 5 +---- sysdeps/x86_64/multiarch/strcmp-sse4_2.S | 5 +---- sysdeps/x86_64/sysdep.h | 13 +++++++++++++ 10 files changed, 77 insertions(+), 16 deletions(-) diff --git a/Makeconfig b/Makeconfig index 77d7fd14df..765d72bcf5 100644 --- a/Makeconfig +++ b/Makeconfig @@ -984,6 +984,11 @@ else +cflags += $(no-fortify-source) endif +# Add flags for Userspace Livepatching support. +ifeq (yes,$(enable-userspace-livepatch)) ++cflags += -fpatchable-function-entry=16,14 +endif + # Each sysdeps directory can contain header files that both will be # used to compile and will be installed. Each can also contain an # include/ subdirectory, whose header files will be used to compile diff --git a/config.h.in b/config.h.in index 0dedc124f7..08b1868002 100644 --- a/config.h.in +++ b/config.h.in @@ -204,6 +204,9 @@ /* Define to 1 if libpthread actually resides in libc. */ #define PTHREAD_IN_LIBC 0 +/* Define to 1 if support for userspace livepatching is enabled. */ +#define ENABLE_USERSPACE_LIVEPATCH 0 + /* An integer used to scale the timeout of test programs. */ #define TIMEOUTFACTOR 1 diff --git a/config.make.in b/config.make.in index d487a4f4e9..e48351c59a 100644 --- a/config.make.in +++ b/config.make.in @@ -85,6 +85,7 @@ nss-crypt = @libc_cv_nss_crypt@ static-nss-crypt = @libc_cv_static_nss_crypt@ # Configuration options. +enable-userspace-livepatch = @enable_userspace_livepatch@ build-shared = @shared@ build-profile = @profile@ build-static-nss = @static_nss@ diff --git a/configure b/configure index c02c0b5825..e2000fdc4a 100755 --- a/configure +++ b/configure @@ -622,6 +622,7 @@ LIBOBJS pthread_in_libc RELEASE VERSION +enable_userspace_livepatch mach_interface_list DEFINES static_nss @@ -819,6 +820,7 @@ enable_cet enable_scv enable_fortify_source with_cpu +enable_userspace_livepatch ' ac_precious_vars='build_alias host_alias @@ -1501,6 +1503,8 @@ Optional Features: Use -D_FORTIFY_SOURCE=[1|2|3] to control code hardening, defaults to highest possible value supported by the build compiler. + --enable-userspace-livepatch + build with userspace livepatch support [default=no] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] @@ -8004,6 +8008,23 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory` +# Check whether --enable-userspace-livepatch was given. +if test ${enable_userspace_livepatch+y} +then : + enableval=$enable_userspace_livepatch; enable_userspace_livepatch=$enableval +else $as_nop + enable_userspace_livepatch=no +fi + + +# Libpulp uses -fpatchable-function-entry to add padding NOPS to the +# prologue of all functions. +if test "x$enable_userspace_livepatch" = xyes; then + printf "%s\n" "#define ENABLE_USERSPACE_LIVEPATCH 1" >>confdefs.h + +fi + + VERSION=`sed -n -e 's/^#define VERSION "\([^"]*\)"/\1/p' < $srcdir/version.h` RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h` diff --git a/configure.ac b/configure.ac index 09553541fb..a07e3d6284 100644 --- a/configure.ac +++ b/configure.ac @@ -1827,6 +1827,19 @@ AC_SUBST(DEFINES) dnl See sysdeps/mach/configure.ac for this variable. AC_SUBST(mach_interface_list) +AC_ARG_ENABLE([userspace-livepatch], + AS_HELP_STRING([--enable-userspace-livepatch], + [build with userspace livepatch support @<:@default=no@:>@]), + [enable_userspace_livepatch=$enableval], + [enable_userspace_livepatch=no]) + +# Libpulp uses -fpatchable-function-entry to add padding NOPS to the +# prologue of all functions. +if test "x$enable_userspace_livepatch" = xyes; then + AC_DEFINE(ENABLE_USERSPACE_LIVEPATCH) +fi +AC_SUBST(enable_userspace_livepatch) + VERSION=`sed -n -e 's/^#define VERSION "\([^"]*\)"/\1/p' < $srcdir/version.h` RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h` AC_SUBST(VERSION) diff --git a/sysdeps/x86/sysdep.h b/sysdeps/x86/sysdep.h index 0b3483a77a..329c16306e 100644 --- a/sysdeps/x86/sysdep.h +++ b/sysdeps/x86/sysdep.h @@ -77,15 +77,29 @@ enum cf_protection_level #define ALIGNARG(log2) 1<