From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x62b.google.com (mail-pl1-x62b.google.com [IPv6:2607:f8b0:4864:20::62b]) by sourceware.org (Postfix) with ESMTPS id 669C9385840D for ; Tue, 19 Dec 2023 19:28:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 669C9385840D Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 669C9385840D Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::62b ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703014119; cv=none; b=tTQVQUlU0pCA6lqzv+JpUiMN0uQ+kvSjrKi209Tl/uLpv/yRYbZmhC1/4AiKKbbOTtpRe9s0SMJikVcDM/URenWMW6yWR1SIdsbprsH05tqFubc72qjphUrNJyhoIQTzHwZNZuK7IYzqm9+OshmJJaCw0arfs+GcZeBCV/2j5kQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1703014119; c=relaxed/simple; bh=3Bn0WOOvd2yRsb/Z39RLxHfy/GMMdpr7y9gmROFHzDs=; h=DKIM-Signature:Message-ID:Date:MIME-Version:Subject:To:From; b=NsAhCSvKwENJKw77Xx7OyfB5RPfhgq0+W+ONfcSvqK1m56Dadw85IXtZ+yAHlgrdjXY7CDAfSiyj7cg76CnltDGw2sHaIJPOa2iJVBDW+66DpAtSR/iDRGy7Vdll3YjqB2pR2oIGGYY590f9/Nzt281GgBohuGaMG0KNcNsi2Xc= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x62b.google.com with SMTP id d9443c01a7336-1d3ec3db764so689465ad.2 for ; Tue, 19 Dec 2023 11:28:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1703014116; x=1703618916; darn=sourceware.org; h=content-transfer-encoding:in-reply-to:organization:from:references :to:content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=22jQ+YBw1X/Q9N8yKX/zitIYaSw1fwKkEkUxZ5MnRXs=; b=dhdQvNCUmoWfY9jSyhQCnC/GYloLjLcumXPAz6pe98q+7gsXvvABRcf+bJQR+Ef3fp VEO40K+ESJt8rpWgRkoU4+CuZe+l3nUjqphOElrPGtPVKjVWigoKWbPML3zmrPp2vCP7 sLi/pauVRansa47yBIIoSYoeyE+TnON6QWLnVQ1GLC83dbflB7422hoAsTFdwka9IH01 6+9ggl568X9z2mg9MfeHfuehCO2PoyCt5LB6M5LQ+XG41OKqrRNj1FbStsbrF1H0zsJU YfCZwi2kbvZgN77W9m7YADtpeVffwuJCPfyvuFo/ULuGG7BBmtn6u9ven7WNx5CXLo0P s/LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703014116; x=1703618916; h=content-transfer-encoding:in-reply-to:organization:from:references :to:content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=22jQ+YBw1X/Q9N8yKX/zitIYaSw1fwKkEkUxZ5MnRXs=; b=fUL6H7sidTbVlX5ECGy5WhD82ZD7NWvQgTm2hBpiKKUmX1yxQuc2YPHoCVM/nfLiBd FVIsNi95j/ReinCiKASVBv4kFP19zsCbNQ41vluNWbhVqrpO59BBENTYd4+p0UqlQP5D 0A9oDnCS3L98fCFAiXzhP1FnvB+0X79IM30VNHcwkPKiSY1+wWR8MP9Jv/4UO5+jO9mF 2r/aCCY/Nl+5vPvAaqn0qCJYx6S6nqxwATVGK7CI9a10g8o8oTgYdVj5Rf6D0y4p7GNC 0hr6YNBAkLJGTQmvqDjSBLp73v+vYlMqoFTJHsVzwbV5pGI9+MVrVK21HTzVJyGKScep 9ULA== X-Gm-Message-State: AOJu0YxqbMeUuwxcYu4H+MSS6hAfR9R6A2a/KLq4NVCZ70uWUXHrrhYY pbo6iWe7+XeO3ICvQVKR31jKXw== X-Google-Smtp-Source: AGHT+IElX+0rXQ1BnQJ5ddUZB9uymHBaZpkyNgISjFRFF33I6Qb3IbOBVbTI5CPM/3NvmI7zWJUnPQ== X-Received: by 2002:a17:903:285:b0:1d3:e582:fa69 with SMTP id j5-20020a170903028500b001d3e582fa69mr1098581plr.70.1703014116261; Tue, 19 Dec 2023 11:28:36 -0800 (PST) Received: from ?IPV6:2804:1b3:a7c3:f221:61c5:6e1b:a722:cc66? ([2804:1b3:a7c3:f221:61c5:6e1b:a722:cc66]) by smtp.gmail.com with ESMTPSA id w14-20020a1709027b8e00b001d0ced578aasm21433587pll.307.2023.12.19.11.28.34 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 19 Dec 2023 11:28:35 -0800 (PST) Message-ID: <8b33f157-5ff0-4a52-91c3-87996c063b5d@linaro.org> Date: Tue, 19 Dec 2023 16:28:33 -0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] elf: Add TLS modid reuse test for bug 29039 Content-Language: en-US To: Szabolcs Nagy , libc-alpha@sourceware.org References: <20231130081119.1252882-1-szabolcs.nagy@arm.com> From: Adhemerval Zanella Netto Organization: Linaro In-Reply-To: <20231130081119.1252882-1-szabolcs.nagy@arm.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_NUMSUBJECT,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE,URIBL_BLACK autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 30/11/23 05:11, Szabolcs Nagy wrote: > This is a minimal regression test for bug 29039 which only affects > targets with TLSDESC and a reproducer requires that > > 1) Have modid gaps (closed modules) with old generation. > 2) Update a DTV to a newer generation (needs a newer dlopen). > 3) But do not update the closed gap entry in that DTV. > 4) Reuse the modid gap for a new module (another dlopen). > 5) Use dynamic TLSDESC in that new module with old generation (bug). > 6) Access TLS via this TLSDESC and the now outdated DTV. > > However step (3) in practice rarely happens: during DTV update the > entries for closed modids are initialized to "unallocated" and then > dynamic TLSDESC calls __tls_get_addr independently of its generation. > The only exception to this is DTV setup at thread creation (gaps are > initialized to NULL instead of unallocated) or DTV resize where the > gap entries are outside the previous DTV array (again NULL instead > of unallocated, and this requires loading > DTV_SURPLUS modules). > > So the bug can only cause NULL (+ offset) dereference, not use after > free. And the easiest way to get (3) is via thread creation. > > Note that step (5) requires that the newly loaded module has larger > TLS than the remaining optional static TLS. And for (6) there cannot > be other TLS access or dlopen in the thread that updates the DTV. > > Tested on aarch64-linux-gnu. LGTM, thanks. Reviewed-by: Adhemerval Zanella > --- > elf/Makefile | 15 +++++++ > elf/tst-tlsgap-mod0.c | 2 + > elf/tst-tlsgap-mod1.c | 2 + > elf/tst-tlsgap-mod2.c | 2 + > elf/tst-tlsgap.c | 92 +++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 113 insertions(+) > create mode 100644 elf/tst-tlsgap-mod0.c > create mode 100644 elf/tst-tlsgap-mod1.c > create mode 100644 elf/tst-tlsgap-mod2.c > create mode 100644 elf/tst-tlsgap.c > > diff --git a/elf/Makefile b/elf/Makefile > index afec7be084..22902c18f1 100644 > --- a/elf/Makefile > +++ b/elf/Makefile > @@ -469,6 +469,7 @@ tests += \ > tst-tls21 \ > tst-tlsalign \ > tst-tlsalign-extern \ > + tst-tlsgap \ > tst-unique1 \ > tst-unique2 \ > tst-unwind-ctor \ > @@ -896,6 +897,9 @@ modules-names += \ > tst-tls20mod-bad \ > tst-tls21mod \ > tst-tlsalign-lib \ > + tst-tlsgap-mod0 \ > + tst-tlsgap-mod1 \ > + tst-tlsgap-mod2 \ > tst-tlsmod1 \ > tst-tlsmod10 \ > tst-tlsmod11 \ Ok. > @@ -3030,3 +3034,14 @@ $(objpfx)tst-nodeps2-mod.so: $(common-objpfx)libc.so \ > $(LINK.o) -Wl,--no-as-needed -nostartfiles -nostdlib -shared -o $@ $^ > $(objpfx)tst-nodeps2.out: \ > $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.so > + > +$(objpfx)tst-tlsgap: $(shared-thread-library) > +$(objpfx)tst-tlsgap.out: \ > + $(objpfx)tst-tlsgap-mod0.so \ > + $(objpfx)tst-tlsgap-mod1.so \ > + $(objpfx)tst-tlsgap-mod2.so > +ifeq (yes,$(have-mtls-dialect-gnu2)) > +CFLAGS-tst-tlsgap-mod0.c += -mtls-dialect=gnu2 > +CFLAGS-tst-tlsgap-mod1.c += -mtls-dialect=gnu2 > +CFLAGS-tst-tlsgap-mod2.c += -mtls-dialect=gnu2 > +endif Ok. > diff --git a/elf/tst-tlsgap-mod0.c b/elf/tst-tlsgap-mod0.c > new file mode 100644 > index 0000000000..1478b0beac > --- /dev/null > +++ b/elf/tst-tlsgap-mod0.c > @@ -0,0 +1,2 @@ > +int __thread tls0; > +int *f0(void) { return &tls0; } > diff --git a/elf/tst-tlsgap-mod1.c b/elf/tst-tlsgap-mod1.c > new file mode 100644 > index 0000000000..b10fc3702c > --- /dev/null > +++ b/elf/tst-tlsgap-mod1.c > @@ -0,0 +1,2 @@ > +int __thread tls1[100]; /* Size > glibc.rtld.optional_static_tls / 2. */ > +int *f1(void) { return tls1; } > diff --git a/elf/tst-tlsgap-mod2.c b/elf/tst-tlsgap-mod2.c > new file mode 100644 > index 0000000000..166c27d7f3 > --- /dev/null > +++ b/elf/tst-tlsgap-mod2.c > @@ -0,0 +1,2 @@ > +int __thread tls2; > +int *f2(void) { return &tls2; } > diff --git a/elf/tst-tlsgap.c b/elf/tst-tlsgap.c Ok. > new file mode 100644 > index 0000000000..4932885076 > --- /dev/null > +++ b/elf/tst-tlsgap.c > @@ -0,0 +1,92 @@ > +/* TLS modid gap reuse regression test for bug 29039. > + Copyright (C) 2023 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 > +#include > +#include > +#include > + > +static void *mod[3]; > +#define MOD(i) "tst-tlsgap-mod" #i ".so" > +static const char *modname[3] = { MOD(0), MOD(1), MOD(2) }; > +#undef MOD > + > +static void > +open_mod (int i) > +{ > + mod[i] = xdlopen (modname[i], RTLD_LAZY); > + printf ("open %s\n", modname[i]); > +} > + > +static void > +close_mod (int i) > +{ > + xdlclose (mod[i]); > + mod[i] = NULL; > + printf ("close %s\n", modname[i]); > +} > + > +static void > +access_mod (int i, const char *sym) > +{ > + int *(*f) (void) = xdlsym (mod[i], sym); > + int *p = f (); > + printf ("access %s: %s() = %p\n", modname[i], sym, p); > + TEST_VERIFY_EXIT (p != NULL); > + ++*p; > +} > + > +static void * > +start (void *arg) > +{ > + /* The DTV generation is at the last dlopen of mod0 and the > + entry for mod1 is NULL. */ > + > + open_mod (1); /* Reuse modid of mod1. Uses dynamic TLS. */ > + > + /* DTV is unchanged: dlopen only updates the DTV to the latest > + generation if static TLS is allocated for a loaded module. > + > + With bug 29039, the TLSDESC relocation in mod1 uses the old > + dlclose generation of mod1 instead of the new dlopen one so > + DTV is not updated on TLS access. */ > + > + access_mod (1, "f1"); > + > + return arg; > +} > + > +static int > +do_test (void) > +{ > + open_mod (0); > + open_mod (1); > + open_mod (2); > + close_mod (0); > + close_mod (1); /* Create modid gap at mod1. */ > + open_mod (0); /* Reuse modid of mod0, bump generation count. */ > + > + /* Create a thread where DTV of mod1 is NULL. */ > + pthread_t t = xpthread_create (NULL, start, NULL); > + xpthread_join (t); > + return 0; > +} > + > +#include Ok.