Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935168AbcJQU6W (ORCPT ); Mon, 17 Oct 2016 16:58:22 -0400 Received: from mail-vk0-f51.google.com ([209.85.213.51]:33928 "EHLO mail-vk0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934780AbcJQU53 (ORCPT ); Mon, 17 Oct 2016 16:57:29 -0400 MIME-Version: 1.0 In-Reply-To: <1476734984-13839-2-git-send-email-riel@redhat.com> References: <1476734984-13839-1-git-send-email-riel@redhat.com> <1476734984-13839-2-git-send-email-riel@redhat.com> From: Andy Lutomirski Date: Mon, 17 Oct 2016 13:57:06 -0700 Message-ID: Subject: Re: [PATCH RFC 1/3] fpu/x86: add make_fpregs_active(_newstate) helper functions To: Rik van Riel , Dave Hansen , Yu-cheng Yu Cc: "linux-kernel@vger.kernel.org" , Ingo Molnar , Borislav Petkov , Linus Torvalds , Andrew Lutomirski , dave.hansen@intel.linux.com, Thomas Gleixner , "H. Peter Anvin" Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1855 Lines: 45 On Mon, Oct 17, 2016 at 1:09 PM, wrote: > From: Rik van Riel > > Add helper functions that ensure a task's floating point registers are > set up the way they need to be - either with the task's floating point > state loaded in, or ready to accept a task's new floating point state. > > These helpers can be called from code that accesses the floating point > state from a preemptible state, in preparation for the lazier floating > point loading code, using loops like this: > > do { > make_fpregs_active(); > ... > } while (unlikely(!fpregs_active())); > > This way a task can safely do things like saving the floating point > state of a task to user space memory (the signal handling code does > this), without requiring that the floating point state is restored > at every context switch. Sadly, I think this model is problematic. An attacker can set up some memory that causes writes to block in a controlled manner (using userfaultfd, FUSE, madvise() hammering, etc). The attacker can arrange for the uaccess write in the "..." to block and then for some privileged target task to be scheduled. The attacker then gets their task to be scheduled next and the privileged xstate gets written to the attacker's memory. Then the attacker either reads it back from a different thread or arranges for the next iteration of the loop to fail outright. Now the attacker has read another task's xstate. Dave and/or Yu-cheng: didn't one of you have some code to allow a user xstate buffer to be filled from the copy in kernel memory? If we did that, we could avoid this mess entirely. Alternatively, there could be flag that causes FPU loads to be temporarily eager. Maybe the sequence would look like: pin_fpregs_active(); ... unpin_fpregs_active(); or maybe get_fpregs() / put_fpregs(). --Andy