selftests/x86/sigreturn/32: Invalidate DS and ES when abusing the kernel
authorAndy Lutomirski <luto@kernel.org>
Wed, 20 Nov 2019 19:58:32 +0000 (11:58 -0800)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 21 Nov 2019 20:55:59 +0000 (21:55 +0100)
If the kernel accidentally uses DS or ES while the user values are
loaded, it will work fine for sane userspace.  In the interest of
simulating maximally insane userspace, make sigreturn_32 zero out DS
and ES for the nasty parts so that inadvertent use of these segments
will crash.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: stable@kernel.org
tools/testing/selftests/x86/sigreturn.c

index 3e49a7873f3e0558a6dde363b257114864903064..57c4f67f16ef2930b85ad6d4701756085bb7b312 100644 (file)
@@ -451,6 +451,19 @@ static void sigusr1(int sig, siginfo_t *info, void *ctx_void)
        ctx->uc_mcontext.gregs[REG_SP] = (unsigned long)0x8badf00d5aadc0deULL;
        ctx->uc_mcontext.gregs[REG_CX] = 0;
 
+#ifdef __i386__
+       /*
+        * Make sure the kernel doesn't inadvertently use DS or ES-relative
+        * accesses in a region where user DS or ES is loaded.
+        *
+        * Skip this for 64-bit builds because long mode doesn't care about
+        * DS and ES and skipping it increases test coverage a little bit,
+        * since 64-bit kernels can still run the 32-bit build.
+        */
+       ctx->uc_mcontext.gregs[REG_DS] = 0;
+       ctx->uc_mcontext.gregs[REG_ES] = 0;
+#endif
+
        memcpy(&requested_regs, &ctx->uc_mcontext.gregs, sizeof(gregset_t));
        requested_regs[REG_CX] = *ssptr(ctx);   /* The asm code does this. */