From patchwork Sat Jul 21 14:20:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 28554 Received: (qmail 83866 invoked by alias); 21 Jul 2018 14:20:54 -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 83115 invoked by uid 89); 21 Jul 2018 14:20:49 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.8 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=*fp X-HELO: mail-pg1-f193.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=a5lLwKQ2+dzfDTXsJX4Bn8cAtDNuUfMm8OZH0rJbHZc=; b=EHd6OriLALjwi5iZd9hhObXrtydvwv2QAjoxXf5q762VZdVBMt99XxFanM9zJlV13w nH4Odjty+m1HsFLfWNqORxN5uwIfciEV8kDftrBxMFR968scl1zjG/axPxspRLydn8o1 N5pmuoGj1Nz8cCAH0nUJ0JeOF8sFlH56L6w4Igha1Oi2WWxOp6NjS/X+jc/brd3lglkM 0jPo5jWQ6SfLkCD/x5M0w6JR+qL00yShQfOlXrNYUJ/uqQbWyPoiEaX9LWvIu2o/YUVO zc9KkiIpHNOI5rj0ThJ0FBrVSZUCV3K/mW2U/j8T2aUwhUlKHDzMea5HIrv8H0/5BF8x wf7g== Return-Path: From: "H.J. Lu" To: libc-alpha@sourceware.org Cc: Carlos O'Donell Subject: [PATCH 07/12] x86/CET: Add tests with legacy non-CET shared objects Date: Sat, 21 Jul 2018 07:20:30 -0700 Message-Id: <20180721142035.21059-8-hjl.tools@gmail.com> In-Reply-To: <20180721142035.21059-1-hjl.tools@gmail.com> References: <20180721142035.21059-1-hjl.tools@gmail.com> Check binary compatibility of CET-enabled executables: 1. When CET-enabled executable is used with legacy non-CET shared object at run-time, ld.so should disable SHSTK and put legacy non-CET shared objects in legacy bitmap. 2. When IBT-enabled executable dlopens legacy non-CET shared object, ld.so should put legacy shared object in legacy bitmap. 3. Use GLIBC_TUNABLES=glibc.tune.x86_shstk=[on|off|permissive] to control how SHSTK is enabled. * sysdeps/x86/Makefile (tests): Add tst-cet-legacy-1, tst-cet-legacy-2, tst-cet-legacy-2a, tst-cet-legacy-3, tst-cet-legacy-4, tst-cet-legacy-4a, tst-cet-legacy-4b and tst-cet-legacy-4c. (modules-names): Add tst-cet-legacy-mod-1, tst-cet-legacy-mod-2 and tst-cet-legacy-mod-4. (CFLAGS-tst-cet-legacy-2.c): New. (CFLAGS-tst-cet-legacy-mod-1.c): Likewise. (CFLAGS-tst-cet-legacy-mod-2.c): Likewise. (CFLAGS-tst-cet-legacy-3.c): Likewise. (CFLAGS-tst-cet-legacy-4.c): Likewise. (CFLAGS-tst-cet-legacy-mod-4.c): Likewise. ($(objpfx)tst-cet-legacy-1): Likewise. ($(objpfx)tst-cet-legacy-2): Likewise. ($(objpfx)tst-cet-legacy-2.out): Likewise. ($(objpfx)tst-cet-legacy-2a): Likewise. ($(objpfx)tst-cet-legacy-2a.out): Likewise. ($(objpfx)tst-cet-legacy-4): Likewise. ($(objpfx)tst-cet-legacy-4.out): Likewise. ($(objpfx)tst-cet-legacy-4a): Likewise. ($(objpfx)tst-cet-legacy-4a.out): Likewise. (tst-cet-legacy-4a-ENV): Likewise. ($(objpfx)tst-cet-legacy-4b): Likewise. ($(objpfx)tst-cet-legacy-4b.out): Likewise. (tst-cet-legacy-4b-ENV): Likewise. ($(objpfx)tst-cet-legacy-4c): Likewise. ($(objpfx)tst-cet-legacy-4c.out): Likewise. (tst-cet-legacy-4c-ENV): Likewise. * sysdeps/x86/tst-cet-legacy-1.c: New file. * sysdeps/x86/tst-cet-legacy-2.c: Likewise. * sysdeps/x86/tst-cet-legacy-2a.c: Likewise. * sysdeps/x86/tst-cet-legacy-3.c: Likewise. * sysdeps/x86/tst-cet-legacy-4.c: Likewise. * sysdeps/x86/tst-cet-legacy-4a.c: Likewise. * sysdeps/x86/tst-cet-legacy-4b.c: Likewise. * sysdeps/x86/tst-cet-legacy-4c.c: Likewise. * sysdeps/x86/tst-cet-legacy-mod-1.c: Likewise. * sysdeps/x86/tst-cet-legacy-mod-2.c: Likewise. * sysdeps/x86/tst-cet-legacy-mod-4.c: Likewise. Reviewed-by: Carlos O'Donell --- sysdeps/x86/Makefile | 38 +++++++++++++ sysdeps/x86/tst-cet-legacy-1.c | 44 +++++++++++++++ sysdeps/x86/tst-cet-legacy-2.c | 64 ++++++++++++++++++++++ sysdeps/x86/tst-cet-legacy-2a.c | 1 + sysdeps/x86/tst-cet-legacy-3.c | 88 ++++++++++++++++++++++++++++++ sysdeps/x86/tst-cet-legacy-4.c | 56 +++++++++++++++++++ sysdeps/x86/tst-cet-legacy-4a.c | 1 + sysdeps/x86/tst-cet-legacy-4b.c | 1 + sysdeps/x86/tst-cet-legacy-4c.c | 1 + sysdeps/x86/tst-cet-legacy-mod-1.c | 24 ++++++++ sysdeps/x86/tst-cet-legacy-mod-2.c | 24 ++++++++ sysdeps/x86/tst-cet-legacy-mod-4.c | 2 + 12 files changed, 344 insertions(+) create mode 100644 sysdeps/x86/tst-cet-legacy-1.c create mode 100644 sysdeps/x86/tst-cet-legacy-2.c create mode 100644 sysdeps/x86/tst-cet-legacy-2a.c create mode 100644 sysdeps/x86/tst-cet-legacy-3.c create mode 100644 sysdeps/x86/tst-cet-legacy-4.c create mode 100644 sysdeps/x86/tst-cet-legacy-4a.c create mode 100644 sysdeps/x86/tst-cet-legacy-4b.c create mode 100644 sysdeps/x86/tst-cet-legacy-4c.c create mode 100644 sysdeps/x86/tst-cet-legacy-mod-1.c create mode 100644 sysdeps/x86/tst-cet-legacy-mod-2.c create mode 100644 sysdeps/x86/tst-cet-legacy-mod-4.c diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile index e9b2d0b35d..672bb19489 100644 --- a/sysdeps/x86/Makefile +++ b/sysdeps/x86/Makefile @@ -17,6 +17,44 @@ endif ifeq ($(enable-cet),yes) ifeq ($(subdir),elf) sysdep-dl-routines += dl-cet + +tests += tst-cet-legacy-1 tst-cet-legacy-2 tst-cet-legacy-2a \ + tst-cet-legacy-3 tst-cet-legacy-4 +ifneq (no,$(have-tunables)) +tests += tst-cet-legacy-4a tst-cet-legacy-4b tst-cet-legacy-4c +endif +modules-names += tst-cet-legacy-mod-1 tst-cet-legacy-mod-2 \ + tst-cet-legacy-mod-4 + +CFLAGS-tst-cet-legacy-2.c += -fcf-protection=branch +CFLAGS-tst-cet-legacy-2a.c += -fcf-protection +CFLAGS-tst-cet-legacy-mod-1.c += -fcf-protection=none +CFLAGS-tst-cet-legacy-mod-2.c += -fcf-protection=none +CFLAGS-tst-cet-legacy-3.c += -fcf-protection=none +CFLAGS-tst-cet-legacy-4.c += -fcf-protection=branch +CFLAGS-tst-cet-legacy-4a.c += -fcf-protection +CFLAGS-tst-cet-legacy-4b.c += -fcf-protection +CFLAGS-tst-cet-legacy-mod-4.c += -fcf-protection=none + +$(objpfx)tst-cet-legacy-1: $(objpfx)tst-cet-legacy-mod-1.so \ + $(objpfx)tst-cet-legacy-mod-2.so +$(objpfx)tst-cet-legacy-2: $(objpfx)tst-cet-legacy-mod-2.so $(libdl) +$(objpfx)tst-cet-legacy-2.out: $(objpfx)tst-cet-legacy-mod-1.so +$(objpfx)tst-cet-legacy-2a: $(objpfx)tst-cet-legacy-mod-2.so $(libdl) +$(objpfx)tst-cet-legacy-2a.out: $(objpfx)tst-cet-legacy-mod-1.so +$(objpfx)tst-cet-legacy-4: $(libdl) +$(objpfx)tst-cet-legacy-4.out: $(objpfx)tst-cet-legacy-mod-4.so +ifneq (no,$(have-tunables)) +$(objpfx)tst-cet-legacy-4a: $(libdl) +$(objpfx)tst-cet-legacy-4a.out: $(objpfx)tst-cet-legacy-mod-4.so +tst-cet-legacy-4a-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=permissive +$(objpfx)tst-cet-legacy-4b: $(libdl) +$(objpfx)tst-cet-legacy-4b.out: $(objpfx)tst-cet-legacy-mod-4.so +tst-cet-legacy-4b-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=on +$(objpfx)tst-cet-legacy-4c: $(libdl) +$(objpfx)tst-cet-legacy-4c.out: $(objpfx)tst-cet-legacy-mod-4.so +tst-cet-legacy-4c-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=off +endif endif # Add -fcf-protection to CFLAGS when CET is enabled. diff --git a/sysdeps/x86/tst-cet-legacy-1.c b/sysdeps/x86/tst-cet-legacy-1.c new file mode 100644 index 0000000000..861c09a26e --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-1.c @@ -0,0 +1,44 @@ +/* Check compatibility of CET-enabled executable linked with legacy + shared object. + Copyright (C) 2018 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 + +extern int in_dso_1 (void); +extern int in_dso_2 (void); + +static int +do_test (void) +{ + if (in_dso_1 () != 0x1234678) + { + puts ("in_dso_1 () != 0x1234678"); + exit (1); + } + + if (in_dso_2 () != 0xbadbeef) + { + puts ("in_dso_2 () != 0xbadbeef"); + exit (1); + } + + return 0; +} + +#include diff --git a/sysdeps/x86/tst-cet-legacy-2.c b/sysdeps/x86/tst-cet-legacy-2.c new file mode 100644 index 0000000000..e039a16797 --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-2.c @@ -0,0 +1,64 @@ +/* Check compatibility of CET-enabled executable with dlopened legacy + shared object. + Copyright (C) 2018 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 + +extern int in_dso_2 (void); + +static int +do_test (void) +{ + static const char modname[] = "tst-cet-legacy-mod-1.so"; + int (*fp) (void); + void *h; + + h = dlopen (modname, RTLD_LAZY); + if (h == NULL) + { + printf ("cannot open '%s': %s\n", modname, dlerror ()); + exit (1); + } + + fp = dlsym (h, "in_dso_1"); + if (fp == NULL) + { + printf ("cannot get symbol 'in_dso': %s\n", dlerror ()); + exit (1); + } + + if (fp () != 0x1234678) + { + puts ("in_dso_1 () != 0x1234678"); + exit (1); + } + + if (in_dso_2 () != 0xbadbeef) + { + puts ("in_dso_2 () != 0xbadbeef"); + exit (1); + } + + dlclose (h); + + return 0; +} + +#include diff --git a/sysdeps/x86/tst-cet-legacy-2a.c b/sysdeps/x86/tst-cet-legacy-2a.c new file mode 100644 index 0000000000..d5aead4303 --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-2a.c @@ -0,0 +1 @@ +#include "tst-cet-legacy-2.c" diff --git a/sysdeps/x86/tst-cet-legacy-3.c b/sysdeps/x86/tst-cet-legacy-3.c new file mode 100644 index 0000000000..7bf0e656b1 --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-3.c @@ -0,0 +1,88 @@ +/* Check compatibility of CET-enabled executable with dlopened legacy + shared object. Copied from gcc.target/i386/pr81128.c in GCC testsuite. + Copyright (C) 2018 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 + +int resolver_fn = 0; +int resolved_fn = 0; + +static inline void +do_it_right_at_runtime_A (void) +{ + resolved_fn++; +} + +static inline void +do_it_right_at_runtime_B (void) +{ + resolved_fn++; +} + +static inline void do_it_right_at_runtime (void); + +void do_it_right_at_runtime (void) + __attribute__ ((ifunc ("resolve_do_it_right_at_runtime"))); + +static void (*resolve_do_it_right_at_runtime (void)) (void) +{ + srand (time (NULL)); + int r = rand (); + resolver_fn++; + + /* Use intermediate variable to get a warning for non-matching + * prototype. */ + typeof(do_it_right_at_runtime) *func; + if (r & 1) + func = do_it_right_at_runtime_A; + else + func = do_it_right_at_runtime_B; + + return (void *) func; +} + +int +test (void) +{ + const unsigned int ITERS = 10; + + for (int i = ITERS; i > 0; i--) + { + do_it_right_at_runtime (); + } + + if (resolver_fn != 1) + __builtin_abort (); + + if (resolved_fn != 10) + __builtin_abort (); + + return 0; +} + +#ifndef TEST_MODULE +static int +do_test (void) +{ + return test (); +} + +#include +#endif diff --git a/sysdeps/x86/tst-cet-legacy-4.c b/sysdeps/x86/tst-cet-legacy-4.c new file mode 100644 index 0000000000..3ead63dd24 --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-4.c @@ -0,0 +1,56 @@ +/* Check compatibility of CET-enabled executable with dlopened legacy + shared object. + Copyright (C) 2018 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 + +static int +do_test (void) +{ + static const char modname[] = "tst-cet-legacy-mod-4.so"; + int (*fp) (void); + void *h; + + h = dlopen (modname, RTLD_LAZY); + if (h == NULL) + { + printf ("cannot open '%s': %s\n", modname, dlerror ()); + exit (1); + } + + fp = dlsym (h, "test"); + if (fp == NULL) + { + printf ("cannot get symbol 'test': %s\n", dlerror ()); + exit (1); + } + + if (fp () != 0) + { + puts ("test () != 0"); + exit (1); + } + + dlclose (h); + + return 0; +} + +#include diff --git a/sysdeps/x86/tst-cet-legacy-4a.c b/sysdeps/x86/tst-cet-legacy-4a.c new file mode 100644 index 0000000000..b9bb18c36b --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-4a.c @@ -0,0 +1 @@ +#include "tst-cet-legacy-4.c" diff --git a/sysdeps/x86/tst-cet-legacy-4b.c b/sysdeps/x86/tst-cet-legacy-4b.c new file mode 100644 index 0000000000..b9bb18c36b --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-4b.c @@ -0,0 +1 @@ +#include "tst-cet-legacy-4.c" diff --git a/sysdeps/x86/tst-cet-legacy-4c.c b/sysdeps/x86/tst-cet-legacy-4c.c new file mode 100644 index 0000000000..b9bb18c36b --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-4c.c @@ -0,0 +1 @@ +#include "tst-cet-legacy-4.c" diff --git a/sysdeps/x86/tst-cet-legacy-mod-1.c b/sysdeps/x86/tst-cet-legacy-mod-1.c new file mode 100644 index 0000000000..09762bce13 --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-mod-1.c @@ -0,0 +1,24 @@ +/* Check compatibility of CET-enabled executable with legacy shared + object. + Copyright (C) 2018 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 + . */ + +int +in_dso_1 (void) +{ + return 0x1234678; +} diff --git a/sysdeps/x86/tst-cet-legacy-mod-2.c b/sysdeps/x86/tst-cet-legacy-mod-2.c new file mode 100644 index 0000000000..1c8de443f6 --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-mod-2.c @@ -0,0 +1,24 @@ +/* Check compatibility of CET-enabled executable with legacy shared + object. + Copyright (C) 2018 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 + . */ + +int +in_dso_2 (void) +{ + return 0xbadbeef; +} diff --git a/sysdeps/x86/tst-cet-legacy-mod-4.c b/sysdeps/x86/tst-cet-legacy-mod-4.c new file mode 100644 index 0000000000..a93c2fe4a7 --- /dev/null +++ b/sysdeps/x86/tst-cet-legacy-mod-4.c @@ -0,0 +1,2 @@ +#define TEST_MODULE +#include "tst-cet-legacy-3.c"