From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31124 invoked by alias); 7 Nov 2019 22:15:41 -0000 Mailing-List: contact libc-stable-help@sourceware.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Subscribe: List-Archive: Sender: libc-stable-owner@sourceware.org Received: (qmail 31065 invoked by uid 89); 7 Nov 2019 22:15:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.100.3 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-18.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT autolearn=ham version=3.3.1 spammy= X-Spam-Status: No, score=-18.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_SHORT autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on sourceware.org X-Spam-Level: X-HELO: us-smtp-delivery-1.mimecast.com Received: from us-smtp-2.mimecast.com (HELO us-smtp-delivery-1.mimecast.com) (207.211.31.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 07 Nov 2019 22:15:25 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1573164914; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0C2hRwYZ/aEm53+y7dL8gmVJ+sHJos1IBMi04QYiik4=; b=YXNOcJ+uS7OXpn/igirEh0Ba2XKkU6JmRAwNvhOazHiFGNKa3sD1iNDahoe3kr7hPGgt1z jFw/wMTbHR68UIyOvG1W2+WMXnUhFSqBF7RAD4LPvaiRKIf4BURzBaffzHq5Ae5juYbEf/ kDP8gEQ5+8Z+YsLydVuV7Kgl2F/y+ME= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-253-E7KM6X3vN0C1GzBs0LjmPg-1; Thu, 07 Nov 2019 17:15:13 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4C48F1800D6B for ; Thu, 7 Nov 2019 22:15:12 +0000 (UTC) Received: from greed.delorie.com (ovpn-116-12.phx2.redhat.com [10.3.116.12]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1C6C03CCA for ; Thu, 7 Nov 2019 22:15:12 +0000 (UTC) Received: from greed.delorie.com.redhat.com (localhost [127.0.0.1]) by greed.delorie.com (8.14.7/8.14.7) with ESMTP id xA7MFBAT002168 for ; Thu, 7 Nov 2019 17:15:11 -0500 Date: Tue, 01 Jan 2019 00:00:00 -0000 Message-Id: From: DJ Delorie To: libc-stable@sourceware.org Subject: [2.29 COMMITTED] Fix alignment of TLS variables for tls variant TLS_TCB_AT_TP [BZ #23403] X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-MC-Unique: E7KM6X3vN0C1GzBs0LjmPg-1 X-Mimecast-Spam-Score: 0 Content-Type: text/plain; charset=WINDOWS-1252 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes X-SW-Source: 2019-11/txt/msg00009.txt.bz2 =46rom 8646009efd1df151cc796055c7f6306495835577 Mon Sep 17 00:00:00 2001 From: Stefan Liebler Date: Wed, 6 Feb 2019 09:06:34 +0100 Subject: Fix alignment of TLS variables for tls variant TLS_TCB_AT_TP [BZ #23403] The alignment of TLS variables is wrong if accessed from within a thread for architectures with tls variant TLS_TCB_AT_TP. For the main thread the static tls data is properly aligned. For other threads the alignment depends on the alignment of the thread pointer as the static tls data is located relative to this pointer. This patch adds this alignment for TLS_TCB_AT_TP variants in the same way as it is already done for TLS_DTV_AT_TP. The thread pointer is also already properly aligned if the user provides its own stack for the new thread. This patch extends the testcase nptl/tst-tls1.c in order to check the alignment of the tls variables and it adds a pthread_create invocation with a user provided stack. The test itself is migrated from test-skeleton.c to test-driver.c and the missing support functions xpthread_attr_setstack and xposix_memalign are added. ChangeLog: [BZ #23403] * nptl/allocatestack.c (allocate_stack): Align pointer pd for TLS_TCB_AT_TP tls variant. * nptl/tst-tls1.c: Migrate to support/test-driver.c. Add alignment checks. * support/Makefile (libsupport-routines): Add xposix_memalign and xpthread_setstack. * support/support.h: Add xposix_memalign. * support/xthread.h: Add xpthread_attr_setstack. * support/xposix_memalign.c: New File. * support/xpthread_attr_setstack.c: Likewise. (cherry picked from commit bc79db3fd487daea36e7c130f943cfb9826a41b4) diff --git a/ChangeLog b/ChangeLog index c0af7c3005..8c8b884edb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2019-02-06 Stefan Liebler + + [BZ #23403] + * nptl/allocatestack.c (allocate_stack): Align pointer pd for + TLS_TCB_AT_TP tls variant. + * nptl/tst-tls1.c: Migrate to support/test-driver.c. + Add alignment checks. + * support/Makefile (libsupport-routines): Add xposix_memalign and + xpthread_setstack. + * support/support.h: Add xposix_memalign. + * support/xthread.h: Add xpthread_attr_setstack. + * support/xposix_memalign.c: New File. + * support/xpthread_attr_setstack.c: Likewise. + 2019-06-18 Florian Weimer =20 [BZ #24323] diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 670cb8ffe6..590350647b 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -572,7 +572,9 @@ allocate_stack (const struct pthread_attr *attr, struct= pthread **pdp, =20 /* Place the thread descriptor at the end of the stack. */ #if TLS_TCB_AT_TP - pd =3D (struct pthread *) ((char *) mem + size) - 1; + pd =3D (struct pthread *) ((((uintptr_t) mem + size) + - TLS_TCB_SIZE) + & ~__static_tls_align_m1); #elif TLS_DTV_AT_TP pd =3D (struct pthread *) ((((uintptr_t) mem + size - __static_tls_size) diff --git a/nptl/tst-tls1.c b/nptl/tst-tls1.c index 00489e23e9..1a915224a7 100644 --- a/nptl/tst-tls1.c +++ b/nptl/tst-tls1.c @@ -19,12 +19,16 @@ #include #include #include - +#include +#include +#include +#include +#include =20 struct test_s { - int a; - int b; + __attribute__ ((aligned(0x20))) int a; + __attribute__ ((aligned(0x200))) int b; }; =20 #define INIT_A 1 @@ -36,15 +40,34 @@ __thread struct test_s s __attribute__ ((tls_model ("in= itial-exec"))) =3D .b =3D INIT_B }; =20 +/* Use noinline in combination with not static to ensure that the + alignment check is really done. Otherwise it was optimized out! */ +__attribute__ ((noinline)) void +check_alignment (const char *thr_name, const char *ptr_name, + int *ptr, int alignment) +{ + uintptr_t offset_aligment =3D ((uintptr_t) ptr) & (alignment - 1); + if (offset_aligment) + { + FAIL_EXIT1 ("%s (%p) is not 0x%x-byte aligned in %s thread\n", + ptr_name, ptr, alignment, thr_name); + } +} + +static void +check_s (const char *thr_name) +{ + if (s.a !=3D INIT_A || s.b !=3D INIT_B) + FAIL_EXIT1 ("initial value of s in %s thread wrong\n", thr_name); + + check_alignment (thr_name, "s.a", &s.a, 0x20); + check_alignment (thr_name, "s.b", &s.b, 0x200); +} =20 static void * tf (void *arg) { - if (s.a !=3D INIT_A || s.b !=3D INIT_B) - { - puts ("initial value of s in child thread wrong"); - exit (1); - } + check_s ("child"); =20 ++s.a; =20 @@ -55,25 +78,14 @@ tf (void *arg) int do_test (void) { - if (s.a !=3D INIT_A || s.b !=3D INIT_B) - { - puts ("initial value of s in main thread wrong"); - exit (1); - } + check_s ("main"); =20 pthread_attr_t a; =20 - if (pthread_attr_init (&a) !=3D 0) - { - puts ("attr_init failed"); - exit (1); - } + xpthread_attr_init (&a); =20 - if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) !=3D 0) - { - puts ("attr_setstacksize failed"); - return 1; - } +#define STACK_SIZE (1 * 1024 * 1024) + xpthread_attr_setstacksize (&a, STACK_SIZE); =20 #define N 10 int i; @@ -83,29 +95,25 @@ do_test (void) pthread_t th[M]; int j; for (j =3D 0; j < M; ++j, ++s.a) - if (pthread_create (&th[j], &a, tf, NULL) !=3D 0) - { - puts ("pthread_create failed"); - exit (1); - } + th[j] =3D xpthread_create (&a, tf, NULL); =20 for (j =3D 0; j < M; ++j) - if (pthread_join (th[j], NULL) !=3D 0) - { - puts ("pthread_join failed"); - exit (1); - } + xpthread_join (th[j]); } =20 - if (pthread_attr_destroy (&a) !=3D 0) - { - puts ("attr_destroy failed"); - exit (1); - } + /* Also check the alignment of the tls variables if a misaligned stack is + specified. */ + pthread_t th; + void *thr_stack =3D NULL; + thr_stack =3D xposix_memalign (0x200, STACK_SIZE + 1); + xpthread_attr_setstack (&a, thr_stack + 1, STACK_SIZE); + th =3D xpthread_create (&a, tf, NULL); + xpthread_join (th); + free (thr_stack); + + xpthread_attr_destroy (&a); =20 return 0; } =20 - -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include diff --git a/support/Makefile b/support/Makefile index e0c25ecb79..a9b5eb4b05 100644 --- a/support/Makefile +++ b/support/Makefile @@ -100,10 +100,12 @@ libsupport-routines =3D \ xopen \ xpipe \ xpoll \ + xposix_memalign \ xpthread_attr_destroy \ xpthread_attr_init \ xpthread_attr_setdetachstate \ xpthread_attr_setguardsize \ + xpthread_attr_setstack \ xpthread_attr_setstacksize \ xpthread_barrier_destroy \ xpthread_barrier_init \ diff --git a/support/support.h b/support/support.h index 1a45ecbb14..b162491be6 100644 --- a/support/support.h +++ b/support/support.h @@ -86,6 +86,7 @@ int support_descriptor_supports_holes (int fd); void *xmalloc (size_t) __attribute__ ((malloc)); void *xcalloc (size_t n, size_t s) __attribute__ ((malloc)); void *xrealloc (void *p, size_t n); +void *xposix_memalign (size_t alignment, size_t n); char *xasprintf (const char *format, ...) __attribute__ ((format (printf, 1, 2), malloc)); char *xstrdup (const char *); diff --git a/support/xposix_memalign.c b/support/xposix_memalign.c new file mode 100644 index 0000000000..5501a0846a --- /dev/null +++ b/support/xposix_memalign.c @@ -0,0 +1,35 @@ +/* Error-checking wrapper for posix_memalign. + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +void * +xposix_memalign (size_t alignment, size_t n) +{ + void *p =3D NULL; + + int ret =3D posix_memalign (&p, alignment, n); + if (ret) + { + errno =3D ret; + oom_error ("posix_memalign", n); + } + return p; +} diff --git a/support/xpthread_attr_setstack.c b/support/xpthread_attr_setst= ack.c new file mode 100644 index 0000000000..c3772e240b --- /dev/null +++ b/support/xpthread_attr_setstack.c @@ -0,0 +1,26 @@ +/* pthread_attr_setstack with error checking. + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +void +xpthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, size_t stac= ksize) +{ + xpthread_check_return ("pthread_attr_setstack", + pthread_attr_setstack (attr, stackaddr, stacksize)); +} diff --git a/support/xthread.h b/support/xthread.h index 9fe1f68b3b..5204f78ed2 100644 --- a/support/xthread.h +++ b/support/xthread.h @@ -68,6 +68,8 @@ void xpthread_attr_destroy (pthread_attr_t *attr); void xpthread_attr_init (pthread_attr_t *attr); void xpthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate); +void xpthread_attr_setstack (pthread_attr_t *attr, void *stackaddr, + size_t stacksize); void xpthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize); void xpthread_attr_setguardsize (pthread_attr_t *attr,