Received: by 10.223.176.46 with SMTP id f43csp816502wra; Fri, 19 Jan 2018 02:23:17 -0800 (PST) X-Google-Smtp-Source: ACJfBosdYO9bi+Xz26la028J8GEb01LTB1ZjELVpUJq4GifZxylcUAKT0t+0hdK6rOfeCcewzNe6 X-Received: by 10.101.78.207 with SMTP id w15mr17594687pgq.349.1516357397279; Fri, 19 Jan 2018 02:23:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1516357397; cv=none; d=google.com; s=arc-20160816; b=sz7lz+WkR49sjJUC9DmoffSu6iwMilvait8IjPNtzOE8uDEpSF0lqTfw49D0KfYBOM TD5f4/lZJqjLal71YaP5nOU+2CQSHuQtsSFFjw4Lrcts9pc8M1tnodKGa/GYqHe8e8YB 85uAzeuy3ZI93MNKy5ozzA7wukpMgYekMhQst8HACCAlDj1e7v0ugahIBL1fh1z4jHpI fXYdos44OK9QNNGEKiHiL6ZkTD0JcJm+h3Q8FeZkq+CgHEUdSksJZoea2P/JDyx6gMKU Kwu4ep62Q74s5BDkRJolcy24CePPfHeEVNaa/m1F1MP7yzZu9eE7Xo2WIJY8VkCl5BBx 6meQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=cd+cyC5XfoYlvK5mY/Ds7ONDJnJOSrGYPeORX58979w=; b=ckoUkSt+NZAHEmN/jJgmdzxvppJSsNhO0eq71dKkdhQlvgVoPAv6FG8d9pkAxgB2Yz GslkQDgOlmytBW+MrELVe6EeQE0LFFUgg4pcXW4cpM27tT3cf833/UuzX9zpi+etaK+f vV5rxhQoWLNS4af2HmeL5AmBC3a8IOj5ANV6wBxm1wiCcq0vzcnD+WLorHrVcwOiaNu1 wZWrVqfCPVtHeEcyn72O+nGihc4fqiaqFyJQOJpEdAmp9mHKMfBoMzRR/3G7WwbpYAIB nxIYofQbOeLTKFUanba4MNRQFW0TKhAtaUItD2Wa+eMLtt4TGDQr11BH4vC7PZVPH2RR 9KDw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=sN5wz7z5; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h11si2828558pgp.297.2018.01.19.02.23.02; Fri, 19 Jan 2018 02:23:17 -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; dkim=pass header.i=@google.com header.s=20161025 header.b=sN5wz7z5; 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; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755390AbeASKVQ (ORCPT + 99 others); Fri, 19 Jan 2018 05:21:16 -0500 Received: from mail-ot0-f172.google.com ([74.125.82.172]:41463 "EHLO mail-ot0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755285AbeASKVK (ORCPT ); Fri, 19 Jan 2018 05:21:10 -0500 Received: by mail-ot0-f172.google.com with SMTP id 44so992132otk.8 for ; Fri, 19 Jan 2018 02:21:09 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=cd+cyC5XfoYlvK5mY/Ds7ONDJnJOSrGYPeORX58979w=; b=sN5wz7z5j0GVTeEai20fWnmTDOdXEeyIZyZmni9r6e2PfHx2LoGg+lUhwpNCwCe5gr ntS5+1jGTO0lBFYqJcTxGZvdrhKQRdRbnUDgFR7U0/8aBCyesPl1qoJAke46cu3rifqS ViG+XZqKl7YYRk5sRgoB3ioKAa1aY1j31qgpTIxTNWPsMycoe0p2sBv9qnRwrr5HdiZb nHnqyiVqIa4UOQHyZhskL3v/MIN0E2lbtuwdKuG5n0JFa7H/9IbhXNZSNTUrrc4s92UR d3KlRzrA0YKjf9e0qsbBIccJ99INivYfe9KRnyk6yYx20pJDm5KspIh4nxz/uGVCr3l1 xUfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=cd+cyC5XfoYlvK5mY/Ds7ONDJnJOSrGYPeORX58979w=; b=jeoG6TmoMvkaZJ2zR0ipH49hQxmqt3/cxZdh5W0GakCK9UIMv28BSKYsJnswyoyZXq t5TruBz67vvRa2Zza+2H3VPHC8B4EyQ3tcq2enu7WJlIu30iJN6WlaXEjjQSKHS7E+/L r6o4/KgGEl0OU4dIJmCcNKPnJ+B5y4YfAQWVqDiwOhFsN5D0xsEV2HKDuc8S5VhOYavU cPnU2jE0e0chm7WI90+DUDeGv1GNxn1hk7enVGZlKd6cBd6T/BGBcIpdfMZZEbwQfGHd FDvaVIUQ7JvK+0xBuVqBEHZZe1zvR0pZ6JGoyUcEEGJtUPWZAOv09Wxbl7DuHLZXZnda b+4w== X-Gm-Message-State: AKwxytdwdfjLq1HgLNTPFaUSvKozje92NMvOmrkm8UTQqCd1y9D+ZrTK 8DNCYvpO8IAembBzzdOR/qWIQnArUqEJdHz7XNL/5T+b X-Received: by 10.157.51.132 with SMTP id u4mr4945845otc.323.1516357268829; Fri, 19 Jan 2018 02:21:08 -0800 (PST) MIME-Version: 1.0 Received: by 10.74.154.97 with HTTP; Fri, 19 Jan 2018 02:20:48 -0800 (PST) In-Reply-To: <151632010687.21271.12004432287640499992.stgit@dwillia2-desk3.amr.corp.intel.com> References: <151632009605.21271.11304291057104672116.stgit@dwillia2-desk3.amr.corp.intel.com> <151632010687.21271.12004432287640499992.stgit@dwillia2-desk3.amr.corp.intel.com> From: Jann Horn Date: Fri, 19 Jan 2018 11:20:48 +0100 Message-ID: Subject: Re: [kernel-hardening] [PATCH v4 02/10] asm/nospec, array_ptr: sanitize speculative array de-references To: Dan Williams Cc: kernel list , linux-arch , Kernel Hardening , Catalin Marinas , "the arch/x86 maintainers" , Will Deacon , Russell King , Ingo Molnar , Greg Kroah-Hartman , "H. Peter Anvin" , Thomas Gleixner , Linus Torvalds , Andrew Morton , alan@linux.intel.com 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 On Fri, Jan 19, 2018 at 1:01 AM, Dan Williams wrote: > '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. [...] > +/* > + * 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 Nit: Maybe add a comment saying that this is equivalent to "return ((long)idx >= 0 && idx < sz) ? ULONG_MAX : 0"? > +/** > + * 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; \ AFAICS, if `idx` is out of bounds, you first zero out the index (`_i & _mask`) and then immediately afterwards zero out the whole pointer (`_u._bit &= _mask`). Is there a reason for the `_i & _mask`, and if so, can you add a comment explaining that?