From patchwork Mon Jun 10 20:25:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andy Lutomirski X-Patchwork-Id: 10985397 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1FB6614C0 for ; Mon, 10 Jun 2019 20:26:13 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 10E6B28355 for ; Mon, 10 Jun 2019 20:26:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 05562285D2; Mon, 10 Jun 2019 20:26:13 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.3 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from mother.openwall.net (mother.openwall.net [195.42.179.200]) by mail.wl.linuxfoundation.org (Postfix) with SMTP id 0813428355 for ; Mon, 10 Jun 2019 20:26:11 +0000 (UTC) Received: (qmail 1786 invoked by uid 550); 10 Jun 2019 20:25:52 -0000 Mailing-List: contact kernel-hardening-help@lists.openwall.com; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-ID: Delivered-To: mailing list kernel-hardening@lists.openwall.com Received: (qmail 1658 invoked from network); 10 Jun 2019 20:25:50 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1560198338; bh=LM7HCsspgClDyFFU9bfxU7yzdejIvcxPP+NiHgQckcY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I8Qst0XkJgfUaO8LzI2g6QMlQK40vtFmOk9iX8piYgY3znc2GBX5zapAxY8+VSby1 er8N0zjs4qZiJ1iXJjl+z/70r1/g5ufTQlgWFPMtpJuAcDX8LUIZqlPcAtjiYn0FQ9 SAwge416WEwQLarrpZEoFvxWOqk9s4uNE8Lmh9yo= From: Andy Lutomirski To: x86@kernel.org Cc: LKML , Andy Lutomirski , Kees Cook , Borislav Petkov , Kernel Hardening , Peter Zijlstra , Thomas Gleixner Subject: [PATCH 3/5] x86/vsyscall: Document odd #PF's error code for vsyscalls Date: Mon, 10 Jun 2019 13:25:29 -0700 Message-Id: X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 X-Virus-Scanned: ClamAV using ClamSMTP Even if vsyscall=none, we report uer page faults on the vsyscall page as though the PROT bit in the error code was set. Add a comment explaining why this is probably okay and display the value in the test case. While we're at it, explain why our behavior is correct with respect to PKRU. If anyone really cares about more accurate emulation, we could change the behavior. Cc: Kees Cook Cc: Borislav Petkov Cc: Kernel Hardening Cc: Peter Zijlstra Cc: Thomas Gleixner Signed-off-by: Andy Lutomirski --- arch/x86/mm/fault.c | 7 +++++++ tools/testing/selftests/x86/test_vsyscall.c | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 46df4c6aae46..1b18819e8e11 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -710,6 +710,10 @@ static void set_signal_archinfo(unsigned long address, * To avoid leaking information about the kernel page * table layout, pretend that user-mode accesses to * kernel addresses are always protection faults. + * + * NB: This means that failed vsyscalls with vsyscall=none + * will have the PROT bit. This doesn't leak any + * information and does not appear to cause any problems. */ if (address >= TASK_SIZE_MAX) error_code |= X86_PF_PROT; @@ -1376,6 +1380,9 @@ void do_user_addr_fault(struct pt_regs *regs, * * The vsyscall page does not have a "real" VMA, so do this * emulation before we go searching for VMAs. + * + * PKRU never rejects instruction fetches, so we don't need + * to consider the PF_PK bit. */ if ((hw_error_code & X86_PF_INSTR) && is_vsyscall_vaddr(address)) { if (emulate_vsyscall(regs, address)) diff --git a/tools/testing/selftests/x86/test_vsyscall.c b/tools/testing/selftests/x86/test_vsyscall.c index 0b4f1cc2291c..4c9a8d76dba0 100644 --- a/tools/testing/selftests/x86/test_vsyscall.c +++ b/tools/testing/selftests/x86/test_vsyscall.c @@ -183,9 +183,13 @@ static inline long sys_getcpu(unsigned * cpu, unsigned * node, } static jmp_buf jmpbuf; +static volatile unsigned long segv_err; static void sigsegv(int sig, siginfo_t *info, void *ctx_void) { + ucontext_t *ctx = (ucontext_t *)ctx_void; + + segv_err = ctx->uc_mcontext.gregs[REG_ERR]; siglongjmp(jmpbuf, 1); } @@ -416,8 +420,11 @@ static int test_vsys_r(void) } else if (!can_read && should_read_vsyscall) { printf("[FAIL]\tWe don't have read access, but we should\n"); return 1; + } else if (can_read) { + printf("[OK]\tWe have read access\n"); } else { - printf("[OK]\tgot expected result\n"); + printf("[OK]\tWe do not have read access: #PF(0x%lx)\n", + segv_err); } #endif