File ulp-prologue-into-asm-functions.patch of Package glibc

From 17d77e73d882f341784da2957b7334566c48f8ad Mon Sep 17 00:00:00 2001
From: Giuliano Belinassi <gbelinassi@suse.de>
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 <gbelinassi@suse.de>
---
 Makeconfig              |  5 +++++
 config.h.in             |  3 +++
 config.make.in          |  1 +
 configure               | 20 ++++++++++++++++++++
 configure.ac            | 13 +++++++++++++
 sysdeps/x86/sysdep.h    | 24 +++++++++++++++++++-----
 sysdeps/x86_64/sysdep.h | 26 ++++++++++++++++++++++++++
 7 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/Makeconfig b/Makeconfig
index f252842979..1700ae6fb0 100644
--- a/Makeconfig
+++ b/Makeconfig
@@ -916,6 +916,11 @@ endif	# $(+cflags) == ""
 	   $(+stack-protector)
 +gcc-nowarn := -w
 
+# 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 dea43df438..f379201aec 100644
--- a/config.h.in
+++ b/config.h.in
@@ -186,6 +186,9 @@
 /* Define if the linker defines __ehdr_start.  */
 #undef HAVE_EHDR_START
 
+/* Define to 1 if support for userspace livepatching is enabled.  */
+#define ENABLE_USERSPACE_LIVEPATCH 0
+
 /*
  */
 
diff --git a/config.make.in b/config.make.in
index 2fed3da773..1ed8bcc786 100644
--- a/config.make.in
+++ b/config.make.in
@@ -88,6 +88,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-pic-default= @libc_cv_pic_default@
 build-pie-default= @libc_cv_pie_default@
diff --git a/configure b/configure
index 3b98ec312f..95de3f637f 100755
--- a/configure
+++ b/configure
@@ -590,6 +590,7 @@ ac_subst_vars='LTLIBOBJS
 LIBOBJS
 RELEASE
 VERSION
+enable_userspace_livepatch
 mach_interface_list
 DEFINES
 static_nss
@@ -795,6 +796,7 @@ enable_tunables
 enable_mathvec
 enable_cet
 with_cpu
+enable_userspace_livepatch
 '
       ac_precious_vars='build_alias
 host_alias
@@ -1471,6 +1473,8 @@ Optional Features:
                           depends on architecture]
   --enable-cet            enable Intel Control-flow Enforcement Technology
                           (CET), x86 only
+  --enable-userspace-livepatch
+                          build with userspace livepatch support [default=no]
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -6918,6 +6922,22 @@ enable-static-pie = $static_pie"
 
 
 
+# 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.
+if test "x$enable_userspace_livepatch" = xyes; then
+  $as_echo "#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 e20034f301..a9bcf62681 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1896,6 +1896,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 f5039bc1b2..94749327c2 100644
--- a/sysdeps/x86/sysdep.h
+++ b/sysdeps/x86/sysdep.h
@@ -72,15 +72,29 @@ enum cf_protection_level
 #define ALIGNARG(log2) 1<<log2
 #define ASM_SIZE_DIRECTIVE(name) .size name,.-name;
 
+/* For 32-bit glibc then define those macros as empty.  */
+#ifndef ULP_PRE_PROLOGUE
+# define ULP_PRE_PROLOGUE
+#endif
+#ifndef ULP_POST_PROLOGUE
+# define ULP_POST_PROLOGUE
+#endif
+
+/* 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(name)							      \
   .globl C_SYMBOL_NAME(name);						      \
   .type C_SYMBOL_NAME(name),@function;					      \
-  .align ALIGNARG(4);							      \
-  C_LABEL(name)								      \
-  cfi_startproc;							      \
-  _CET_ENDBR;								      \
-  CALL_MCOUNT
+  .align ALIGNARG(4);						      \
+  FUNCTION_START(name)
 
 #undef	END
 #define END(name)							      \
diff --git a/sysdeps/x86_64/sysdep.h b/sysdeps/x86_64/sysdep.h
index c8ad778fee..0eb6cf2d81 100644
--- a/sysdeps/x86_64/sysdep.h
+++ b/sysdeps/x86_64/sysdep.h
@@ -23,6 +23,32 @@
 
 #ifdef	__ASSEMBLER__
 
+/* Libpulp uses -fpatchable-function-entry to add padding NOPS to the
+   prologue of all functions. This works for C functions. For functions
+   written in ASM, the way we do this is by adding this prologue manually.  */
+
+#if ENABLE_USERSPACE_LIVEPATCH == 1
+# undef ULP_PRE_PROLOGUE
+# undef ULP_POST_PROLOGUE
+# define ULP_PRE_PROLOGUE \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop; \
+  nop;
+# define ULP_POST_PROLOGUE \
+  xchg %ax, %ax
+#endif
+
 /* Syntactic details of assembler.  */
 
 /* This macro is for setting proper CFI with DW_CFA_expression describing
-- 
2.39.0

openSUSE Build Service is sponsored by