From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933442AbcAMJiT (ORCPT ); Wed, 13 Jan 2016 04:38:19 -0500 Received: from terminus.zytor.com ([198.137.202.10]:48603 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933252AbcAMJiL (ORCPT ); Wed, 13 Jan 2016 04:38:11 -0500 Date: Wed, 13 Jan 2016 01:37:04 -0800 From: tip-bot for Andy Lutomirski Message-ID: Cc: hpa@zytor.com, bp@alien8.de, shuahkh@osg.samsung.com, linux-kernel@vger.kernel.org, torvalds@linux-foundation.org, tglx@linutronix.de, mingo@kernel.org, luto@kernel.org, dvlasenk@redhat.com, luto@amacapital.net, peterz@infradead.org, brgerst@gmail.com Reply-To: peterz@infradead.org, brgerst@gmail.com, luto@amacapital.net, tglx@linutronix.de, mingo@kernel.org, dvlasenk@redhat.com, luto@kernel.org, shuahkh@osg.samsung.com, bp@alien8.de, hpa@zytor.com, torvalds@linux-foundation.org, linux-kernel@vger.kernel.org In-Reply-To: <32946d714156879cd8e5d8eab044cd07557ed558.1452628504.git.luto@kernel.org> References: <32946d714156879cd8e5d8eab044cd07557ed558.1452628504.git.luto@kernel.org> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/urgent] selftests/x86: Test __kernel_sigreturn and __kernel_rt_sigreturn Git-Commit-ID: 65cacec1ba908a153cfb19c4de596a108f95970c X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 65cacec1ba908a153cfb19c4de596a108f95970c Gitweb: http://git.kernel.org/tip/65cacec1ba908a153cfb19c4de596a108f95970c Author: Andy Lutomirski AuthorDate: Tue, 12 Jan 2016 11:56:15 -0800 Committer: Ingo Molnar CommitDate: Wed, 13 Jan 2016 10:34:40 +0100 selftests/x86: Test __kernel_sigreturn and __kernel_rt_sigreturn The vdso-based sigreturn mechanism is fragile and isn't used by modern glibc so, if we break it, we'll only notice when someone tests an unusual libc. Add an explicit selftest. [ I wrote this while debugging a Bionic breakage -- my first guess was that I had somehow messed up sigreturn. I've caused problems in that code before, and it's really easy to fail to notice it because there's nothing on a modern distro that needs vdso-based sigreturn. ] Signed-off-by: Andy Lutomirski Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Shuah Khan Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/32946d714156879cd8e5d8eab044cd07557ed558.1452628504.git.luto@kernel.org Signed-off-by: Ingo Molnar --- tools/testing/selftests/x86/Makefile | 3 +- tools/testing/selftests/x86/vdso_restorer.c | 88 +++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index 398bb0e..d0c473f 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -7,7 +7,8 @@ include ../lib.mk TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault sigreturn test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \ - ldt_gdt + ldt_gdt \ + vdso_restorer TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) BINARIES_32 := $(TARGETS_C_32BIT_ALL:%=%_32) diff --git a/tools/testing/selftests/x86/vdso_restorer.c b/tools/testing/selftests/x86/vdso_restorer.c new file mode 100644 index 0000000..cb03842 --- /dev/null +++ b/tools/testing/selftests/x86/vdso_restorer.c @@ -0,0 +1,88 @@ +/* + * vdso_restorer.c - tests vDSO-based signal restore + * Copyright (c) 2015 Andrew Lutomirski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * This makes sure that sa_restorer == NULL keeps working on 32-bit + * configurations. Modern glibc doesn't use it under any circumstances, + * so it's easy to overlook breakage. + * + * 64-bit userspace has never supported sa_restorer == NULL, so this is + * 32-bit only. + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include + +/* Open-code this -- the headers are too messy to easily use them. */ +struct real_sigaction { + void *handler; + unsigned long flags; + void *restorer; + unsigned int mask[2]; +}; + +static volatile sig_atomic_t handler_called; + +static void handler_with_siginfo(int sig, siginfo_t *info, void *ctx_void) +{ + handler_called = 1; +} + +static void handler_without_siginfo(int sig) +{ + handler_called = 1; +} + +int main() +{ + int nerrs = 0; + struct real_sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.handler = handler_with_siginfo; + sa.flags = SA_SIGINFO; + sa.restorer = NULL; /* request kernel-provided restorer */ + + if (syscall(SYS_rt_sigaction, SIGUSR1, &sa, NULL, 8) != 0) + err(1, "raw rt_sigaction syscall"); + + raise(SIGUSR1); + + if (handler_called) { + printf("[OK]\tSA_SIGINFO handler returned successfully\n"); + } else { + printf("[FAIL]\tSA_SIGINFO handler was not called\n"); + nerrs++; + } + + sa.flags = 0; + sa.handler = handler_without_siginfo; + if (syscall(SYS_sigaction, SIGUSR1, &sa, 0) != 0) + err(1, "raw sigaction syscall"); + handler_called = 0; + + raise(SIGUSR1); + + if (handler_called) { + printf("[OK]\t!SA_SIGINFO handler returned successfully\n"); + } else { + printf("[FAIL]\t!SA_SIGINFO handler was not called\n"); + nerrs++; + } +}