Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755840AbeAIA6W (ORCPT + 1 other); Mon, 8 Jan 2018 19:58:22 -0500 Received: from mail-io0-f177.google.com ([209.85.223.177]:45332 "EHLO mail-io0-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755310AbeAIA6U (ORCPT ); Mon, 8 Jan 2018 19:58:20 -0500 X-Google-Smtp-Source: ACJfBoufMvg/87eDIoDfxryKUFyVuWWFnEGLmVarDRIqzkoF9PNmaqjaCR+V/sj8nO1I7lJoVEUwC0wnHr5ra9y/1VY= MIME-Version: 1.0 In-Reply-To: <20180109004415.GG6718@tassilo.jf.intel.com> References: <1515363085-4219-1-git-send-email-dwmw@amazon.co.uk> <1515455051.15588.7.camel@infradead.org> <1515455902.4423.59.camel@amazon.co.uk> <20180109004415.GG6718@tassilo.jf.intel.com> From: Linus Torvalds Date: Mon, 8 Jan 2018 16:58:19 -0800 X-Google-Sender-Auth: LE9mHeaeNfASrQtcxohQC_oaV4k Message-ID: Subject: Re: [PATCH v6 11/10] x86/retpoline: Avoid return buffer underflows on context switch To: Andi Kleen Cc: "Woodhouse, David" , "linux-kernel@vger.kernel.org" , "tim.c.chen@linux.intel.com" , "peterz@infradead.org" , "tglx@linutronix.de" , "riel@redhat.com" , "keescook@google.com" , "gnomes@lxorguk.ukuu.org.uk" , "pjt@google.com" , "dave.hansen@intel.com" , "luto@amacapital.net" , "jikos@kernel.org" , "gregkh@linux-foundation.org" Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: On Mon, Jan 8, 2018 at 4:44 PM, Andi Kleen wrote: > > Essentially the RSB are hidden registers, and the only way to clear them > is the FILL_RETURN_BUFFER sequence. I don't see how clearing anything else > would help? Forget theory. Look at practice. Let's just assume that the attacker can write arbitrarily to the RSB state. Just accept it. If you accept that, then you turn the question instead into: are there things we can do to make that useless to an attacker. And there the point is that even if you control the RSB contents, you need to find something relevant to *put* in the RSB. You need to find the gadget that makes that control of the RSB useful. That's where clearing the other registers comes in. Particularly for the shallow cases (maybe the attack involves calling a shallow system call that goes to the scheduler immediately, like "pause()"). Finding those gadgets is already hard. And then you have to find them in such a way that you can control some state that you can start reading out arbitrary memory. So you need to not just find the gadget, you need to pass in an interesting pointer to it. Preferably a pointer you control easily, like one of the registers that nobody used on the way from the attacking user space to the scheduler() call. That's already going to be damn hard, but with the C compiler saving many registers by default, it might not be impossible. And THAT is where "clear the registers" comes in. It adds _another_ huge barrier to an attack that was already pretty hard to begin with. If we clear the registers, what the hell are you going to put in the RSB that helps you? I really think that people need to think about the actual _practical_ side here. We're never ever going to solve all theoretical timing attacks. But when it comes to something like Spectre, it's already very much non-trivial to attack. When then looking at something like "a few call chains deep in the scheduler", it got harder still. If we clear registers and don't give the attacker a way to leak data, that's yet another big barrier. So instead of saying "we have to flush the return stack", I'm saying that we should look at things that make flushing the return stack _unnecessary_, simply because even if the attacker were to control it entirely, they'd still be up shit creek without a paddle. Linus