From patchwork Wed Feb 24 23:28:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nix X-Patchwork-Id: 11069 Received: (qmail 128475 invoked by alias); 24 Feb 2016 23:29:12 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 128159 invoked by uid 89); 24 Feb 2016 23:29:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.4 required=5.0 tests=AWL, BAYES_50, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD autolearn=no version=3.3.2 spammy=*src, multiarch, UD:2.7.0.198.g6dd47b6, sk:2701 X-HELO: mail.esperi.org.uk From: Nix To: libc-alpha@sourceware.org Subject: [PATCH 04/14] Open-code the memcpy() at static TLS initialization time. Date: Wed, 24 Feb 2016 23:28:10 +0000 Message-Id: <1456356500-25601-5-git-send-email-nix@esperi.org.uk> In-Reply-To: <1456356500-25601-1-git-send-email-nix@esperi.org.uk> References: <1456356500-25601-1-git-send-email-nix@esperi.org.uk> X-DCC-wuwien-Metrics: spindle 1290; Body=1 Fuz1=1 Fuz2=1 From: Nick Alcock This one is a bit nasty. Now that we are initializing TLS earlier for the stack canary's sake, existing memcpy() implementations become problematic. We cannot use the multiarch implementations, even if we move the irel initialization up above TLS initialization, because ifunc resolvers may not work this early (among other things, they might be compiled with stack-protection!). We cannot use posix/memcpy.c unmodified without marking both it and */wordcopy.c as non-stack-protected, which for memcpy() of all things seems like a seriously bad idea: if any function in glibc should be stack-protected, it's memcpy() (though stack-protecting the many optimized assembly versions is not done in this patch series). So we have two real options: hack up the guts of posix/memcpy.c and */wordcopy.c so that they can be #included (renamed and declared static) inside libc-tls.c, or simply open-code the memcpy(). For simplicity's sake, this patch open-codes it, on the grounds that static binaries are relatively rare and quasi-deprecated anyway, and static binaries with large TLS sections are yet rarer, and not worth the complexity of hacking up all the arch-dependent wordcopy files. (This was not revealed when testing on x86 because on that platform GCC was open-coding the memcpy() for us.) v2: New, lets us remove the memcpy() -fno-stack-protection, which wasn't enough in any case. --- csu/libc-tls.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/csu/libc-tls.c b/csu/libc-tls.c index 3d67a64..20f478d 100644 --- a/csu/libc-tls.c +++ b/csu/libc-tls.c @@ -176,8 +176,17 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign) # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined" #endif _dl_static_dtv[2].pointer.is_static = true; - /* sbrk gives us zero'd memory, so we don't need to clear the remainder. */ - memcpy (_dl_static_dtv[2].pointer.val, initimage, filesz); + + /* sbrk gives us zero'd memory, so we don't need to clear the remainder. + + Copy by hand, because memcpy() is stack-protected and is often multiarch too. */ + + char *dst = (char *) _dl_static_dtv[2].pointer.val; + char *src = (char *) initimage; + size_t i; + + for (i = 0; i < filesz; dst++, src++, i++) + *dst = *src; /* Install the pointer to the dtv. */