From patchwork Tue Jul 24 15:25:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kleber Sacilotto de Souza X-Patchwork-Id: 948559 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41ZhyX1nDfz9s21; Wed, 25 Jul 2018 01:25:56 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1fhzC8-0001aS-TU; Tue, 24 Jul 2018 15:25:48 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1fhzC6-0001Zj-T1 for kernel-team@lists.ubuntu.com; Tue, 24 Jul 2018 15:25:46 +0000 Received: from mail-ed1-f70.google.com ([209.85.208.70]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1fhzC6-0003u5-Kc for kernel-team@lists.ubuntu.com; Tue, 24 Jul 2018 15:25:46 +0000 Received: by mail-ed1-f70.google.com with SMTP id f13-v6so1956869edr.10 for ; Tue, 24 Jul 2018 08:25:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=auMBbjQWe0FDdK8oEKhUJGV76iVpWLveCiexC52lcu4=; b=fqMWrwM+kDkdiKLIEkOCnC6iVkMc9V4BNrtqEbdxhN+rhvQKl71LiwG9pBz5HNRO8x RwGQeUV7406Ma497BL0Blt19yUkjQEW6y+PYPH7bZG+lBK2QOjCvWmxBb4iWXovPXuAK xaJjaVMnbGKMR35TmQjJnKySAVrIhbvq+lRMquMEKPBnOZnXi0hOujSuBw6WrpIx1Deu uFbng2AkiLtVthmhlasjRVS2byAGbBCkpOvD7H6+JSBwe68LmXdq9Co/QM6LkRMwJAKJ ZjJL40l5eT0ud+Mt/JaCuHldGm7R/L7DxYrH6Me5hV3B8Q05WOLADgrvbYw+Lv6JrmGn QECA== X-Gm-Message-State: AOUpUlFJUG7W+VtaJWWdfEeWoS5IDzrfov3yOQsGDxVQwhs3LaMDOmJn ZoFx/kSxyl1Hd+tJvjm8qJdzGl0biZv1+hVf3j19L/8jqTjIRf5e/ikbu2fiGobLIZyDtl4hLH6 wulQnBPqk6sfdlqfDyfbKAPpOKgbw5RIzD7SAizsXCw== X-Received: by 2002:a50:9704:: with SMTP id c4-v6mr18667554edb.246.1532445946092; Tue, 24 Jul 2018 08:25:46 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcp09OD6mMJNzXxAGIqBYu0f2Ln33Xoanw6BsDqZDKhw3sXe7TGzsNZkQJwOg+kqtLyVtNIlw== X-Received: by 2002:a50:9704:: with SMTP id c4-v6mr18667539edb.246.1532445945928; Tue, 24 Jul 2018 08:25:45 -0700 (PDT) Received: from localhost ([2a02:8109:98c0:1604:b106:8d3e:8009:f269]) by smtp.gmail.com with ESMTPSA id f11-v6sm13752923ede.76.2018.07.24.08.25.44 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 24 Jul 2018 08:25:45 -0700 (PDT) From: Kleber Sacilotto de Souza To: kernel-team@lists.ubuntu.com Subject: [SRU][Trusty][PATCH 1/1] KVM: x86: fix emulation of "MOV SS, null selector" Date: Tue, 24 Jul 2018 17:25:42 +0200 Message-Id: <20180724152542.12420-2-kleber.souza@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180724152542.12420-1-kleber.souza@canonical.com> References: <20180724152542.12420-1-kleber.souza@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Paolo Bonzini This is CVE-2017-2583. On Intel this causes a failed vmentry because SS's type is neither 3 nor 7 (even though the manual says this check is only done for usable SS, and the dmesg splat says that SS is unusable!). On AMD it's worse: svm.c is confused and sets CPL to 0 in the vmcb. The fix fabricates a data segment descriptor when SS is set to a null selector, so that CPL and SS.DPL are set correctly in the VMCS/vmcb. Furthermore, only allow setting SS to a NULL selector if SS.RPL < 3; this in turn ensures CPL < 3 because RPL must be equal to CPL. Thanks to Andy Lutomirski and Willy Tarreau for help in analyzing the bug and deciphering the manuals. Reported-by: Xiaohan Zhang Fixes: 79d5b4c3cd809c770d4bf9812635647016c56011 Cc: stable@nongnu.org Signed-off-by: Paolo Bonzini CVE-2017-2583 (backported from commit 33ab91103b3415e12457e3104f0e4517ce12d0f3) [ klebers: adjusted context. ] Signed-off-by: Kleber Sacilotto de Souza Acked-by: Stefan Bader --- arch/x86/kvm/emulate.c | 48 +++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index d924843b0a78..0bc3a88547d0 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1454,7 +1454,6 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt, &ctxt->exception); } -/* Does not support long mode */ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, u16 selector, int seg, u8 cpl, struct desc_struct *desc) @@ -1489,20 +1488,34 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, rpl = selector & 3; - /* NULL selector is not valid for TR, CS and SS (except for long mode) */ - if ((seg == VCPU_SREG_CS - || (seg == VCPU_SREG_SS - && (ctxt->mode != X86EMUL_MODE_PROT64 || rpl != cpl)) - || seg == VCPU_SREG_TR) - && null_selector) - goto exception; - /* TR should be in GDT only */ if (seg == VCPU_SREG_TR && (selector & (1 << 2))) goto exception; - if (null_selector) /* for NULL selector skip all following checks */ + /* NULL selector is not valid for TR, CS and (except for long mode) SS */ + if (null_selector) { + if (seg == VCPU_SREG_CS || seg == VCPU_SREG_TR) + goto exception; + + if (seg == VCPU_SREG_SS) { + if (ctxt->mode != X86EMUL_MODE_PROT64 || rpl != cpl) + goto exception; + + /* + * ctxt->ops->set_segment expects the CPL to be in + * SS.DPL, so fake an expand-up 32-bit data segment. + */ + seg_desc.type = 3; + seg_desc.p = 1; + seg_desc.s = 1; + seg_desc.dpl = cpl; + seg_desc.d = 1; + seg_desc.g = 1; + } + + /* Skip all following checks */ goto load; + } ret = read_segment_descriptor(ctxt, selector, &seg_desc, &desc_addr); if (ret != X86EMUL_CONTINUE) @@ -1604,6 +1617,21 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt, u16 selector, int seg) { u8 cpl = ctxt->ops->cpl(ctxt); + + /* + * None of MOV, POP and LSS can load a NULL selector in CPL=3, but + * they can load it at CPL<3 (Intel's manual says only LSS can, + * but it's wrong). + * + * However, the Intel manual says that putting IST=1/DPL=3 in + * an interrupt gate will result in SS=3 (the AMD manual instead + * says it doesn't), so allow SS=3 in __load_segment_descriptor + * and only forbid it here. + */ + if (seg == VCPU_SREG_SS && selector == 3 && + ctxt->mode == X86EMUL_MODE_PROT64) + return emulate_exception(ctxt, GP_VECTOR, 0, true); + return __load_segment_descriptor(ctxt, selector, seg, cpl, NULL); }