From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by sourceware.org (Postfix) with ESMTPS id 5C8F93858C2B for ; Mon, 19 Dec 2022 19:28:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5C8F93858C2B Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-ej1-x631.google.com with SMTP id bj12so23919478ejb.13 for ; Mon, 19 Dec 2022 11:28:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=8S9R0UlCEd1FKHxlJuf5d9rVEpjFjgItoz/rLOipcQo=; b=GDQhHUUFe1kn+ZywJP9hiSoN+rD7d4dtcU/RsNtPV8qFEYIvseaOiNu4kYt8ZAVR8u zz5ojXhb1iiWTaxo29J621ziF7JTZL08Y2BsP2/eWWTsEstDetV6CRX+5mm7eQXmZKAq pUOJDSSczZP07N1bufCZaXXDx8TCRSaeC97NlL03duSo/QjMmh3VvJDeJ5UhyBZFMRRX If2XwpfcQmh3lS58KTb5m9ewZ/CV3LpZSEoyMpStoZb4ktHXEY92oVT7sWjWcgrm2Gin 6Z2CZlVA+0Iq9U0Hn8ss1fTTyjW05eaLS9ObTH7poKsOk+1K4bn0xrnFLEH0rk87F5dT 4ZYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=8S9R0UlCEd1FKHxlJuf5d9rVEpjFjgItoz/rLOipcQo=; b=wWBc01U5+Ys1Ql6itc3uGRBbBrPLRo2JhKFoHnpc000k9rxqs9bmI/1LyMFuhIGLGK AuBkLxFQrdpr0dzEfo0mEDToSjSuV91iAfv2UMjsT6peqJcs22Twj+O9DiKkP4pnLmaU cTgoiL+Wc0x9hWPcka8+jMR3jzpMNvWs/LWpEcCUBLxu/tF/7fYsdCevTK2GlxjMOj5I ccswlrmwsSUfRi2ErsRBIHsG1rxkqZYU+7raRm9x+NNz1LH6vSKDtb6rUypQt+63zz4r JxG8LVVvYJaOne4ju1RCFGUYfzh79eCf9E/g55smhp+oVvSpIvsLH+UtzQM6pH8smplk L1Hw== X-Gm-Message-State: ANoB5pm4utNyg+Je2UHWntYdDP53Z9GChl1VOg/ULCkfd3QrAN6F96pg fCtoX8QEglOSBdvlYvLaiRVBbqlmsvuroeng6OJmIX4TLZY= X-Google-Smtp-Source: AMrXdXtC9yd4DrF1m6RhW8GczoXlyAMRlGbNAnoLDuvn+X3NFBcLbEM8WECYkrCAdVcpaz+kMhy5Qa8+W3SobeIsCS4= X-Received: by 2002:a17:907:9c05:b0:7c3:6be3:279e with SMTP id ld5-20020a1709079c0500b007c36be3279emr2945676ejc.526.1671478131706; Mon, 19 Dec 2022 11:28:51 -0800 (PST) MIME-Version: 1.0 References: <20221219192726.999818-1-goldstein.w.n@gmail.com> <20221219192726.999818-2-goldstein.w.n@gmail.com> In-Reply-To: <20221219192726.999818-2-goldstein.w.n@gmail.com> From: Noah Goldstein Date: Mon, 19 Dec 2022 11:28:41 -0800 Message-ID: Subject: Re: [PATCH v1 2/2] nptl: Add a testcase for inputs racey to {w}memcmp{eq} BZ #29863 To: libc-alpha@sourceware.org Cc: hjl.tools@gmail.com, carlos@systemhalted.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-9.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,GIT_PATCH_0,KAM_NUMSUBJECT,KAM_SHORT,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP 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 Mon, Dec 19, 2022 at 11:27 AM Noah Goldstein wrote: > > Add test that modifies data as {w}memcmp{eq} runs (creating a race > condition). Failures from this tests do not inherently mean the > {w}memcmp{eq} implementation is buggy, but is at the very least > something we should be aware of. > > Success is no SIGSEGV. Failure is a SIGSEGV. > > Verified test failed 10/10 times without: > > commit b712be52645282c706a5faa038242504feb06db5 > Author: Noah Goldstein > Date: Wed Dec 14 10:52:10 2022 -0800 > > x86: Prevent SIGSEGV in memcmp-sse2 when data is concurrently modified [BZ #29863] > > And passes with the fix. NB: Forget tag "Co-authored-by: H.J. Lu ", will add before commit or next version if more revisions are needed. > --- > nptl/Makefile | 7 ++ > nptl/tst-memcmp-race.c | 149 +++++++++++++++++++++++++++++++++++++++ > nptl/tst-memcmpeq-race.c | 19 +++++ > nptl/tst-wmemcmp-race.c | 20 ++++++ > 4 files changed, 195 insertions(+) > create mode 100644 nptl/tst-memcmp-race.c > create mode 100644 nptl/tst-memcmpeq-race.c > create mode 100644 nptl/tst-wmemcmp-race.c > > diff --git a/nptl/Makefile b/nptl/Makefile > index fc955cd604..5f56bdc80a 100644 > --- a/nptl/Makefile > +++ b/nptl/Makefile > @@ -285,6 +285,8 @@ tests = \ > tst-exec4 \ > tst-exec5 \ > tst-initializers1 $(addprefix tst-initializers1-,c89 gnu89 c99 gnu99 c11 gnu11) \ > + tst-memcmp-race \ > + tst-memcmpeq-race \ > tst-minstack-cancel \ > tst-minstack-exit \ > tst-minstack-throw \ > @@ -348,8 +350,13 @@ tests = \ > tst-thread_local1 \ > tst-tsd3 \ > tst-tsd4 \ > + tst-wmemcmp-race \ > # tests > > +CFLAGS-tst-memcmp-race.c += -O0 > +CFLAGS-tst-memcmpeq-race.c += -O0 > +CFLAGS-tst-wmemcmp-race.c += -O0 > + > tests-nolibpthread = \ > tst-pthread_exit-nothreads \ > tst-pthread_exit-nothreads-static \ > diff --git a/nptl/tst-memcmp-race.c b/nptl/tst-memcmp-race.c > new file mode 100644 > index 0000000000..56e62b2f7b > --- /dev/null > +++ b/nptl/tst-memcmp-race.c > @@ -0,0 +1,149 @@ > +/* Test case for memcmp with race condition. > + Copyright (C) 2022 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 > + . */ > + > +/* Verify that there is no segfault when one thread is updating the > + memory block of memcmp and the other thread is doing memcmp. > + > + NOTE: This test failing does not automatically mean the > + {w}memcmp{eq} is incorrect. This is testing UB and behavior that > + is supported. That being said, users may expect that the mem* > + functions never access out of bounds data (even with data races) > + and we should be aware of the cases when we do. */ > + > +#define TEST_MAIN > +#define MIN_PAGE_SIZE 4096 > + > +#ifdef TEST_MEMCMPEQ > +# define MEMCMP __memcmpeq > +# define TEST_NAME "__memcmpeq" > +#elif defined WIDE > +# define MEMCMP wmemcmp > +# define TEST_NAME "wmemcmp" > +#else > +# define MEMCMP memcmp > +# define TEST_NAME "memcmp" > +#endif > + > +#ifdef WIDE > +# define MEMSET wmemset > +# define CHAR wchar_t > +#else > +# define MEMSET memset > +# define CHAR char > +#endif > + > +#include > +#include > +#include > +#include > +#include > + > +#define NUM_THREADS 2 > +#define LOOP1 10000 > +#define LOOP2 1000000 > + > +typedef int (*proto_t) (const CHAR *, const CHAR *, size_t); > + > +IMPL (MEMCMP, 1) > + > +struct arg > +{ > + proto_t func; > + CHAR *a; > + CHAR *b; > + size_t len; > + size_t wpos; > + int todo; > +}; > + > +static void * > +childThread (void *tArgs) > +{ > + struct arg *args = (struct arg *) tArgs; > + int i; > + if (0 == args->todo % 2) > + { > + for (i = 0; i < LOOP1; i++) > + { > + volatile int result = args->func (args->a, args->b, args->len); > + (void)(result); > + } > + } > + else > + { > + for (i = 0; i < LOOP2; i++) > + args->a[args->wpos] = i & 1; > + args->a[args->wpos] = 1; > + } > + return NULL; > +} > + > +static void > +do_one_test (proto_t func, size_t len) > +{ > + int r; > + if (len * sizeof (CHAR) > page_size) > + return; > + for (r = 0; r < 2; ++r) > + { > + size_t wpos; > + for (wpos = 1; wpos < 128 && wpos <= len; wpos = wpos + wpos + 1) > + { > + int i; > + size_t off; > + pthread_t threads[NUM_THREADS]; > + struct arg a[NUM_THREADS]; > + > + off = r ? (page_size - len * sizeof (CHAR)) : 0; > + for (i = 0; i < NUM_THREADS; ++i) > + { > + a[i].func = func; > + a[i].a = (CHAR *) (buf1 + off); > + a[i].b = (CHAR *) (buf2 + off); > + a[i].len = len; > + a[i].wpos = len - wpos; > + a[i].todo = i; > + threads[i] = xpthread_create (NULL, childThread, (void *) &a[i]); > + } > + > + for (i = 0; i < NUM_THREADS; ++i) > + xpthread_join (threads[i]); > + } > + } > +} > + > +int > +test_main (void) > +{ > + test_init (); > + > + MEMSET ((CHAR *) buf1, 1, page_size / sizeof (CHAR)); > + MEMSET ((CHAR *) buf2, 1, page_size / sizeof (CHAR)); > + for (size_t i = 1; i <= 1024; i += i) > + { > + FOR_EACH_IMPL (impl, 0) > + { > + do_one_test ((proto_t) impl->fn, i); > + do_one_test ((proto_t) impl->fn, i + 1); > + do_one_test ((proto_t) impl->fn, i - 1); > + } > + } > + return 0; > +} > + > +#include > diff --git a/nptl/tst-memcmpeq-race.c b/nptl/tst-memcmpeq-race.c > new file mode 100644 > index 0000000000..7088928f49 > --- /dev/null > +++ b/nptl/tst-memcmpeq-race.c > @@ -0,0 +1,19 @@ > +/* Test case for __memcmpeq with race condition. > + Copyright (C) 2022 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 > + . */ > +#define TEST_MEMCMPEQ 1 > +#include "tst-memcmp-race.c" > diff --git a/nptl/tst-wmemcmp-race.c b/nptl/tst-wmemcmp-race.c > new file mode 100644 > index 0000000000..8278f71842 > --- /dev/null > +++ b/nptl/tst-wmemcmp-race.c > @@ -0,0 +1,20 @@ > +/* Test case for wmemcmp with race condition. > + Copyright (C) 2022 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 > +#define WIDE 1 > +#include "tst-memcmp-race.c" > -- > 2.34.1 >