]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
x86: Add x86-ibt-test.c
authorH.J. Lu <hjl.tools@gmail.com>
Mon, 16 Mar 2020 12:17:34 +0000 (05:17 -0700)
committerNiels Möller <nisse@lysator.liu.se>
Sun, 22 Mar 2020 19:56:57 +0000 (20:56 +0100)
On Linux/x86, when CET is enabled, all indirect branch targets must
start with ENDBR instruction.  Add x86-ibt-test.c to verify that missing
ENDBR instruction at indirect branch target will trigger SIGSEGV on CET
platforms.

testsuite/.test-rules.make
testsuite/Makefile.in
testsuite/x86-ibt-test.c [new file with mode: 0644]

index 922a2c7f135068bf304d29ab6d248024cf1c6005..9de8f412507942c4fb416f96f2031e12db7c4e0d 100644 (file)
@@ -178,6 +178,9 @@ xts-test$(EXEEXT): xts-test.$(OBJEXT)
 pbkdf2-test$(EXEEXT): pbkdf2-test.$(OBJEXT)
        $(LINK) pbkdf2-test.$(OBJEXT) $(TEST_OBJS) -o pbkdf2-test$(EXEEXT)
 
+x86-ibt-test$(EXEEXT): x86-ibt-test.$(OBJEXT)
+       $(LINK) x86-ibt-test.$(OBJEXT) $(TEST_OBJS) -o x86-ibt-test$(EXEEXT)
+
 sexp-test$(EXEEXT): sexp-test.$(OBJEXT)
        $(LINK) sexp-test.$(OBJEXT) $(TEST_OBJS) -o sexp-test$(EXEEXT)
 
index 813467a548bd1ccf9e52e51d717613f6ce35463b..70a9279347843aa11640226df3fef87f4dac15fc 100644 (file)
@@ -33,7 +33,8 @@ TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \
                    hmac-test.c umac-test.c \
                    meta-hash-test.c meta-cipher-test.c\
                    meta-aead-test.c meta-armor-test.c meta-mac-test.c \
-                   buffer-test.c yarrow-test.c xts-test.c pbkdf2-test.c
+                   buffer-test.c yarrow-test.c xts-test.c pbkdf2-test.c \
+                   x86-ibt-test.c
 
 TS_HOGWEED_SOURCES = sexp-test.c sexp-format-test.c \
                     rsa2sexp-test.c sexp2rsa-test.c \
diff --git a/testsuite/x86-ibt-test.c b/testsuite/x86-ibt-test.c
new file mode 100644 (file)
index 0000000..1f3d1d6
--- /dev/null
@@ -0,0 +1,69 @@
+#include "testutils.h"
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) \
+    && defined(__CET__) && defined(__linux__)
+#include <signal.h>
+
+static void
+segfault_handler(int signo)
+{
+  exit(0);
+}
+
+static void
+ibt_violation(void)
+{
+#ifdef __i386__
+  unsigned int reg;
+  asm volatile("lea 1f, %0\n\t"
+              "jmp *%0\n"
+              "1:" : "=r" (reg));
+#else
+  unsigned long long reg;
+  asm volatile("lea 1f(%%rip), %0\n\t"
+              "jmp *%0\n"
+              "1:" : "=r" (reg));
+#endif
+}
+
+#ifdef __i386__
+static unsigned int
+_get_ssp(void)
+{
+  unsigned int ssp;
+  asm volatile("xor %0, %0\n\trdsspd %0" : "=r" (ssp));
+  return ssp;
+}
+#else
+static unsigned long long
+_get_ssp(void)
+{
+  unsigned long long ssp;
+  asm volatile("xor %0, %0\n\trdsspq %0" : "=r" (ssp));
+  return ssp;
+}
+#endif
+
+void
+test_main(void)
+{
+   /* NB: This test should trigger SIGSEGV on CET platforms.  _get_ssp
+      returns the address of shadow stack pointer.  If the address of
+      shadow stack pointer is 0, SHSTK is disabled and we assume that
+      IBT is also disabled.  */
+  if (_get_ssp() == 0)
+    {
+      ibt_violation();
+      SKIP();
+    }
+
+  signal(SIGSEGV, segfault_handler);
+  ibt_violation();
+  FAIL();
+}
+#else
+void
+test_main(void)
+{
+  SKIP();
+}
+#endif