Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756765AbeAIM57 (ORCPT + 1 other); Tue, 9 Jan 2018 07:57:59 -0500 Received: from wtarreau.pck.nerim.net ([62.212.114.60]:39130 "EHLO 1wt.eu" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753218AbeAIM5z (ORCPT ); Tue, 9 Jan 2018 07:57:55 -0500 From: Willy Tarreau To: linux-kernel@vger.kernel.org, x86@kernel.org Cc: Willy Tarreau , Andy Lutomirski , Borislav Petkov , Brian Gerst , Dave Hansen , Ingo Molnar , Linus Torvalds , Peter Zijlstra , Thomas Gleixner , Josh Poimboeuf , "H. Peter Anvin" , Kees Cook Subject: [RFC PATCH v2 2/6] x86/arch_prctl: add ARCH_GET_NOPTI and ARCH_SET_NOPTI to enable/disable PTI Date: Tue, 9 Jan 2018 13:56:16 +0100 Message-Id: <1515502580-12261-3-git-send-email-w@1wt.eu> X-Mailer: git-send-email 2.8.0.rc2.1.gbe9624a In-Reply-To: <1515502580-12261-1-git-send-email-w@1wt.eu> References: <1515502580-12261-1-git-send-email-w@1wt.eu> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: This allows to report the current state of the PTI protection and to enable or disable it for the current process. The state change is only allowed if the mm is not shared (no threads have been created yet). Setting the flag to disable the protection is subject to CAP_SYS_RAWIO. However it is possible to re-enable the protection without this privilege. Signed-off-by: Willy Tarreau Cc: Andy Lutomirski Cc: Borislav Petkov Cc: Brian Gerst Cc: Dave Hansen Cc: Ingo Molnar Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Josh Poimboeuf Cc: "H. Peter Anvin" Cc: Kees Cook v2: - use {set,clear}_thread_flag() as recommended by Peter - use task->mm->context.pti_disable instead of task flag - check for mm_users == 1 - check for CAP_SYS_RAWIO only when setting, not clearing - make the code depend on CONFIG_PAGE_TABLE_ISOLATION --- arch/x86/include/uapi/asm/prctl.h | 3 +++ arch/x86/kernel/process_64.c | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/arch/x86/include/uapi/asm/prctl.h b/arch/x86/include/uapi/asm/prctl.h index 5a6aac9..1f1b5bc 100644 --- a/arch/x86/include/uapi/asm/prctl.h +++ b/arch/x86/include/uapi/asm/prctl.h @@ -10,6 +10,9 @@ #define ARCH_GET_CPUID 0x1011 #define ARCH_SET_CPUID 0x1012 +#define ARCH_GET_NOPTI 0x1021 +#define ARCH_SET_NOPTI 0x1022 + #define ARCH_MAP_VDSO_X32 0x2001 #define ARCH_MAP_VDSO_32 0x2002 #define ARCH_MAP_VDSO_64 0x2003 diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index c754662..9516310 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -654,7 +654,22 @@ long do_arch_prctl_64(struct task_struct *task, int option, unsigned long arg2) ret = put_user(base, (unsigned long __user *)arg2); break; } +#ifdef CONFIG_PAGE_TABLE_ISOLATION + case ARCH_GET_NOPTI: { + unsigned long flag = !!task->mm->context.pti_disable; + ret = put_user(flag, (unsigned long __user *)arg2); + break; + } + case ARCH_SET_NOPTI: + if (!task->mm || atomic_read(&task->mm->mm_users) > 1 || + (arg2 && !capable(CAP_SYS_RAWIO))) + return -EPERM; + + if (doit) + task->mm->context.pti_disable = !!arg2; + break; +#endif #ifdef CONFIG_CHECKPOINT_RESTORE # ifdef CONFIG_X86_X32_ABI case ARCH_MAP_VDSO_X32: -- 1.7.12.1