From patchwork Mon Dec 21 14:44:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 346422 Delivered-To: patch@linaro.org Received: by 2002:a02:85a7:0:0:0:0:0 with SMTP id d36csp4529615jai; Mon, 21 Dec 2020 07:05:50 -0800 (PST) X-Google-Smtp-Source: ABdhPJwaFQECDakhiwVFajUae4j1P4dGt+BK3buytzsGCNGJFkL9N4oQSM/oXprJ/qCfDN078gQH X-Received: by 2002:a25:e03:: with SMTP id 3mr22730037ybo.414.1608563150660; Mon, 21 Dec 2020 07:05:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1608563150; cv=none; d=google.com; s=arc-20160816; b=zWmSbYdz7qVlnE9lgBwWWuU7jUmOeMSEtyTtIDXHR1i6n033sG96tTeHdd+CFTKBuh MGxkoDBo1AkFtR2XKPT7lGsV7zSVVxQqb6owPKHLUwuACZDdmXzncGL7kRZmwb5foM6G 5Qdfc/EfinJFA8vmQp2S8m8K+c743GtWGRGUVQ0+wyJY/qyJKz6KMDVJGJTtMlt9s1Oo g4i1+TRRrsc8IhYnQDAzNUlqxiULAT4MXaqz6Tk/5PwhvbZdrc1eogu5VS5jZ43sCS8x 1+0epMx9GnKdsRvAfaKUWJAECGNsb7KiCYiOSNmePSnWl3Uhwe+eVhXO82ALI2xype7J g5xQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=jM3hkD4CvKdZOABArp0NAjoE5fJXpKMpDEFZ8ZRfbww=; b=Z2y+pW0N53yCUqe/a8/XNK/Sg5lbdz9EJ9+YM6RO44VXb+axBgh/VF2PIjdJjBfBxq wE10trfhalZjJ2Fn/gaUe2O2hZWu1KCGGBNhPMn6iVJJzamwIEQKoT9t80Kn80RcRlPU S1BE/DbVJ64AIzXPvkMoV2fVdK3Dap2/rRMc8MQV/PFjMZoE8jADNuTk0Eivv3ThXfUT NkRy3wEQSuAPMrGg97FjycUeuHqyD4gl7y0pKHGh5/J4kIhzIijHR7NBIk/I3VgwcHlv Zh0U4hv83ajdhPRurX1tMGl1fnOXzjvUUemrxQBEvoEZPh9M1f1GVaDNiwMonGc8yqRa lHwQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=p8aFyLKR; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id r4si16687161ybb.438.2020.12.21.07.05.50 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Mon, 21 Dec 2020 07:05:50 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=p8aFyLKR; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from localhost ([::1]:38728 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1krMkw-00049B-2O for patch@linaro.org; Mon, 21 Dec 2020 10:05:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:42258) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1krMR0-0004on-NH for qemu-devel@nongnu.org; Mon, 21 Dec 2020 09:45:19 -0500 Received: from mail-wm1-x330.google.com ([2a00:1450:4864:20::330]:50713) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1krMQr-0007iq-8v for qemu-devel@nongnu.org; Mon, 21 Dec 2020 09:45:07 -0500 Received: by mail-wm1-x330.google.com with SMTP id 190so10102965wmz.0 for ; Mon, 21 Dec 2020 06:45:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=jM3hkD4CvKdZOABArp0NAjoE5fJXpKMpDEFZ8ZRfbww=; b=p8aFyLKR3J6XHwoqW+v81SVJJcziWaM+dHmi+w5JY3EZZR3d3Z08OoeNa9fopwj6wd eq/sQwFKmpZfAR5/hf2pig2EN8e2tWfu5Wqador1h5Kic/RpBkNXqAjQlzMWG/78yQPi HNQx2mgwNz0L/J5SvtZlELv4ySzvtowpo9jqJL4g6C70hvE2KaiB93LurWLHar1yBZil jJLYTQYq9+97Gv7gROQJ9LLEOOPXx5vYASBzPWGfBQ9eGJtlZXFzB7kYJ1RODQpaWajA 6Y5wgn8aVopOIKVTTIvk2Ehb/tDyiIrvetxbxvIA9dSa3Exjr2dJ3Q4SUA441KDR9laH Xq/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=jM3hkD4CvKdZOABArp0NAjoE5fJXpKMpDEFZ8ZRfbww=; b=Ftw6lsqoqsNctCA/B/DUJ8V+EbytZhmYlm0ZiRmzPyc/6aO+G15ORAEnkg/IIpg5T4 9NmFGGynhsBxdJ0Zf0mOjKsWOhg0AX/uf3kRzd/yuPAjvwmI/Wm7yY+USNxjsn74MsO+ zoyZFhbCKBjyWZLMUrS8UiSNAcrxZL5HhrLztmOPyyDzmmO3NJgLU3MQIa/ZzVsONKL8 l4uymQjye+ponB99q8P7gI62zAytNHkhKkfoK8INH8C5l282G+ockVqpLbWRVKDc6225 u4p/9Yu7YiNY8Vsbjx7tlylRkS6gydaoKH6qHkxfXUo5kepGrBZMZ6AjBHP9xL0WCTqz ji/A== X-Gm-Message-State: AOAM532gpLd4NiBz4Qg2LnHz/DUqfYFglDU//grs2cSDhb2ocs3VVeXX stQRnQ1eFhZV9Y5fTNUsgPYF6lTvtpA= X-Received: by 2002:a1c:1c1:: with SMTP id 184mr16961171wmb.112.1608561902836; Mon, 21 Dec 2020 06:45:02 -0800 (PST) Received: from avogadro.lan ([2001:b07:6468:f312:c8dd:75d4:99ab:290a]) by smtp.gmail.com with ESMTPSA id l5sm27439627wrv.44.2020.12.21.06.45.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Dec 2020 06:45:02 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 15/55] target/i386: Check privilege level for protected mode 'int N' task gate Date: Mon, 21 Dec 2020 15:44:07 +0100 Message-Id: <20201221144447.26161-16-pbonzini@redhat.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201221144447.26161-1-pbonzini@redhat.com> References: <20201221144447.26161-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::330; envelope-from=paolo.bonzini@gmail.com; helo=mail-wm1-x330.google.com X-Spam_score_int: -14 X-Spam_score: -1.5 X-Spam_bar: - X-Spam_report: (-1.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FORGED_FROMDOMAIN=0.25, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Richard Henderson Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Peter Maydell When the 'int N' instruction is executed in protected mode, the pseudocode in the architecture manual specifies that we need to check: * vector number within IDT limits * selected IDT descriptor is a valid type (interrupt, trap or task gate) * if this was a software interrupt then gate DPL < CPL The way we had structured the code meant that the privilege check for software interrupts ended up not in the code path taken for task gate handling, because all of the task gate handling code was in the 'case 5' of the switch which was checking "is this descriptor a valid type". Move the task gate handling code out of that switch (so that it is now purely doing the "valid type?" check) and below the software interrupt privilege check. The effect of this missing check was that in a guest userspace binary executing 'int 8' would cause a guest kernel panic rather than the userspace binary being handed a SEGV. This is essentially the same bug fixed in VirtualBox in 2012: https://www.halfdog.net/Security/2012/VirtualBoxSoftwareInterrupt0x8GuestCrash/ Note that for QEMU this is not a security issue because it is only present when using TCG. Fixes: https://bugs.launchpad.net/qemu/+bug/1813201 Signed-off-by: Peter Maydell Message-Id: <20201121224445.16236-1-peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/tcg/seg_helper.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) -- 2.29.2 diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 1255efe7e0..5f2ee6aa7e 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -634,6 +634,24 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; switch (type) { case 5: /* task gate */ + case 6: /* 286 interrupt gate */ + case 7: /* 286 trap gate */ + case 14: /* 386 interrupt gate */ + case 15: /* 386 trap gate */ + break; + default: + raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); + break; + } + dpl = (e2 >> DESC_DPL_SHIFT) & 3; + cpl = env->hflags & HF_CPL_MASK; + /* check privilege if software int */ + if (is_int && dpl < cpl) { + raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); + } + + if (type == 5) { + /* task gate */ /* must do that check here to return the correct error code */ if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2); @@ -661,21 +679,10 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, SET_ESP(esp, mask); } return; - case 6: /* 286 interrupt gate */ - case 7: /* 286 trap gate */ - case 14: /* 386 interrupt gate */ - case 15: /* 386 trap gate */ - break; - default: - raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); - break; - } - dpl = (e2 >> DESC_DPL_SHIFT) & 3; - cpl = env->hflags & HF_CPL_MASK; - /* check privilege if software int */ - if (is_int && dpl < cpl) { - raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); } + + /* Otherwise, trap or interrupt gate */ + /* check valid bit */ if (!(e2 & DESC_P_MASK)) { raise_exception_err(env, EXCP0B_NOSEG, intno * 8 + 2);