From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.org/gmane.linux.lib.musl.general/10529 Path: news.gmane.org!.POSTED!not-for-mail From: "LeMay, Michael" Newsgroups: gmane.linux.lib.musl.general Subject: [RFC PATCH 6/7] support dynamic linking with segmentation-hardened SafeStack Date: Tue, 27 Sep 2016 15:38:36 -0700 Message-ID: <20c44e3d-2981-c6cf-f6b8-cc5bfd2fa149@intel.com> Reply-To: musl@lists.openwall.com NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Trace: blaine.gmane.org 1475015936 26755 195.159.176.226 (27 Sep 2016 22:38:56 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 27 Sep 2016 22:38:56 +0000 (UTC) User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 To: "musl@lists.openwall.com" Original-X-From: musl-return-10542-gllmg-musl=m.gmane.org@lists.openwall.com Wed Sep 28 00:38:52 2016 Return-path: Envelope-to: gllmg-musl@m.gmane.org Original-Received: from mother.openwall.net ([195.42.179.200]) by blaine.gmane.org with smtp (Exim 4.84_2) (envelope-from ) id 1bp11W-0006I8-RK for gllmg-musl@m.gmane.org; Wed, 28 Sep 2016 00:38:50 +0200 Original-Received: (qmail 5396 invoked by uid 550); 27 Sep 2016 22:38:51 -0000 Mailing-List: contact musl-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Original-Received: (qmail 5364 invoked from network); 27 Sep 2016 22:38:49 -0000 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.30,407,1470726000"; d="scan'208";a="14390045" Xref: news.gmane.org gmane.linux.lib.musl.general:10529 Archived-At: 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 --- 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