Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [day] [month] [year] [list]
Date: Tue, 27 Sep 2016 15:38:36 -0700
From: "LeMay, Michael" <michael.lemay@...el.com>
To: "musl@...ts.openwall.com" <musl@...ts.openwall.com>
Subject: [RFC PATCH 6/7] support dynamic linking with segmentation-hardened
 SafeStack

This patch splits the third stage of dynamic linking around the
initialization of segmentation-hardened SafeStack and adds other
aspects of support for that.

Signed-off-by: Michael LeMay <michael.lemay@...el.com>
---
  ldso/dlstart.c | 23 +++++++++++++++++++++--
  ldso/dynlink.c | 44 ++++++++++++++++++++++++++++++++++++--------
  2 files changed, 57 insertions(+), 10 deletions(-)

diff --git a/ldso/dlstart.c b/ldso/dlstart.c
index 4dbe178..53d2295 100644
--- a/ldso/dlstart.c
+++ b/ldso/dlstart.c
@@ -17,8 +17,14 @@
      *(fp) = static_func_ptr; } while(0)
  #endif

-__attribute__((__visibility__("hidden")))
-void _dlstart_c(size_t *sp, size_t *dynv)
+#if SAFE_STACK
+#define _DLSTART_C _dlstart_c_impl
+#else
+#define _DLSTART_C _dlstart_c
+#endif
+
+__attribute__((__visibility__("hidden"), noinline))
+void _DLSTART_C(size_t *sp, size_t *dynv)
  {
      size_t i, aux[AUX_CNT], dyn[DYN_CNT];
      size_t *rel, rel_size, base;
@@ -146,3 +152,16 @@ void _dlstart_c(size_t *sp, size_t *dynv)
      GETFUNCSYM(&dls2, __dls2, base+dyn[DT_PLTGOT]);
      dls2((void *)base, sp);
  }
+
+#if SAFE_STACK
+
+void __preinit_unsafe_stack(void);
+
+__attribute__((__visibility__("hidden"), no_sanitize("safe-stack")))
+void _dlstart_c(size_t *sp, size_t *dynv)
+{
+    __preinit_unsafe_stack();
+    _DLSTART_C(sp, dynv);
+}
+
+#endif
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index e458f38..e729ac1 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -1383,21 +1383,27 @@ void __dls2(unsigned char *base, size_t *sp)
      else ((stage3_func)laddr(&ldso, dls3_def.sym->st_value))(sp);
  }

+__attribute__((noinline))
+_Noreturn void __dls4(size_t *sp, int argc, char **argv, size_t *aux);
+
+#if SAFE_STACK
+void __init_unsafe_stack(void);
+#endif
+
  /* Stage 3 of the dynamic linker is called with the dynamic linker/libc
- * fully functional. Its job is to load (if not already loaded) and
- * process dependencies and relocations for the main application and
- * transfer control to its entry point. */
+ * fully functional. Its job is to prepare for syscalls. It also 
configures a
+ * thread-local unsafe stack and protects the safe stack with 
segmentation if
+ * those features are enabled. */

+#if SAFE_STACK
+__attribute__((no_sanitize("safe-stack")))
+#endif
  _Noreturn void __dls3(size_t *sp)
  {
-    static struct dso app, vdso;
      size_t aux[AUX_CNT], *auxv;
      size_t i;
-    char *env_preload=0;
-    size_t vdso_base;
      int argc = *sp;
      char **argv = (void *)(sp+1);
-    char **argv_orig = argv;
      char **envp = argv+argc+1;

      /* Find aux vector just past environ[] and use it to initialize
@@ -1420,6 +1426,28 @@ _Noreturn void __dls3(size_t *sp)
          a_crash();
      }

+#if SAFE_STACK
+    __init_unsafe_stack();
+#endif
+
+    __dls4(sp, argc, argv, aux);
+}
+
+/* Stage 4 of the dynamic linker is called with a thread-local unsafe 
stack and
+ * the safe stack protected with segmentation if those features are 
enabled.
+ * Its job is to load (if not already loaded) and process dependencies and
+ * relocations for the main application and transfer control to its entry
+ * point. */
+
+_Noreturn void __dls4(size_t *sp, int argc, char **argv, size_t *aux)
+{
+    static struct dso app, vdso;
+    size_t i;
+    char *env_preload=0;
+    size_t vdso_base;
+    char **argv_orig = argv;
+    char *execfn;
+
      /* Only trust user/env if kernel says we're not suid/sgid */
      if (!libc.secure) {
          env_path = getenv("LD_LIBRARY_PATH");
@@ -1549,7 +1577,7 @@ _Noreturn void __dls3(size_t *sp)
      }

      /* Attach to vdso, if provided by the kernel */
-    if (search_vec(auxv, &vdso_base, AT_SYSINFO_EHDR)) {
+    if (search_vec(libc.auxv, &vdso_base, AT_SYSINFO_EHDR)) {
          Ehdr *ehdr = (void *)vdso_base;
          Phdr *phdr = vdso.phdr = (void *)(vdso_base + ehdr->e_phoff);
          vdso.phnum = ehdr->e_phnum;
-- 
2.7.4


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.