x86/CET: Add tests with legacy shared objects

Message ID 20180718031104.GA12426@intel.com
State New, archived
Headers

Commit Message

Lu, Hongjiu July 18, 2018, 3:11 a.m. UTC
  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
  

Comments

Joseph Myers July 18, 2018, 8:19 p.m. UTC | #1
On Tue, 17 Jul 2018, H.J. Lu wrote:

> 	* 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.

I think the use of "legacy" without "cet" in test names is problematic.  
You mean legacy with respect to CET support, but there could be any number 
of new features with respect to which there are legacy objects (lacking 
support for the feature, or lacking markings indicating state with respect 
to the feature, or similar).  So I think the test names should all mention 
"cet" explicitly.
  
H.J. Lu July 18, 2018, 8:22 p.m. UTC | #2
On Wed, Jul 18, 2018 at 1:19 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> On Tue, 17 Jul 2018, H.J. Lu wrote:
>
>>       * 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.
>
> I think the use of "legacy" without "cet" in test names is problematic.
> You mean legacy with respect to CET support, but there could be any number
> of new features with respect to which there are legacy objects (lacking
> support for the feature, or lacking markings indicating state with respect
> to the feature, or similar).  So I think the test names should all mention
> "cet" explicitly.
>

Will rename tst-legacy-XX to tst-cet-legacy-XX be sufficient?

Thanks.
  
Joseph Myers July 18, 2018, 9:08 p.m. UTC | #3
On Wed, 18 Jul 2018, H.J. Lu wrote:

> On Wed, Jul 18, 2018 at 1:19 PM, Joseph Myers <joseph@codesourcery.com> wrote:
> > On Tue, 17 Jul 2018, H.J. Lu wrote:
> >
> >>       * 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.
> >
> > I think the use of "legacy" without "cet" in test names is problematic.
> > You mean legacy with respect to CET support, but there could be any number
> > of new features with respect to which there are legacy objects (lacking
> > support for the feature, or lacking markings indicating state with respect
> > to the feature, or similar).  So I think the test names should all mention
> > "cet" explicitly.
> 
> Will rename tst-legacy-XX to tst-cet-legacy-XX be sufficient?

Yes (that is, for the naming issue; I have not otherwise reviewed the 
substance of the tests).
  

Patch

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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+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 <support/test-driver.c>
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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+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 <support/test-driver.c>
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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+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 <support/test-driver.c>
+#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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+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 <support/test-driver.c>
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
+   <http://www.gnu.org/licenses/>.  */
+
+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
+   <http://www.gnu.org/licenses/>.  */
+
+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"