Received: by 10.223.176.46 with SMTP id f43csp203713wra; Thu, 18 Jan 2018 16:12:15 -0800 (PST) X-Google-Smtp-Source: ACJfBosb9iE0YwRcfiRpgpE4WJcvt5iO3EQTN6wyWozoDOeRIbrdbA9TcyCZOmPJIvEryxIoHL1A X-Received: by 10.101.80.6 with SMTP id f6mr5721725pgo.272.1516320735661; Thu, 18 Jan 2018 16:12:15 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516320735; cv=none; d=google.com; s=arc-20160816; b=SRBHhT060eOQog2op4gVfPa1SFhkkSNymr0O4hd8/x9i6wNS1M7vOsoeVCzTPWnyCb gq1DUq40HZQ5dazWIgeH2hjKx5ltLThrDb6R9wuPUjAYQpKEzzEKTiZcNlQhvA3WaypX DkwYYGsDl4y+jaZqef2C/7yIBWklspg9Q+TxLvlwllSIA8HryD5jHvx2lip7j+FBpBIL eNXRhqlE8JOq7+3sO8Fih+RJy9CIgQHm8iSOTTiXnu0xqCoIyJIvjDLUGMXnfgCVl+mj HWgXsIjN9r9CqqypKT1tQVDCG6BWyZX20Mw2C/Flkjc3qYSg1pyJcJpFgOx5nq/pvYwp btlw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:cc:to:from :subject:arc-authentication-results; bh=O3zSWLaAG77AEsGBo6Vk+9RsLG+dx9ixCiTuGSrORRQ=; b=M5W5Oisz+Eo5u/qyh4f/bar9KCfGRO5vBkyJkpD6ADRLz3Pt+C5eOZDI0x9+vB/NIV /XmgUn6ceSQ6gaCXpts2Rg4CXK77PdZuIYNVizO9lfhT77LP/FEgFxYtUXZXIuMNUm/9 3dH2J/PNYlYakoGit6KzudU625zgSHk7b7Z0H0xbovjZiP97Tk8VPjoD1X5Gd/0zfuiG hUxZO1Zlx3vTO/fTJA0tN9Ts6bRa5mjKOib1qfsS08eLmBDQkR/DkoKfgx7JAnnSzMMu +ep3vLI/0FkD0stfThi92c/1dzgMokS5+GDgZ0nv3Lcoh3x+YZlazlUb/Crob9G3gQqc yprQ== 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 c80si7911910pfb.182.2018.01.18.16.12.01; Thu, 18 Jan 2018 16:12:15 -0800 (PST) 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 S1755245AbeASALU (ORCPT + 99 others); Thu, 18 Jan 2018 19:11:20 -0500 Received: from mga03.intel.com ([134.134.136.65]:63244 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755040AbeASAKy (ORCPT ); Thu, 18 Jan 2018 19:10:54 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Jan 2018 16:10:53 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,379,1511856000"; d="scan'208";a="196908601" Received: from dwillia2-desk3.jf.intel.com (HELO dwillia2-desk3.amr.corp.intel.com) ([10.54.39.16]) by fmsmga006.fm.intel.com with ESMTP; 18 Jan 2018 16:10:52 -0800 Subject: [PATCH v4 02/10] asm/nospec, array_ptr: sanitize speculative array de-references From: Dan Williams To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, kernel-hardening@lists.openwall.com, Catalin Marinas , x86@kernel.org, Will Deacon , Russell King , Ingo Molnar , gregkh@linuxfoundation.org, "H. Peter Anvin" , tglx@linutronix.de, torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@linux.intel.com Date: Thu, 18 Jan 2018 16:01:46 -0800 Message-ID: <151632010687.21271.12004432287640499992.stgit@dwillia2-desk3.amr.corp.intel.com> In-Reply-To: <151632009605.21271.11304291057104672116.stgit@dwillia2-desk3.amr.corp.intel.com> References: <151632009605.21271.11304291057104672116.stgit@dwillia2-desk3.amr.corp.intel.com> User-Agent: StGit/0.17.1-9-g687f MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 'array_ptr' is proposed as a generic mechanism to mitigate against Spectre-variant-1 attacks, i.e. an attack that bypasses boundary checks via speculative execution). The 'array_ptr' implementation is expected to be safe for current generation cpus across multiple architectures (ARM, x86). Based on an original implementation by Linus Torvalds, tweaked to remove speculative flows by Alexei Starovoitov, and tweaked again by Linus to introduce an x86 assembly implementation for the mask generation. Co-developed-by: Linus Torvalds Co-developed-by: Alexei Starovoitov Co-developed-by: Peter Zijlstra Cc: Russell King Cc: Catalin Marinas Cc: Will Deacon Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: x86@kernel.org Signed-off-by: Dan Williams --- include/linux/nospec.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 include/linux/nospec.h diff --git a/include/linux/nospec.h b/include/linux/nospec.h new file mode 100644 index 000000000000..f841c11f3f1f --- /dev/null +++ b/include/linux/nospec.h @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright(c) 2018 Intel Corporation. All rights reserved. + +#ifndef __NOSPEC_H__ +#define __NOSPEC_H__ + +#include +#include + +/* + * If idx is negative or if idx > size then bit 63 is set in the mask, + * and the value of ~(-1L) is zero. When the mask is zero, bounds check + * failed, array_ptr will return NULL. + */ +#ifndef array_ptr_mask +static inline unsigned long array_ptr_mask(unsigned long idx, unsigned long sz) +{ + return ~(long)(idx | (sz - 1 - idx)) >> (BITS_PER_LONG - 1); +} +#endif + +/** + * array_ptr - Generate a pointer to an array element, ensuring + * the pointer is bounded under speculation to NULL. + * + * @base: the base of the array + * @idx: the index of the element, must be less than LONG_MAX + * @sz: the number of elements in the array, must be less than LONG_MAX + * + * If @idx falls in the interval [0, @sz), returns the pointer to + * @arr[@idx], otherwise returns NULL. + */ +#define array_ptr(base, idx, sz) \ +({ \ + union { typeof(*(base)) *_ptr; unsigned long _bit; } __u; \ + typeof(*(base)) *_arr = (base); \ + unsigned long _i = (idx); \ + unsigned long _mask = array_ptr_mask(_i, (sz)); \ + \ + __u._ptr = _arr + (_i & _mask); \ + __u._bit &= _mask; \ + __u._ptr; \ +}) +#endif /* __NOSPEC_H__ */