From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linutronix.de (146.0.238.70:993) by crypto-ml.lab.linutronix.de with IMAP4-SSL for ; 25 Feb 2019 16:58:20 -0000 Received: from mga12.intel.com ([192.55.52.136]) by Galois.linutronix.de with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1gyJa7-00037C-Hl for speck@linutronix.de; Mon, 25 Feb 2019 17:58:19 +0100 Date: Mon, 25 Feb 2019 08:58:16 -0800 From: Andi Kleen Subject: [MODERATED] Re: [PATCH v6 10/43] MDSv6 Message-ID: <20190225165816.GT16922@tassilo.jf.intel.com> References: <20190225163013.GB22318@kroah.com> MIME-Version: 1.0 In-Reply-To: <20190225163013.GB22318@kroah.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit To: speck@linutronix.de List-ID: Ok I feel like a lawyer now, but ... Let's see if we can draft a contract. On Mon, Feb 25, 2019 at 05:30:13PM +0100, speck for Greg KH wrote: > On Sun, Feb 24, 2019 at 07:07:16AM -0800, speck for Andi Kleen wrote: > > +Guidance for driver/subsystem developers > > +---------------------------------------- > > + > > +[These generally need to be enforced in code review for new code now] > > + > > +When you touch user supplied data of *other* processes in system call > > +context add lazy_clear_cpu(). > > What do you mean by "user supplied data of *other* processes"? I think > I understand the kernel, and I have no idea what this means. *other* here means a process which is not current. Anything that would be copied from/to the other process. It's actually fairly rare. Or rather in all situations I know about the process has access to the other process' data anyways (e.g. ptrace or process_vm_read/write) It happens in special situations like the context switch today. Here's a hypothetical situation where it could happen: You have a driver which processes a shared input queue which contains data for multiple processes. The processing happens with the CPU so touches data, and does not only read metadata, but actually has to read the full data. It runs some code in process context to go through the queue and pick out data items that belong to a process. It skips data for other processes, but still has to read it. That would be touching other processes' data. Does it actually happen anywhere in the code? I'm not sure. But I wanted to document it anyways. > > > +For the cases below we care only about data from other processes. > > +Touching non cryptographic data from the current process is always allowed. > > Define "non cryptographic data". Is data coming across a serial port > crypto data? From a camera? That's IO data which is sensitive. > > > + > > +Touching only pointers to user data is always allowed. > > But not touching the data the pointer points to? Right. > I still don't know what "user data" means. Is a serial stream coming > from a bluetooth device "user data"? Is a program that talks directly > to a USB data without a special kernel driver reading "user data"? Is a > serial port data stream "user data"? These are all IO (but not meta) data. > > +For networking code, make sure to only touch user data through > > +skb_push/put/copy [add more], unless it is data from the current > > +process. If that is not ensured add lazy_clear_cpu or > > +lazy_clear_cpu_interrupt. > > How do you know if data coming across the network is for the "current" > process? What does "current process" even mean here? Current process is "current". You know it if you're in process context and you only process data for your process. For example recvmsg() doesn't need to worry because it only processes a queue of data that is for the current process context. > How about UIO drivers, how does their data get classified? Lots of > networking stacks use UIO now... virtual io channels? It's all sensitive I guess. These will clear after the process context switch anyways. > > We do that today, right? If not, that needs to be done regardless. Yes. > > And what about password data? I _think_ we got most of that now out of > the tty layer, but we could be wrong :) I don't think the kernel processes passwords directly. If it's in the tty later it's IO data. If it's in the user program it's user data. When it's uploaded to the kernel as a processed key it's cryptographic data. > > > + > > +If your RCU callback touches user data add lazy_clear_cpu(). > > Ugh, really? Yes. But none need it currently, so it's very unlikely. BTW you seem to think that lazy_clear_cpu is very expensive. It is not. And it is done after all process context switches anyways. > > +Protecting process data > > +----------------------- > > + > > +If a system call touches data of its own process, CPU state does not > > +need to be cleared, because it has already access to it. > > How do you know if it is it's own process or not? See above. > > What about something like IPC data? You already have access to that, so no need to clear. > > + > > +If there is a sandbox inside the process the process should take care > > +itself of clearing its own sensitive data before running sandbox > > +code. This would include data touched by system calls. > > i.e. "Userspace code is hosed, sorry."? User space has lots of own ways to mitigate. Most code which doesn't use run untrusted code sandboxes doesn't need to worry. > > > +BPF > > +--- > > + > > +Assume BPF execution does not touch other user's data, so does > > +not need to schedule a clear for itself. > > Can you assume that? > > > +BPF could attack the rest of the kernel if it can successfully > > +measure side channel side effects. > > Can it do such a measurement? For Spectre it could, so likely it can for MDS too. -Andi