From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Cyrus-Session-Id: sloti22d1t05-1931288-1516467411-2-3605822901976489164 X-Sieve: CMU Sieve 3.0 X-Spam-known-sender: no X-Spam-score: 0.0 X-Spam-hits: BAYES_00 -1.9, FREEMAIL_FORGED_FROMDOMAIN 0.25, FREEMAIL_FROM 0.001, HEADER_FROM_DIFFERENT_DOMAINS 0.25, RCVD_IN_DNSWL_HI -5, T_RP_MATCHES_RCVD -0.01, LANGUAGES en, BAYES_USED global, SA_VERSION 3.4.0 X-Spam-source: IP='209.132.180.67', Host='vger.kernel.org', Country='US', FromHeader='com', MailFrom='org' X-Spam-charsets: plain='us-ascii' X-Resolved-to: greg@kroah.com X-Delivered-to: greg@kroah.com X-Mail-from: stable-owner@vger.kernel.org ARC-Seal: i=1; a=rsa-sha256; cv=none; d=messagingengine.com; s=arctest; t=1516467410; b=uiyPYRWzxCvtZI16rSlvxhjIFxxunlty01h9JvgRUO3Ot0h WD88q9YM+f8tay1VuK7RbrA/8FfXXZLx+GTMkklOOtRHplLibvLbXeDLt3HzXD8x eJA0GRgyjEI9LSNhZ7cDyWLkq6iWFXphuROCyy7v11v6HM8ymdXzVhAfQpmO05ri LXfkqZP++c9iC5bIcDKpI1ABk3jf7jSA92rd2LmrBYFhiRsPJ/OYs+8Ubz/pDXoo vKDpvjX4cv5sd4SvQTqQWOJZLsO/9QRX+6VdaerQeoEWIEFyXrtzYOun7DexbpKx vktaKxxcKYXzumOXYbrFy4PmIq5VZCWv7c3/QDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=date:from:to:cc:subject:message-id :references:mime-version:content-type:in-reply-to:sender :list-id; s=arctest; t=1516467410; bh=2CCKU7wwp9/cI/7Ro1NAqjadxu T6Lo66n1qgDs1tcqk=; b=ceR/Mx/VpypDkHPOBi1IjU/QVeKWaTFCtXOHKLHHyT RPxSqGPWqWqg8s8zHA1v0cFoJNaDX6ZMA/47XXHKmNzt6S35wA0eyfpqfbnbUDNL eVsgUL6HEjLW3p+KF1mfzZsnfWNuCmW0TSmU1u71fJTusjucxjEDpArHncgNtgnB SKqyQBtdydYnsE1z/h1Fno5Sm0590W/7VYRN+MCNgQONPU8y4DPWvVlx8lX8/NgM Q8D+13pGhxmIxSiSPxru/gH5QQkw9FUhHATcy3e70ynyAy0LiQcJ5AzZHMG5YceJ Hzs2ldopZeNcPMmVexTEGqRBWwGuJx4BWGPTpowK0gng== ARC-Authentication-Results: i=1; mx4.messagingengine.com; arc=none (no signatures found); dkim=pass (2048-bit rsa key sha256) header.d=gmail.com header.i=@gmail.com header.b=DPsZ59hB x-bits=2048 x-keytype=rsa x-algorithm=sha256 x-selector=20161025; dmarc=pass (p=none,has-list-id=yes,d=none) header.from=gmail.com; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=stable-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-google-dkim=pass (2048-bit rsa key) header.d=1e100.net header.i=@1e100.net header.b=dFQSxpOi; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=gmail.com header.result=pass header_is_org_domain=yes Authentication-Results: mx4.messagingengine.com; arc=none (no signatures found); dkim=pass (2048-bit rsa key sha256) header.d=gmail.com header.i=@gmail.com header.b=DPsZ59hB x-bits=2048 x-keytype=rsa x-algorithm=sha256 x-selector=20161025; dmarc=pass (p=none,has-list-id=yes,d=none) header.from=gmail.com; iprev=pass policy.iprev=209.132.180.67 (vger.kernel.org); spf=none smtp.mailfrom=stable-owner@vger.kernel.org smtp.helo=vger.kernel.org; x-aligned-from=fail; x-google-dkim=pass (2048-bit rsa key) header.d=1e100.net header.i=@1e100.net header.b=dFQSxpOi; x-ptr=pass x-ptr-helo=vger.kernel.org x-ptr-lookup=vger.kernel.org; x-return-mx=pass smtp.domain=vger.kernel.org smtp.result=pass smtp_org.domain=kernel.org smtp_org.result=pass smtp_is_org_domain=no header.domain=gmail.com header.result=pass header_is_org_domain=yes Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755643AbeATQ4l (ORCPT ); Sat, 20 Jan 2018 11:56:41 -0500 Received: from mail-pg0-f65.google.com ([74.125.83.65]:45915 "EHLO mail-pg0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754913AbeATQ4j (ORCPT ); Sat, 20 Jan 2018 11:56:39 -0500 X-Google-Smtp-Source: AH8x224VZjCiY3JLAg/tVgpPJ3BSLLjA1C7Nw8LSpo5zjmY8CGEZIhkWfRgR+TbCEDStDpI0yMQECA== Date: Sat, 20 Jan 2018 08:56:34 -0800 From: Alexei Starovoitov To: Dan Williams Cc: Linux Kernel Mailing List , Mark Rutland , Kernel Hardening , Peter Zijlstra , Catalin Marinas , Will Deacon , "H. Peter Anvin" , Elena Reshetova , linux-arch , Andi Kleen , Jonathan Corbet , X86 ML , Russell King , Ingo Molnar , Andrew Honig , Alan Cox , Tom Lendacky , Kees Cook , Al Viro , Andy Lutomirski , Thomas Gleixner , Andrew Morton , Jim Mattson , Christian Lamparter , Greg KH , Linux Wireless List , stable@vger.kernel.org, Paolo Bonzini , Johannes Berg , Linus Torvalds , "David S. Miller" Subject: Re: [PATCH v4 00/10] prevent bounds-check bypass via speculative execution Message-ID: <20180120165631.e7c3kipmhb5sckor@ast-mbp> References: <151632009605.21271.11304291057104672116.stgit@dwillia2-desk3.amr.corp.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: NeoMutt/20170421 (1.8.2) Sender: stable-owner@vger.kernel.org X-Mailing-List: stable@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-Mailing-List: linux-kernel@vger.kernel.org List-ID: On Fri, Jan 19, 2018 at 10:58:44PM -0800, Dan Williams wrote: > On Thu, Jan 18, 2018 at 4:01 PM, Dan Williams wrote: > > Changes since v3 [1] > > * Drop 'ifence_array_ptr' and associated compile-time + run-time > > switching and just use the masking approach all the time. > > > > * Convert 'get_user' to use pointer sanitization via masking rather than > > lfence. '__get_user' and associated paths still rely on > > lfence. (Linus) > > > > "Basically, the rule is trivial: find all 'stac' users, and use > > address masking if those users already integrate the limit > > check, and lfence they don't." > > > > * At syscall entry sanitize the syscall number under speculation > > to remove a user controlled pointer de-reference in kernel > > space. (Linus) > > > > * Fix a raw lfence in the kvm code (added for v4.15-rc8) to use > > 'array_ptr'. > > > > * Propose 'array_idx' as a way to sanitize user input that is > > later used as an array index, but where the validation is > > happening in a different code block than the array reference. > > (Christian). > > > > * Fix grammar in speculation.txt (Kees) > > > > --- > > > > Quoting Mark's original RFC: > > > > "Recently, Google Project Zero discovered several classes of attack > > against speculative execution. One of these, known as variant-1, allows > > explicit bounds checks to be bypassed under speculation, providing an > > arbitrary read gadget. Further details can be found on the GPZ blog [2] > > and the Documentation patch in this series." > > > > A precondition of using this attack on the kernel is to get a user > > controlled pointer de-referenced (under speculation) in privileged code. > > The primary source of user controlled pointers in the kernel is the > > arguments passed to 'get_user' and '__get_user'. An example of other > > user controlled pointers are user-controlled array / pointer offsets. > > > > Better tooling is needed to find more arrays / pointers with user > > controlled indices / offsets that can be converted to use 'array_ptr' or > > 'array_idx'. A few are included in this set, and these are not expected > > to be complete. That said, the 'get_user' protections raise the bar on > > finding a vulnerable gadget in the kernel. > > > > These patches are also available via the 'nospec-v4' git branch here: > > > > git://git.kernel.org/pub/scm/linux/kernel/git/djbw/linux nospec-v4 > > I've pushed out a nospec-v4.1 with the below minor cleanup, a fixup of > the changelog for "kvm, x86: fix spectre-v1 mitigation", and added > Paolo's ack. > > git://git.kernel.org/pub/scm/linux/kernel/git/djbw/linux nospec-v4.1 > > diff --git a/include/linux/nospec.h b/include/linux/nospec.h > index 8af35be1869e..b8a9222e34d1 100644 > --- a/include/linux/nospec.h > +++ b/include/linux/nospec.h > @@ -37,7 +37,7 @@ static inline unsigned long array_ptr_mask(unsigned > long idx, unsigned long sz) > unsigned long _i = (idx); \ > unsigned long _mask = array_ptr_mask(_i, (sz)); \ > \ > - __u._ptr = _arr + (_i & _mask); \ > + __u._ptr = _arr + _i; \ > __u._bit &= _mask; \ > __u._ptr; \ hmm. I'm not sure it's the right thing to do, since the macro is forcing cpu to speculate subsequent load from null instead of valid pointer. As Linus said: " So that __u._bit masking wasn't masking the pointer, it was masking the value that was *read* from the pointer, so that you could know that an invalid access returned 0/NULL, not just the first value in the array. " imo just return _arr + (_i & _mask); is enough. No need for union games. The cpu will speculate the load from _arr[0] if _i is out of bounds which is the same as if user passed _i == 0 which would have passed bounds check anyway, so I don't see any data leak from populating cache with _arr[0] data. In-bounds access can do that just as well without any speculation.