Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp588910imm; Sat, 22 Sep 2018 06:32:17 -0700 (PDT) X-Google-Smtp-Source: ANB0VdZ9CUtrX01DRmVye8jL26ez8KrkWgsb0ZOGp6EezOfExfJDFAWreShEHReC7V9pYgYL5RfP X-Received: by 2002:a62:464f:: with SMTP id t76-v6mr2625360pfa.118.1537623137329; Sat, 22 Sep 2018 06:32:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1537623137; cv=none; d=google.com; s=arc-20160816; b=TjSQ4f3Oe+SxiedZ1fQJQ3n3QY503u4hYoX9/k71u45K8+JtmTkTNrTqxc+g9WrmRz vvfIu3dWWfZdv9A0LCgzuFMdzVI59ogk1ggFmCcJesHBLWIYCrXVczmJ0pHZqEZrzBwT 1LGhXJ5HZJcEMkgsCgWQkAywMqNBP8z0X7TKtjNAfo8ns3aH15fgPonKPByxQnWzJG3o llaOfHCoAC/bk/SZ16Hfpg8aiUKxfT+NPeG60n1T0ZPB63PS8Qi+ei0hLIqXQONSzYnu owKTfj0azd6g1vIaIkxqXQY39ofnpXIsdDzSLn/GcxbvKbfHdoivHyipOrVHIKgNARTs U+ig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :message-id:in-reply-to:subject:cc:to:from:date; bh=N2aLnKZAGvKTXzdt354oKXYzIw8VUZcJpNQZmt00Afw=; b=A7EcxVYRm63NScswCpkLVW/u5jrcBTxWjO6nvrVDafssrXRaLAsiDEwQEU2YPNVTw9 4VkEhrp0E3YuhZ6B3kHN1Dn5ciMkp05sRtUktri2N4o9KQilbr8a8Y7E5UEqECp9YL2w HhjCTY9LxKg6fqYdDw4gcpRBBB8SuCWtltH00bwGEFWp2gScq42FSALJfT299LR6Lm6T 3DVUJNtF8n3CCP8yTUTZHZ1acFwia5VurZiHZKmX9oYMnxwve8u7JVJsUlZ5vb3KrvXf b6iv5+ZoyTiMN0BQrsUQLzTl813+ZtmbcrAwdM3t9M17U42FlcC0lC1aCDk8RlvU37tr ZZmw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id g70-v6si32623843pfe.4.2018.09.22.06.32.01; Sat, 22 Sep 2018 06:32:17 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731505AbeIVTYL (ORCPT + 99 others); Sat, 22 Sep 2018 15:24:11 -0400 Received: from Galois.linutronix.de ([146.0.238.70]:41644 "EHLO Galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726022AbeIVTYL (ORCPT ); Sat, 22 Sep 2018 15:24:11 -0400 Received: from tmo-109-175.customers.d1-online.com ([80.187.109.175] helo=nanos) by Galois.linutronix.de with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1g3hz6-0000nm-FC; Sat, 22 Sep 2018 15:30:08 +0200 Date: Sat, 22 Sep 2018 15:30:07 +0200 (CEST) From: Thomas Gleixner To: Peter Zijlstra cc: Jiri Kosina , "Schaufler, Casey" , Ingo Molnar , Josh Poimboeuf , Andrea Arcangeli , "Woodhouse, David" , Andi Kleen , Tim Chen , "linux-kernel@vger.kernel.org" , "x86@kernel.org" Subject: Re: [PATCH v6 0/3] Harden spectrev2 userspace-userspace protection In-Reply-To: Message-ID: References: <99FC4B6EFCEFD44486C35F4C281DC6732144EA58@ORSMSX107.amr.corp.intel.com> <20180919154828.GJ24124@hirez.programming.kicks-ass.net> <20180922101844.GF24124@hirez.programming.kicks-ass.net> User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII X-Linutronix-Spam-Score: -1.0 X-Linutronix-Spam-Level: - X-Linutronix-Spam-Status: No , -1.0 points, 5.0 required, ALL_TRUSTED=-1,SHORTCIRCUIT=-0.0001 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sat, 22 Sep 2018, Thomas Gleixner wrote: > On Sat, 22 Sep 2018, Peter Zijlstra wrote: > > This has some unfortunate duplication. > > > > Lets go with it for now, but I'll see if I can do something about that > > later. > > Yes, I know. I tried to make the duplication smaller, but all attempts > ended up being a convoluted mess. I'll try again after applying more > coffee. Lunch and coffee indeed made brain work better. The simple solution was way too obvious. Thanks, tglx 8<-------------------- --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -180,6 +181,19 @@ static void sync_current_stack_to_mm(str } } +static bool ibpb_needed(struct task_struct *tsk, u64 last_ctx_id) +{ + /* + * Check if the current (previous) task has access to the memory + * of the @tsk (next) task. If access is denied, make sure to + * issue a IBPB to stop user->user Spectre-v2 attacks. + * + * Note: __ptrace_may_access() returns 0 or -ERRNO. + */ + return (tsk && tsk->mm && tsk->mm->context.ctx_id != last_ctx_id && + ptrace_may_access_sched(tsk, PTRACE_MODE_SPEC_IBPB)); +} + void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, struct task_struct *tsk) { @@ -262,18 +276,13 @@ void switch_mm_irqs_off(struct mm_struct * one process from doing Spectre-v2 attacks on another. * * As an optimization, flush indirect branches only when - * switching into processes that disable dumping. This - * protects high value processes like gpg, without having - * too high performance overhead. IBPB is *expensive*! - * - * This will not flush branches when switching into kernel - * threads. It will also not flush if we switch to idle - * thread and back to the same process. It will flush if we - * switch to a different non-dumpable process. + * switching into a processes that can't be ptrace by the + * current one (as in such case, attacker has much more + * convenient way how to tamper with the next process than + * branch buffer poisoning). */ - if (tsk && tsk->mm && - tsk->mm->context.ctx_id != last_ctx_id && - get_dumpable(tsk->mm) != SUID_DUMP_USER) + if (static_cpu_has(X86_FEATURE_USE_IBPB) && + ibpb_needed(tsk, last_ctx_id)) indirect_branch_prediction_barrier(); if (IS_ENABLED(CONFIG_VMAP_STACK)) { --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -62,14 +62,17 @@ extern void exit_ptrace(struct task_stru #define PTRACE_MODE_READ 0x01 #define PTRACE_MODE_ATTACH 0x02 #define PTRACE_MODE_NOAUDIT 0x04 -#define PTRACE_MODE_FSCREDS 0x08 -#define PTRACE_MODE_REALCREDS 0x10 +#define PTRACE_MODE_FSCREDS 0x08 +#define PTRACE_MODE_REALCREDS 0x10 +#define PTRACE_MODE_SCHED 0x20 +#define PTRACE_MODE_IBPB 0x40 /* shorthands for READ/ATTACH and FSCREDS/REALCREDS combinations */ #define PTRACE_MODE_READ_FSCREDS (PTRACE_MODE_READ | PTRACE_MODE_FSCREDS) #define PTRACE_MODE_READ_REALCREDS (PTRACE_MODE_READ | PTRACE_MODE_REALCREDS) #define PTRACE_MODE_ATTACH_FSCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS) #define PTRACE_MODE_ATTACH_REALCREDS (PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS) +#define PTRACE_MODE_SPEC_IBPB (PTRACE_MODE_ATTACH_REALCREDS | PTRACE_MOD_IBPB) /** * ptrace_may_access - check whether the caller is permitted to access @@ -87,6 +90,20 @@ extern void exit_ptrace(struct task_stru */ extern bool ptrace_may_access(struct task_struct *task, unsigned int mode); +/** + * ptrace_may_access - check whether the caller is permitted to access + * a target task. + * @task: target task + * @mode: selects type of access and caller credentials + * + * Returns true on success, false on denial. + * + * Similar to ptrace_may_access(). Only to be called from context switch + * code. Does not call into audit and the regular LSM hooks due to locking + * constraints. + */ +extern bool ptrace_may_access_sched(struct task_struct *task, unsigned int mode); + static inline int ptrace_reparented(struct task_struct *child) { return !same_thread_group(child->real_parent, child->parent); --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -261,6 +261,9 @@ static int ptrace_check_attach(struct ta static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode) { + if (mode & PTRACE_MODE_SCHED) + return false; + if (mode & PTRACE_MODE_NOAUDIT) return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE); else @@ -328,9 +331,16 @@ static int __ptrace_may_access(struct ta !ptrace_has_cap(mm->user_ns, mode))) return -EPERM; + if (mode & PTRACE_MODE_SCHED) + return 0; return security_ptrace_access_check(task, mode); } +bool ptrace_may_access_sched(struct task_struct *task, unsigned int mode) +{ + return __ptrace_may_access(task, mode | PTRACE_MODE_SCHED); +} + bool ptrace_may_access(struct task_struct *task, unsigned int mode) { int err;