File 0001-Add-Userspace-Livepatch-prologue-into-ASM-functions.patch of Package glibc

From 323f4ec450459f28a80e7c3edf418fc629ba19ea Mon Sep 17 00:00:00 2001
From: Giuliano Belinassi <gbelinassi@suse.de>
Date: Fri, 28 Apr 2023 17:48:33 -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 <gbelinassi@suse.de>
---
 config.h.in                              |  6 ++++
 configure                                | 38 ++++++++++++++++++++++++
 configure.ac                             | 27 +++++++++++++++++
 sysdeps/x86/sysdep.h                     | 14 ++++++---
 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 +---
 7 files changed, 84 insertions(+), 16 deletions(-)

diff --git a/config.h.in b/config.h.in
index c87008b6a9..a151927a29 100644
--- a/config.h.in
+++ b/config.h.in
@@ -292,4 +292,10 @@
 /* Define if -mmovbe is enabled by default on x86.  */
 #undef HAVE_X86_MOVBE
 
+/* Padding nops before function label */
+#undef ULP_PRE_PROLOGUE
+
+/* Padding nops after function label */
+#undef ULP_POST_PROLOGUE
+
 #endif
diff --git a/configure b/configure
index f84040644b..7d57a58d9f 100755
--- a/configure
+++ b/configure
@@ -783,6 +783,7 @@ enable_mathvec
 enable_cet
 enable_scv
 with_cpu
+enable_userspace_livepatch
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1452,6 +1453,8 @@ Optional Features:
                           (CET), x86 only
   --disable-scv           syscalls will not use scv instruction, even if the
                           kernel supports it, powerpc only
+  --enable-userspace-livepatch
+                          build with userspace livepatch support [default=no]
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -6708,6 +6711,41 @@ libc_cv_multidir=`${CC-cc} $CFLAGS $CPPFLAGS -print-multi-directory`
 
 
 
+# Check whether --enable-userspace-livepatch was given.
+if test "${enable_userspace_livepatch+set}" = set; then :
+  enableval=$enable_userspace_livepatch; enable_userspace_livepatch=$enableval
+else
+  enable_userspace_livepatch=no
+fi
+
+
+# Libpulp uses -fpatchable-function-entry to add padding NOPS to the
+# prologue of all functions: ULP_PRE_PROLOGUE nop before the entry
+# point, and the remaining nops after it. For C functions it is enough
+# to compile with this flag, but ASM functions needs to have those NOPS
+# inserted manually.
+ULP_PRE_PROLOGUE=""
+ULP_POST_PROLOGUE=""
+if test "x$enable_userspace_livepatch" = xyes; then
+  if test "${host_cpu}" = "x86_64"; then
+    ULP_PRE_PROLOGUE="nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop"
+    ULP_POST_PROLOGUE="xchg %ax, %ax"
+    CFLAGS="$CFLAGS -fpatchable-function-entry=16,14"
+  fi
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define ULP_PRE_PROLOGUE $ULP_PRE_PROLOGUE
+_ACEOF
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define ULP_POST_PROLOGUE $ULP_POST_PROLOGUE
+_ACEOF
+
+
 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 88df3e5eed..098a3a476d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1803,6 +1803,33 @@ 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: ULP_PRE_PROLOGUE nop before the entry
+# point, and the remaining nops after it. For C functions it is enough
+# to compile with this flag, but ASM functions needs to have those NOPS
+# inserted manually.
+ULP_PRE_PROLOGUE=""
+ULP_POST_PROLOGUE=""
+if test "x$enable_userspace_livepatch" = xyes; then
+  if test "${host_cpu}" = "x86_64"; then
+    ULP_PRE_PROLOGUE="nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop; nop"
+    ULP_POST_PROLOGUE="xchg %ax, %ax"
+    CFLAGS="$CFLAGS -fpatchable-function-entry=16,14"
+  fi
+fi
+
+AC_DEFINE_UNQUOTED([ULP_PRE_PROLOGUE], [$ULP_PRE_PROLOGUE],
+[Padding nops before function label])
+
+AC_DEFINE_UNQUOTED([ULP_POST_PROLOGUE], [$ULP_POST_PROLOGUE],
+[Padding nops after function label])
+
 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..7f35fb40d7 100644
--- a/sysdeps/x86/sysdep.h
+++ b/sysdeps/x86/sysdep.h
@@ -77,15 +77,21 @@ enum cf_protection_level
 #define ALIGNARG(log2) 1<<log2
 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
 
+/* Define the first instructions of a function.  */
+#define FUNCTION_START(name) \
+  ULP_PRE_PROLOGUE; \
+  C_LABEL(name); \
+  cfi_startproc; \
+  _CET_ENDBR; \
+  ULP_POST_PROLOGUE; \
+  CALL_MCOUNT;
+
 /* Define an entry point visible from C.  */
 #define	ENTRY_P2ALIGN(name, alignment)					      \
   .globl C_SYMBOL_NAME(name);						      \
   .type C_SYMBOL_NAME(name),@function;					      \
   .align ALIGNARG(alignment);						      \
-  C_LABEL(name)								      \
-  cfi_startproc;							      \
-  _CET_ENDBR;								      \
-  CALL_MCOUNT
+  FUNCTION_START(name)
 
 /* Common entry 16 byte aligns.  */
 #define ENTRY(name) ENTRY_P2ALIGN (name, 4)
diff --git a/sysdeps/x86_64/multiarch/strcmp-avx2.S b/sysdeps/x86_64/multiarch/strcmp-avx2.S
index 07f8ec54c6..b22d59b5cf 100644
--- a/sysdeps/x86_64/multiarch/strcmp-avx2.S
+++ b/sysdeps/x86_64/multiarch/strcmp-avx2.S
@@ -201,10 +201,7 @@ END (STRCASECMP)
 # endif
 
 	.p2align 4
-STRCMP:
-	cfi_startproc
-	_CET_ENDBR
-	CALL_MCOUNT
+FUNCTION_START(STRCMP)
 
 # if defined USE_AS_STRCASECMP_L
 	/* We have to fall back on the C implementation for locales with
diff --git a/sysdeps/x86_64/multiarch/strcmp-evex.S b/sysdeps/x86_64/multiarch/strcmp-evex.S
index a8bd5cd786..809ba10447 100644
--- a/sysdeps/x86_64/multiarch/strcmp-evex.S
+++ b/sysdeps/x86_64/multiarch/strcmp-evex.S
@@ -224,10 +224,7 @@ END (STRCASECMP)
 # endif
 
 	.p2align 4
-STRCMP:
-	cfi_startproc
-	_CET_ENDBR
-	CALL_MCOUNT
+FUNCTION_START(STRCMP)
 
 # if defined USE_AS_STRCASECMP_L
 	/* We have to fall back on the C implementation for locales with
diff --git a/sysdeps/x86_64/multiarch/strcmp-sse4_2.S b/sysdeps/x86_64/multiarch/strcmp-sse4_2.S
index f93c34465e..f96f66d54c 100644
--- a/sysdeps/x86_64/multiarch/strcmp-sse4_2.S
+++ b/sysdeps/x86_64/multiarch/strcmp-sse4_2.S
@@ -103,10 +103,7 @@ END (STRCASECMP)
 
 # define arg arg
 
-STRCMP:
-	cfi_startproc
-	_CET_ENDBR
-	CALL_MCOUNT
+FUNCTION_START(STRCMP)
 
 /*
  * This implementation uses SSE to compare up to 16 bytes at a time.
-- 
2.40.0

openSUSE Build Service is sponsored by