Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp4750305ybb; Tue, 7 Apr 2020 13:47:18 -0700 (PDT) X-Google-Smtp-Source: APiQypJW764NHqSguEU8YTncanjY2Fkt09QYUShTeCzlTTLGfObOQWgPPh23EX5mIRiyfK1+WwcD X-Received: by 2002:a9d:32b6:: with SMTP id u51mr3212946otb.268.1586292438388; Tue, 07 Apr 2020 13:47:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586292438; cv=none; d=google.com; s=arc-20160816; b=kNMMBeBjBIW4KunTa3TfLXTNI8udK7eX8FqNusuLvJBiru+Guqz+csedyJ0ce0OXsN l68NZ0K9lA/CuOV2EiyliXZ7v/P8fN5Z3LurppvUYigbr5ZNvMbWs9LvQ4phVQm7vOSL FPUcgeP6qRpyXXFI1Figc5lV5Ts2WyjJh8k6RnJP+H+ZpKMW3R5jsvJbwk5iTfKQgjge Rhyw92CMBBIdE5OyXVcckfelpi9/wUPJKtEZY+ZBOqV9rgKlsp2/79fBJ9J2q3QwzQsC 9C6qWI0miMgVhm8Kqjnj48WTuH1EUewLRYHf8/JvIkicbcZIb0LPXoVZhrYEZZtvWYUL IJcA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-transfer-encoding:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=M/PmSf03EWCyTALuMOuTV3/WAZiw/Bj9sLqNHDMVOhg=; b=BgKs4gUS6/RswIKFooQ1NGZtaLJun7vrD3x3BcFcSaLGOiksi9GhPuznbpS/fHjH+D dsIabk/ZUhZKfq4xT20IE6WpY/jUAQkxpJfqOJaDAX2gTxSUtBWjbiSLPnoY1eZ+sDmj CrIQXNiHD76dTcOXQdlev7x1ijTgImiqmulcsxw/zoRudMOyLKgf6nSCIaOltwdsuIeU J1CJFR11WejvCBtOZQjceIZR8faNPZtkYHkiwCAXypPHySA6d4zeLydMCfibd8yUgQjl W4hoZ2Z35JCetE4jzkaDYcnqHfOtnp7SWOkqQAYGvtRkhCt9gRA4NOZdKTsubBVaffRE v9Uw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=CX0cu7dL; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z62si1521522oiz.23.2020.04.07.13.47.04; Tue, 07 Apr 2020 13:47:18 -0700 (PDT) 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=fail header.i=@infradead.org header.s=bombadil.20170209 header.b=CX0cu7dL; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726525AbgDGUqJ (ORCPT + 99 others); Tue, 7 Apr 2020 16:46:09 -0400 Received: from bombadil.infradead.org ([198.137.202.133]:60806 "EHLO bombadil.infradead.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726428AbgDGUqI (ORCPT ); Tue, 7 Apr 2020 16:46:08 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=In-Reply-To:Content-Transfer-Encoding :Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date: Sender:Reply-To:Content-ID:Content-Description; bh=M/PmSf03EWCyTALuMOuTV3/WAZiw/Bj9sLqNHDMVOhg=; b=CX0cu7dL5hzuNQ2rV2r6GtxcDF SZVZo0WFpA1QIEeCWBv+ymIgM9u/dw8BA7CwpfZHlkftcdWRMkrO1KscVbElsj55LreO7A78/DuTc f1AZz9Q2ADH+tpJroPFtoVriSsO2DqNLJMPlpG8Le4CTULX3zPem+GmLoM3xA1JDh/xaS5sbw+AZi 5VrTNVOLuG+aspV5W74+CI0oktL32wSSynF1ZUs2y3neIQRoZuHC5OfyXmOnel7f354+FRjEHc+cA GgWHJ9hUgtjTdmDCaVDGA3EX+S2RS/ZKewFyoxZ37oOl+t7znH5PkqvRgvev5mbyVVRVc7O269myJ d+6WYaVg==; Received: from j217100.upc-j.chello.nl ([24.132.217.100] helo=worktop.programming.kicks-ass.net) by bombadil.infradead.org with esmtpsa (Exim 4.92.3 #3 (Red Hat Linux)) id 1jLv6D-000123-G8; Tue, 07 Apr 2020 20:45:33 +0000 Received: by worktop.programming.kicks-ass.net (Postfix, from userid 1000) id DD6A5982F1A; Tue, 7 Apr 2020 22:45:30 +0200 (CEST) Date: Tue, 7 Apr 2020 22:45:30 +0200 From: Peter Zijlstra To: Andrew Cooper Cc: tglx@linutronix.de, linux-kernel@vger.kernel.org, hch@infradead.org, sean.j.christopherson@intel.com, mingo@redhat.com, bp@alien8.de, hpa@zytor.com, x86@kernel.org, kenny@panix.com, jeyu@kernel.org, rasmus.villemoes@prevas.dk, pbonzini@redhat.com, fenghua.yu@intel.com, xiaoyao.li@intel.com, nadav.amit@gmail.com, thellstrom@vmware.com, tony.luck@intel.com, rostedt@goodmis.org, gregkh@linuxfoundation.org, jannh@google.com, keescook@chromium.org, David.Laight@aculab.com, dcovelli@vmware.com, mhiramat@kernel.org Subject: Re: [PATCH 0/4] x86/module: Out-of-tree module decode and sanitize Message-ID: <20200407204530.GR2452@worktop.programming.kicks-ass.net> References: <20200407110236.930134290@infradead.org> <20200407194112.GQ2452@worktop.programming.kicks-ass.net> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Apr 07, 2020 at 09:11:17PM +0100, Andrew Cooper wrote: > Sorry - should have been more clear.? By friends, I meant LGDT, LIDT, > LLDT and LTR which are the 4 system table loading instructions.? LLDT > and LTR depend on being able to write into the GDT, but still have no > business being used. > > Also, LMSW if you care about it, but its utility is somewhere close to 0 > these days, so probably not worth the cycles searching for. > > The Sxxx instructions have no business being used, but are also harmless > and similarly, probably not worth spending cycles searching for. > > L{D,E,F,S}S are functional equivalents to "MOV val1, %sreg; mov val2, > %reg"? so harmless (also mode specific as to whether they are useable). OK, LxDT + LTR it is. > Other things to consider, while we're on a roll: > > WRMSR and RDMSR:? There is a lot of damage which can be done with these, > and at least forcing people to use the regular hooks will get proper > paravirt support and/or exception support.? That said, this might cause > large carnage to out-of-tree modules which are a device driver for > random platform things. Yeah, I had already considered that, didn't want to touch that just yet. > POPF: Don't really want someone being able to set IOPL3.? However, this > might quite easily show up as a false positive depending on how the > irqsafe infrastructure gets inlined. local_irq_restore() will be a POPF :/ > SYSRET/SYSEXIT/IRET: Don't want a module returning to userspace behind > the kernels back.? Good thinking, let me add this. > IRET may be a false positive for serialising > purposes, as may be a write to CR2 for that matter. We can out-of-line and export sync_core() for that. > Looking over the list of other privileged instructions, CLTS, > {,WB,WBNO}INVD, INVLPG and HLT might be candidates for "clearly doing > something which shouldn't be done".? Not on the list is INVPCID which > falls into the same category. > > Come to think about it, it might be easier to gauge on CPL0 instructions > and whitelist the ok ones, such as VMX and SVM for out-of-tree hypervisors. Fair enough, I'll go over those tomorrow. For now I ended up with: --- --- a/arch/x86/kernel/module.c +++ b/arch/x86/kernel/module.c @@ -282,6 +282,68 @@ static bool insn_is_mov_DRn(struct insn return false; } +static bool insn_is_GDT_modifier(struct insn *insn) +{ + u8 modrm = insn->modrm.bytes[0]; + u8 modrm_mod = X86_MODRM_MOD(modrm); + u8 modrm_reg = X86_MODRM_REG(modrm); + + if (insn->opcode.bytes[0] != 0x0f) + return false; + + switch (insn->opcode.bytes[1]) { + case 0x00: /* Grp6 */ + switch (modrm_reg) { + /* case 0x0: SLDT */ + case 0x2: /* LLDT */ + case 0x3: /* LTR */ + return true; + + default: + break; + } + break; + + case 0x01: /* Grp7 */ + if (modrm_mod == 0x03) + break; + + switch (modrm_reg) { + /* case 0x0: SGDT */ + /* case 0x1: SIDT */ + case 0x2: /* LGDT */ + case 0x3: /* LIDT */ + return true; + + default: + break; + } + break; + + default: + break; + } + + return false; +} + +static bool insn_is_xRET(struct insn *insn) +{ + u8 op1 = insn->opcode.bytes[0]; + u8 op2 = insn->opcode.bytes[1]; + + if (op1 == 0xcf) /* IRET */ + return true; + + if (op1 != 0x0f) + return false; + + if (op2 == 0x07 || op2 == 0x35) /* SYSRET, SYSEXIT */ + return true; + + return false; +} + static int decode_module(struct module *mod, void *text, void *text_end, bool sld_safe) { bool allow_vmx = sld_safe || !split_lock_enabled();