From patchwork Wed Jul 18 03:11:04 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Lu, Hongjiu" X-Patchwork-Id: 28449 Received: (qmail 125424 invoked by alias); 18 Jul 2018 03:11:56 -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 125410 invoked by uid 89); 18 Jul 2018 03:11:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, KAM_SHORT, NO_DNS_FOR_FROM autolearn=ham version=3.3.2 spammy= X-HELO: mga02.intel.com Date: Tue, 17 Jul 2018 20:11:04 -0700 From: "H.J. Lu" To: GNU C Library Subject: [PATCH] x86/CET: Add tests with legacy shared objects Message-ID: <20180718031104.GA12426@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.0 (2018-05-17) Check binary compatibility of CET-enabled executables: 1. When CET-enabled executable is used with legacy shared object at run-time, ld.so should disable SHSTK and put legacy shared objects in legacy bitmap. 2. When IBT-enabled executable dlopens legacy 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. OK for master? H.J. --- * sysdeps/x86/Makefile (tests): Add tst-legacy-1, tst-legacy-2, tst-legacy-2a, tst-legacy-3, tst-legacy-4, tst-legacy-4a, tst-legacy-4b and tst-legacy-4c. (modules-names): Add tst-legacy-mod-1, tst-legacy-mod-2 and tst-legacy-mod-4. (CFLAGS-tst-legacy-2.c): New. (CFLAGS-tst-legacy-mod-1.c): Likewise. (CFLAGS-tst-legacy-mod-2.c): Likewise. (CFLAGS-tst-legacy-3.c): Likewise. (CFLAGS-tst-legacy-4.c): Likewise. (CFLAGS-tst-legacy-mod-4.c): Likewise. ($(objpfx)tst-legacy-1): Likewise. ($(objpfx)tst-legacy-2): Likewise. ($(objpfx)tst-legacy-2.out): Likewise. ($(objpfx)tst-legacy-2a): Likewise. ($(objpfx)tst-legacy-2a.out): Likewise. ($(objpfx)tst-legacy-4): Likewise. ($(objpfx)tst-legacy-4.out): Likewise. ($(objpfx)tst-legacy-4a): Likewise. ($(objpfx)tst-legacy-4a.out): Likewise. (tst-legacy-4a-ENV): Likewise. ($(objpfx)tst-legacy-4b): Likewise. ($(objpfx)tst-legacy-4b.out): Likewise. (tst-legacy-4b-ENV): Likewise. ($(objpfx)tst-legacy-4c): Likewise. ($(objpfx)tst-legacy-4c.out): Likewise. (tst-legacy-4c-ENV): Likewise. * sysdeps/x86/tst-legacy-1.c: New file. * sysdeps/x86/tst-legacy-2.c: Likewise. * sysdeps/x86/tst-legacy-2a.c: Likewise. * sysdeps/x86/tst-legacy-3.c: Likewise. * sysdeps/x86/tst-legacy-4.c: Likewise. * sysdeps/x86/tst-legacy-4a.c: Likewise. * sysdeps/x86/tst-legacy-4b.c: Likewise. * sysdeps/x86/tst-legacy-4c.c: Likewise. * sysdeps/x86/tst-legacy-mod-1.c: Likewise. * sysdeps/x86/tst-legacy-mod-2.c: Likewise. * sysdeps/x86/tst-legacy-mod-4.c: Likewise. --- sysdeps/x86/Makefile | 37 ++++++++++++++ sysdeps/x86/tst-legacy-1.c | 44 +++++++++++++++++ sysdeps/x86/tst-legacy-2.c | 64 +++++++++++++++++++++++++ sysdeps/x86/tst-legacy-2a.c | 1 + sysdeps/x86/tst-legacy-3.c | 88 ++++++++++++++++++++++++++++++++++ sysdeps/x86/tst-legacy-4.c | 56 ++++++++++++++++++++++ sysdeps/x86/tst-legacy-4a.c | 1 + sysdeps/x86/tst-legacy-4b.c | 1 + sysdeps/x86/tst-legacy-4c.c | 1 + sysdeps/x86/tst-legacy-mod-1.c | 24 ++++++++++ sysdeps/x86/tst-legacy-mod-2.c | 24 ++++++++++ sysdeps/x86/tst-legacy-mod-4.c | 2 + 12 files changed, 343 insertions(+) create mode 100644 sysdeps/x86/tst-legacy-1.c create mode 100644 sysdeps/x86/tst-legacy-2.c create mode 100644 sysdeps/x86/tst-legacy-2a.c create mode 100644 sysdeps/x86/tst-legacy-3.c create mode 100644 sysdeps/x86/tst-legacy-4.c create mode 100644 sysdeps/x86/tst-legacy-4a.c create mode 100644 sysdeps/x86/tst-legacy-4b.c create mode 100644 sysdeps/x86/tst-legacy-4c.c create mode 100644 sysdeps/x86/tst-legacy-mod-1.c create mode 100644 sysdeps/x86/tst-legacy-mod-2.c create mode 100644 sysdeps/x86/tst-legacy-mod-4.c diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile index e9b2d0b35d..92a53bb763 100644 --- a/sysdeps/x86/Makefile +++ b/sysdeps/x86/Makefile @@ -17,6 +17,43 @@ endif ifeq ($(enable-cet),yes) ifeq ($(subdir),elf) sysdep-dl-routines += dl-cet + +tests += tst-legacy-1 tst-legacy-2 tst-legacy-2a tst-legacy-3 \ + tst-legacy-4 +ifneq (no,$(have-tunables)) +tests += tst-legacy-4a tst-legacy-4b tst-legacy-4c +endif +modules-names += tst-legacy-mod-1 tst-legacy-mod-2 tst-legacy-mod-4 + +CFLAGS-tst-legacy-2.c += -fcf-protection=branch +CFLAGS-tst-legacy-2a.c += -fcf-protection +CFLAGS-tst-legacy-mod-1.c += -fcf-protection=none +CFLAGS-tst-legacy-mod-2.c += -fcf-protection=none +CFLAGS-tst-legacy-3.c += -fcf-protection=none +CFLAGS-tst-legacy-4.c += -fcf-protection=branch +CFLAGS-tst-legacy-4a.c += -fcf-protection +CFLAGS-tst-legacy-4b.c += -fcf-protection +CFLAGS-tst-legacy-mod-4.c += -fcf-protection=none + +$(objpfx)tst-legacy-1: $(objpfx)tst-legacy-mod-1.so \ + $(objpfx)tst-legacy-mod-2.so +$(objpfx)tst-legacy-2: $(objpfx)tst-legacy-mod-2.so $(libdl) +$(objpfx)tst-legacy-2.out: $(objpfx)tst-legacy-mod-1.so +$(objpfx)tst-legacy-2a: $(objpfx)tst-legacy-mod-2.so $(libdl) +$(objpfx)tst-legacy-2a.out: $(objpfx)tst-legacy-mod-1.so +$(objpfx)tst-legacy-4: $(libdl) +$(objpfx)tst-legacy-4.out: $(objpfx)tst-legacy-mod-4.so +ifneq (no,$(have-tunables)) +$(objpfx)tst-legacy-4a: $(libdl) +$(objpfx)tst-legacy-4a.out: $(objpfx)tst-legacy-mod-4.so +tst-legacy-4a-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=permissive +$(objpfx)tst-legacy-4b: $(libdl) +$(objpfx)tst-legacy-4b.out: $(objpfx)tst-legacy-mod-4.so +tst-legacy-4b-ENV = GLIBC_TUNABLES=glibc.tune.x86_shstk=on +$(objpfx)tst-legacy-4c: $(libdl) +$(objpfx)tst-legacy-4c.out: $(objpfx)tst-legacy-mod-4.so +tst-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-legacy-1.c b/sysdeps/x86/tst-legacy-1.c new file mode 100644 index 0000000000..861c09a26e --- /dev/null +++ b/sysdeps/x86/tst-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-legacy-2.c b/sysdeps/x86/tst-legacy-2.c new file mode 100644 index 0000000000..2e6b9c4078 --- /dev/null +++ b/sysdeps/x86/tst-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-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-legacy-2a.c b/sysdeps/x86/tst-legacy-2a.c new file mode 100644 index 0000000000..1f4405a661 --- /dev/null +++ b/sysdeps/x86/tst-legacy-2a.c @@ -0,0 +1 @@ +#include "tst-legacy-2.c" diff --git a/sysdeps/x86/tst-legacy-3.c b/sysdeps/x86/tst-legacy-3.c new file mode 100644 index 0000000000..7bf0e656b1 --- /dev/null +++ b/sysdeps/x86/tst-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-legacy-4.c b/sysdeps/x86/tst-legacy-4.c new file mode 100644 index 0000000000..50f53aa1f9 --- /dev/null +++ b/sysdeps/x86/tst-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-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-legacy-4a.c b/sysdeps/x86/tst-legacy-4a.c new file mode 100644 index 0000000000..0aee4f1161 --- /dev/null +++ b/sysdeps/x86/tst-legacy-4a.c @@ -0,0 +1 @@ +#include "tst-legacy-4.c" diff --git a/sysdeps/x86/tst-legacy-4b.c b/sysdeps/x86/tst-legacy-4b.c new file mode 100644 index 0000000000..0aee4f1161 --- /dev/null +++ b/sysdeps/x86/tst-legacy-4b.c @@ -0,0 +1 @@ +#include "tst-legacy-4.c" diff --git a/sysdeps/x86/tst-legacy-4c.c b/sysdeps/x86/tst-legacy-4c.c new file mode 100644 index 0000000000..0aee4f1161 --- /dev/null +++ b/sysdeps/x86/tst-legacy-4c.c @@ -0,0 +1 @@ +#include "tst-legacy-4.c" diff --git a/sysdeps/x86/tst-legacy-mod-1.c b/sysdeps/x86/tst-legacy-mod-1.c new file mode 100644 index 0000000000..09762bce13 --- /dev/null +++ b/sysdeps/x86/tst-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-legacy-mod-2.c b/sysdeps/x86/tst-legacy-mod-2.c new file mode 100644 index 0000000000..1c8de443f6 --- /dev/null +++ b/sysdeps/x86/tst-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-legacy-mod-4.c b/sysdeps/x86/tst-legacy-mod-4.c new file mode 100644 index 0000000000..d808623676 --- /dev/null +++ b/sysdeps/x86/tst-legacy-mod-4.c @@ -0,0 +1,2 @@ +#define TEST_MODULE +#include "tst-legacy-3.c"