Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp5769631imm; Mon, 23 Jul 2018 05:53:49 -0700 (PDT) X-Google-Smtp-Source: AAOMgpdJCmLohkcuvGTItWgjWaSEP2jjX+lGbrbwyC9MHb/d0jxjZGqDH71V4PUOSLXi1PzxZhcc X-Received: by 2002:a17:902:42a3:: with SMTP id h32-v6mr12671499pld.72.1532350429857; Mon, 23 Jul 2018 05:53:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1532350429; cv=none; d=google.com; s=arc-20160816; b=acUudgsd943xCjExxHBSGxhhOP1R2D/eaQT9aDg0VzmuigaMefVmqWZBNNX7Cdg9cy ydaQOfZ84c5nf8EZpxRYWnOUCTzQi6ko0sui0rxk/EL3h7hZeOh/UzVOYrhm+Czctid4 1MDJwIEVlf50VY3q+7uuRtkWkt7GViv3M3Xi7bSILAbTKbd8KWumDjIx8tm507FUO+uA 4c+ZcEaCGAD1Ib3YbrKkzuKomfwo2OdAtaxAA0wiggfM9sQhnW3I+S9rAEWpWOELgoSN s+1DFcX7Yr0fCpTECjt3UgwzSZwjln0ecJf1i807cV+YJPU9MatNSOT2JcynNUHimLTJ Jg0w== 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 :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=udnQnoGyO/xACS3FuoKAz96YVfssKVCEw6SCwwD24JI=; b=dgY+saIdRcqr4fosD9W9nGvjFJHl3/CH4hYxw3RFdt3N8L0sB23Ue5VkV4qNSKL7BW gKMpmxVEzIiBCK7NDVDt0kwRwzSQOD14YUnJyq7XKhr4qInJ+oYhszhNC7fTcHgOmVWi LAjLtmvFZAcfETlIOo4u2ZG+TrxfRudyHExkP8bXRLSwEy0RujYKZ9+MFXpcqzY2msJH Olmd4OPDPeORIFS29hIfv5jkb+orbHv7ruY3XT3B/QNGWBE1gN+PmasU4N20aKU4ucQb m1SLTfrbsD1hCrII2cxRId+4kKQQmBVo52ytbar3RqTttVN7zCNdsswLhCl1IgcK29QZ +PzA== 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 g11-v6si8144753plb.100.2018.07.23.05.53.32; Mon, 23 Jul 2018 05:53:49 -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 S2388722AbeGWNw5 (ORCPT + 99 others); Mon, 23 Jul 2018 09:52:57 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:51386 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388391AbeGWNrw (ORCPT ); Mon, 23 Jul 2018 09:47:52 -0400 Received: from localhost (LFbn-1-12238-233.w90-92.abo.wanadoo.fr [90.92.53.233]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id D6C14CB7; Mon, 23 Jul 2018 12:45:46 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Kees Cook , Thomas Gleixner , David Woodhouse , "Srivatsa S. Bhat" , "Matt Helsley (VMware)" , Alexey Makhalov , Bo Gan Subject: [PATCH 4.4 073/107] seccomp: Add filter flag to opt-out of SSB mitigation Date: Mon, 23 Jul 2018 14:42:07 +0200 Message-Id: <20180723122417.054322782@linuxfoundation.org> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180723122413.003644357@linuxfoundation.org> References: <20180723122413.003644357@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Kees Cook commit 00a02d0c502a06d15e07b857f8ff921e3e402675 upstream If a seccomp user is not interested in Speculative Store Bypass mitigation by default, it can set the new SECCOMP_FILTER_FLAG_SPEC_ALLOW flag when adding filters. Signed-off-by: Kees Cook Signed-off-by: Thomas Gleixner Signed-off-by: David Woodhouse Signed-off-by: Greg Kroah-Hartman Signed-off-by: Srivatsa S. Bhat Reviewed-by: Matt Helsley (VMware) Reviewed-by: Alexey Makhalov Reviewed-by: Bo Gan Signed-off-by: Greg Kroah-Hartman --- include/linux/seccomp.h | 3 - include/uapi/linux/seccomp.h | 4 + kernel/seccomp.c | 19 +++--- tools/testing/selftests/seccomp/seccomp_bpf.c | 78 +++++++++++++++++++++++++- 4 files changed, 93 insertions(+), 11 deletions(-) --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h @@ -3,7 +3,8 @@ #include -#define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC) +#define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC | \ + SECCOMP_FILTER_FLAG_SPEC_ALLOW) #ifdef CONFIG_SECCOMP --- a/include/uapi/linux/seccomp.h +++ b/include/uapi/linux/seccomp.h @@ -15,7 +15,9 @@ #define SECCOMP_SET_MODE_FILTER 1 /* Valid flags for SECCOMP_SET_MODE_FILTER */ -#define SECCOMP_FILTER_FLAG_TSYNC 1 +#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) +/* In v4.14+ SECCOMP_FILTER_FLAG_LOG is (1UL << 1) */ +#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2) /* * All BPF programs must return a 32-bit value. --- a/kernel/seccomp.c +++ b/kernel/seccomp.c @@ -230,7 +230,8 @@ static inline void spec_mitigate(struct } static inline void seccomp_assign_mode(struct task_struct *task, - unsigned long seccomp_mode) + unsigned long seccomp_mode, + unsigned long flags) { assert_spin_locked(&task->sighand->siglock); @@ -240,8 +241,9 @@ static inline void seccomp_assign_mode(s * filter) is set. */ smp_mb__before_atomic(); - /* Assume seccomp processes want speculation flaw mitigation. */ - spec_mitigate(task, PR_SPEC_STORE_BYPASS); + /* Assume default seccomp processes want spec flaw mitigation. */ + if ((flags & SECCOMP_FILTER_FLAG_SPEC_ALLOW) == 0) + spec_mitigate(task, PR_SPEC_STORE_BYPASS); set_tsk_thread_flag(task, TIF_SECCOMP); } @@ -309,7 +311,7 @@ static inline pid_t seccomp_can_sync_thr * without dropping the locks. * */ -static inline void seccomp_sync_threads(void) +static inline void seccomp_sync_threads(unsigned long flags) { struct task_struct *thread, *caller; @@ -350,7 +352,8 @@ static inline void seccomp_sync_threads( * allow one thread to transition the other. */ if (thread->seccomp.mode == SECCOMP_MODE_DISABLED) - seccomp_assign_mode(thread, SECCOMP_MODE_FILTER); + seccomp_assign_mode(thread, SECCOMP_MODE_FILTER, + flags); } } @@ -469,7 +472,7 @@ static long seccomp_attach_filter(unsign /* Now that the new filter is in place, synchronize to all threads. */ if (flags & SECCOMP_FILTER_FLAG_TSYNC) - seccomp_sync_threads(); + seccomp_sync_threads(flags); return 0; } @@ -764,7 +767,7 @@ static long seccomp_set_mode_strict(void #ifdef TIF_NOTSC disable_TSC(); #endif - seccomp_assign_mode(current, seccomp_mode); + seccomp_assign_mode(current, seccomp_mode, 0); ret = 0; out: @@ -822,7 +825,7 @@ static long seccomp_set_mode_filter(unsi /* Do not free the successfully attached filter. */ prepared = NULL; - seccomp_assign_mode(current, seccomp_mode); + seccomp_assign_mode(current, seccomp_mode, flags); out: spin_unlock_irq(¤t->sighand->siglock); if (flags & SECCOMP_FILTER_FLAG_TSYNC) --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -1477,7 +1477,11 @@ TEST_F(TRACE_syscall, syscall_dropped) #endif #ifndef SECCOMP_FILTER_FLAG_TSYNC -#define SECCOMP_FILTER_FLAG_TSYNC 1 +#define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) +#endif + +#ifndef SECCOMP_FILTER_FLAG_SPEC_ALLOW +#define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2) #endif #ifndef seccomp @@ -1576,6 +1580,78 @@ TEST(seccomp_syscall_mode_lock) } } +/* + * Test detection of known and unknown filter flags. Userspace needs to be able + * to check if a filter flag is supported by the current kernel and a good way + * of doing that is by attempting to enter filter mode, with the flag bit in + * question set, and a NULL pointer for the _args_ parameter. EFAULT indicates + * that the flag is valid and EINVAL indicates that the flag is invalid. + */ +TEST(detect_seccomp_filter_flags) +{ + unsigned int flags[] = { SECCOMP_FILTER_FLAG_TSYNC, + SECCOMP_FILTER_FLAG_SPEC_ALLOW }; + unsigned int flag, all_flags; + int i; + long ret; + + /* Test detection of known-good filter flags */ + for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) { + int bits = 0; + + flag = flags[i]; + /* Make sure the flag is a single bit! */ + while (flag) { + if (flag & 0x1) + bits ++; + flag >>= 1; + } + ASSERT_EQ(1, bits); + flag = flags[i]; + + ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); + ASSERT_NE(ENOSYS, errno) { + TH_LOG("Kernel does not support seccomp syscall!"); + } + EXPECT_EQ(-1, ret); + EXPECT_EQ(EFAULT, errno) { + TH_LOG("Failed to detect that a known-good filter flag (0x%X) is supported!", + flag); + } + + all_flags |= flag; + } + + /* Test detection of all known-good filter flags */ + ret = seccomp(SECCOMP_SET_MODE_FILTER, all_flags, NULL); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EFAULT, errno) { + TH_LOG("Failed to detect that all known-good filter flags (0x%X) are supported!", + all_flags); + } + + /* Test detection of an unknown filter flag */ + flag = -1; + ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno) { + TH_LOG("Failed to detect that an unknown filter flag (0x%X) is unsupported!", + flag); + } + + /* + * Test detection of an unknown filter flag that may simply need to be + * added to this test + */ + flag = flags[ARRAY_SIZE(flags) - 1] << 1; + ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EINVAL, errno) { + TH_LOG("Failed to detect that an unknown filter flag (0x%X) is unsupported! Does a new flag need to be added to this test?", + flag); + } +} + TEST(TSYNC_first) { struct sock_filter filter[] = {