From patchwork Thu Sep 5 20:56:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 173180 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:ce:0:0:0:0 with SMTP id r14csp1238068ilq; Thu, 5 Sep 2019 13:57:05 -0700 (PDT) X-Google-Smtp-Source: APXvYqyRC2doosXN4HwT6h0OkFwACJoI46GzTTKxbo+b8PbuS6EfTwhR4Kf1cypWEUt8pXLDd7dx X-Received: by 2002:a17:902:7792:: with SMTP id o18mr5346928pll.73.1567717025172; Thu, 05 Sep 2019 13:57:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1567717025; cv=none; d=google.com; s=arc-20160816; b=sD4S5JPS37IzwucZRGmyYOXNDRmvmHF0urKSy1bThGN8QZmcXS9CjlmGuFA8BQR2r2 FSsWEegJrIELOgtAYoJqsyZ4o26jXN6QI12+vypHx9b+dEXususbet7cvi7Nn4WTBdVZ +2urVhbOHAIsOEHIOFlKSiiCDUaDAfyW0FMSL9iEn8LaRSx8hzYTTB3FJg/7U/E7g+Jx TwVMVWe8hGLWGuaZyP2QKbj5BgQhO0Wu0lcuQpszZY64GItVCoXh1vyFJ8UPTOGm2bfc jgUgR9rNWP7ldEGB0NiuD7aWhVOeWotwauv3mY+hLZaHbW6JglXi+zfL++c0neC/n9Xz sujQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from :dkim-signature:delivered-to:sender:list-help:list-post:list-archive :list-subscribe:list-unsubscribe:list-id:precedence:mailing-list :dkim-signature:domainkey-signature; bh=uF6VWzgOgPXbytf1jDxQtnk29kzBnBa+AO2W3HtkS2U=; b=jVDQPSAMCBnMVwQLrghbySvhfsD1Z8JvOs4LJN52XKOlhCsSEV08WTmosq26imeDnm nuEU9LJ/TnLZrF9HYGm/Rdha5v27oT3Q81C4YhMEDVtOXWKJuVA0Kn65BW1Wth58QSKU BtxgDpqrPq3sfOLMNmd4nd2GV61pgkhTO7dWeTMoQv0tFyckH3FEewEfykONeruBo9Sm 5hWx46H85AzauZx6ss09Em469o7ub5ju02HscS8buzuraO8HDpdszybNJ/vxco0tn6bc Uj2xtANY5O6BgyjnRWCQ9FvetyPbF/KhNGe/46JgxFpV/WpmnvAOpynyzUfEVsx5ruwJ phsQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=pHTHJb4s; dkim=pass header.i=@linaro.org header.s=google header.b=dc8kHJ2S; spf=pass (google.com: domain of libc-alpha-return-105065-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-105065-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id u13si2716981pgf.382.2019.09.05.13.57.04 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 05 Sep 2019 13:57:05 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-105065-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=pHTHJb4s; dkim=pass header.i=@linaro.org header.s=google header.b=dc8kHJ2S; spf=pass (google.com: domain of libc-alpha-return-105065-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom="libc-alpha-return-105065-patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=YmveBerkPfLvgN3UGEDaKLqWv+6Iyfz p2ahT1g+Xp53dmc7FEuItGFW4NzqTtv8774mvrgjZSNuEH1INaLCDLjiUm0tfnPD ZtAtem03sMqWK5efqkPNF2xz+oH/Ayd+ErT3IypHSnSl7+AV5CrvxsZpmGkwZIsD x2ksZEfcmwfM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; s=default; bh=nceBQ6hVKyP3HuZ9ZuQ8maw/wH4=; b=pHTHJ b4sZS4w31xuI4VW+E7mABQo+7+4WJHKcIfaDEbo9RwIn3soa8oDF3sbWsgO6j2lt Nfwv5d8T1yWzeEiVcLQ+Rj0uIStXFIIMCrNsBz8mbc2Ak9t0ZWqDi3NYCzTYyL21 VUJUs8jeS8Y9Hek3gyYV13voGfWMt5BmrGFrRI= Received: (qmail 116697 invoked by alias); 5 Sep 2019 20:56:34 -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 116618 invoked by uid 89); 5 Sep 2019 20:56:33 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mail-qt1-f182.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:subject:date:message-id:in-reply-to:references; bh=uF6VWzgOgPXbytf1jDxQtnk29kzBnBa+AO2W3HtkS2U=; b=dc8kHJ2SRJagq5tVshhY/RHR72OMPlLa0PPHL0DpSK/p4xzaquRNZXls/ZxbU6vuR8 6uKKriJi9nzoP+7hB17neBkO7VEqvBtTQfNDJOhTQTKS3Njk4Q8EqgNqqMrr4ATK0lNH t8Iz77KVcFEe7MhLSSNfvNyK6eCduskWo9EdQTt83dwaH+UIXFdqdnQ+x7mYOoBCgUVl XWK7meltjhJcvQ4heX4HQ8xngcsY2eKLZky7/2NTKh60KTeggdH/oiJSkvRnovlGOVaE RjPzSALr7Tdi/mEVZy+/KnIVxI2ZGyKu0ACLbT9pC57fcT2QpLrcDYkI1SJSPE5BMiqu RHkg== Return-Path: From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 3/8] Enable vDSO on interposed malloc linked statically Date: Thu, 5 Sep 2019 17:56:15 -0300 Message-Id: <20190905205620.4646-3-adhemerval.zanella@linaro.org> In-Reply-To: <20190905205620.4646-1-adhemerval.zanella@linaro.org> References: <20190905205620.4646-1-adhemerval.zanella@linaro.org> For statically linked binaries, _dl_non_dynamic_init (csu/init-first.c:74) calls malloc before the vDSO is properly initialized (it will fully usable only after VDSO_SETUP call). The bug is triggered for the cases where an interposed malloc calls clock_gettime or any other implementation that may call a vDSO symbol. It is because PTR_DEMANDLE at {INLINE,INTERNAL}_VSYSCALL is called with uninitialized __vdso_* pointer value, which should be done by PTR_MANGLE (zero-initialized value in this case is invalid). The patch fixes by adding an extra hook before _dl_non_dynamic_init which setup the initial __vdso_* pointer symbol to an mangled NULL value. For NULL mangled values {INLINE,INTERNAL}_VSYSCALL issues the syscall directly in fallback code path. Once the __vdso_* is setup the vsyscall branches to vDSO. Checked on x86_64-linux-gnu. [BZ #24967] * sysdeps/unix/sysv/linux/init-first.c (libc_vdso_mangled_symbol): New symbol. (__libc_vdso_platform_setup): Add an option to call it to initialize the hooks to null values. (VDSO_PRE_SETUP): Define. * csu/init-first.c (_init): Add a pre-hook to initialize the vDSO internal pointer. * malloc/tst-interpose-aux.c (allocation_header): Add ts member. (malloc_internal): Call clock_gettime. --- csu/init-first.c | 8 ++++++ malloc/tst-interpose-aux.c | 5 ++++ sysdeps/unix/sysv/linux/init-first.c | 37 +++++++++++++++++++--------- 3 files changed, 39 insertions(+), 11 deletions(-) -- 2.17.1 diff --git a/csu/init-first.c b/csu/init-first.c index 10762b61f5..d984419554 100644 --- a/csu/init-first.c +++ b/csu/init-first.c @@ -69,6 +69,14 @@ _init (int argc, char **argv, char **envp) __environ = envp; #ifndef SHARED + /* Initialize the vDSO internal pointers to mangled zero value. It makes + the {INTERNAL,INLINE}_VSYSCALL macro to fallback to direct syscall + and allows call the symbol that might the vDSO on _dl_non_dynamic_init + (for instance clock_gettime on an interposed malloc). */ +# ifdef VDSO_PRE_SETUP + VDSO_PRE_SETUP (); +# endif + /* First the initialization which normally would be done by the dynamic linker. */ _dl_non_dynamic_init (); diff --git a/malloc/tst-interpose-aux.c b/malloc/tst-interpose-aux.c index bf86224401..de62d436bc 100644 --- a/malloc/tst-interpose-aux.c +++ b/malloc/tst-interpose-aux.c @@ -28,6 +28,7 @@ #include #include #include +#include #if INTERPOSE_THREADS #include @@ -96,6 +97,7 @@ struct __attribute__ ((aligned (__alignof__ (max_align_t)))) allocation_header { size_t allocation_index; size_t allocation_size; + struct timespec ts; }; /* Array of known allocations, to track invalid frees. */ @@ -166,6 +168,9 @@ malloc_internal (size_t size) .allocation_index = index, .allocation_size = allocation_size }; + /* Check if calling a symbol which may use the vDSO does not fail. + The CLOCK_REALTIME should be supported on all systems. */ + clock_gettime (CLOCK_REALTIME, &allocations[index]->ts); return allocations[index] + 1; } diff --git a/sysdeps/unix/sysv/linux/init-first.c b/sysdeps/unix/sysv/linux/init-first.c index d90ca820be..a23e5d9f6e 100644 --- a/sysdeps/unix/sysv/linux/init-first.c +++ b/sysdeps/unix/sysv/linux/init-first.c @@ -44,37 +44,52 @@ long int (*VDSO_SYMBOL(getcpu)) (unsigned *, unsigned *, void *) time_t (*VDSO_SYMBOL(time)) (time_t *) attribute_hidden; #endif +static inline void * +__libc_vdso_mangled_symbol (const char *symbol) +{ + void *vdsop = NULL; + if (symbol != NULL) + vdsop = get_vdso_mangle_symbol (symbol); + else + PTR_MANGLE (vdsop); + return vdsop; +} + static inline void -__libc_vdso_platform_setup (void) +__libc_vdso_platform_setup (bool initial) { #ifdef HAVE_CLOCK_GETTIME_VSYSCALL - VDSO_SYMBOL(clock_gettime) - = get_vdso_mangle_symbol (HAVE_CLOCK_GETTIME_VSYSCALL); + VDSO_SYMBOL(clock_gettime) = + __libc_vdso_mangled_symbol (initial ? NULL : HAVE_CLOCK_GETTIME_VSYSCALL); #endif #ifdef HAVE_CLOCK_GETRES_VSYSCALL - VDSO_SYMBOL(clock_getres) - = get_vdso_mangle_symbol (HAVE_CLOCK_GETRES_VSYSCALL); + VDSO_SYMBOL(clock_getres) = + __libc_vdso_mangled_symbol (initial ? NULL : HAVE_CLOCK_GETRES_VSYSCALL); #endif #ifdef HAVE_GETTIMEOFDAY_VSYSCALL - VDSO_SYMBOL(gettimeofday) - = get_vdso_mangle_symbol (HAVE_GETTIMEOFDAY_VSYSCALL); + VDSO_SYMBOL(gettimeofday) = + __libc_vdso_mangled_symbol (initial ? NULL : HAVE_GETTIMEOFDAY_VSYSCALL); #endif #ifdef HAVE_GETCPU_VSYSCALL - VDSO_SYMBOL(getcpu) = get_vdso_mangle_symbol (HAVE_GETCPU_VSYSCALL); + VDSO_SYMBOL(getcpu) = + __libc_vdso_mangled_symbol (initial ? NULL : HAVE_GETCPU_VSYSCALL); #endif #ifdef HAVE_TIME_VSYSCALL - VDSO_SYMBOL(time) = get_vdso_mangle_symbol (HAVE_TIME_VSYSCALL); + VDSO_SYMBOL(time) = + __libc_vdso_mangled_symbol (initial ? NULL : HAVE_TIME_VSYSCALL); #endif #ifdef VDSO_SETUP_ARCH - VDSO_SETUP_ARCH (); + if (!initial) + VDSO_SETUP_ARCH (); #endif } -#define VDSO_SETUP __libc_vdso_platform_setup +#define VDSO_PRE_SETUP() ({ __libc_vdso_platform_setup (true); }) +#define VDSO_SETUP() ({ __libc_vdso_platform_setup (false); }) #include