From patchwork Tue Mar 7 19:24:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Borislav Petkov X-Patchwork-Id: 65836 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:5915:0:0:0:0:0 with SMTP id v21csp2642522wrd; Tue, 7 Mar 2023 12:22:29 -0800 (PST) X-Google-Smtp-Source: AK7set9T6uZnNj+G0hdbzr+a0nqI4LRLKf5jbcsXXuTjnEkrjG3z8Kge8aXsM+IAcEXljcoWlxUz X-Received: by 2002:a17:906:fcb9:b0:8b2:7564:dfd7 with SMTP id qw25-20020a170906fcb900b008b27564dfd7mr14925180ejb.61.1678220549265; Tue, 07 Mar 2023 12:22:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1678220549; cv=none; d=google.com; s=arc-20160816; b=OgodsSXrgthwjgvCMp0XkrTVRefgX/r0dD2Rn/gVdNRMbcOZujWgod4vpAHhMTZ9cA c2xxeG3i21SgIVOU2gwg5/Gu2rvnRPqiBKuPGLmRQ3UBluzyQN7+Dbz/k5KdtcloTdi0 cdz6S2KvifxZlTn+3hyBxNegN7d7oy6iZkGdXXGqOhZbRVMYwk4B5Y7URVSur3OuIsLl q7WRnYFh05RqV3pQQ1iL+7Vp8AO2OfoiHXuxXYqSS4zFO/fpctPsK4k1KxAVTa3hPyKR 8CvyeZArNc9Tkz7d8wf4GWbq/QiaEeNeMFNh5oFann7UESx7UFsH0fB+plNC1j6wpkis b7rg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=gSs80yh0DjTeBBgJyw8SUIiy0yTuPDLDQy0HhlQzc2I=; b=a6/Y+/UuvsizKWOSjLkzNkcS4iw6HXLXYD74S/UqGjWUe4obt0N95duZY7yyb7o++A izfOMzdGRbHpZ8WOFey1DXIJ1YRaKdZUe/ZTbOGMwCi8D2IEqE39jBBAfXWcRJlQ7A42 kfz9Q3czC9NUjb/2mRIrvkEz2y0PuzkDUdaQiGwjNyFo0NInPql2v5KdSD9ipVv1EFzR gojx1h/jiz5vyQXDsKAj0TKeS0DD4Y822xdDa2WtqyRP9gVQu7gs9sifnHXj7TQtndwT goD4eGbEdw2AOXvZVlkZ5PNKd1gGAo0bqiGdD9GfspSeqWqyg89tomsCBmBmMzxfe74v aWRg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@alien8.de header.s=dkim header.b="CJGDOi/A"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=alien8.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id c17-20020a170906d19100b008d3be841ccdsi502557ejz.326.2023.03.07.12.22.05; Tue, 07 Mar 2023 12:22:29 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@alien8.de header.s=dkim header.b="CJGDOi/A"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=alien8.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229684AbjCGTim (ORCPT + 99 others); Tue, 7 Mar 2023 14:38:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50326 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234183AbjCGThn (ORCPT ); Tue, 7 Mar 2023 14:37:43 -0500 Received: from mail.skyhub.de (mail.skyhub.de [IPv6:2a01:4f8:190:11c2::b:1457]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7C7B9E312 for ; Tue, 7 Mar 2023 11:25:02 -0800 (PST) Received: from zn.tnic (p5de8e9fe.dip0.t-ipconnect.de [93.232.233.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.skyhub.de (SuperMail on ZX Spectrum 128k) with ESMTPSA id 1B77D1EC06C1; Tue, 7 Mar 2023 20:25:01 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alien8.de; s=dkim; t=1678217101; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gSs80yh0DjTeBBgJyw8SUIiy0yTuPDLDQy0HhlQzc2I=; b=CJGDOi/Al5NbWq2cbyNRicnIDTfoE7ymfBPCyg5fRK646hkBAX9tir7f2An4VjwbEQbr3y QJwFPTZew9d9tSky7lObNgas1HXchJbCtUfRNSfWsjx3Lvb6DCUtgxocHIEKLC6RgMFzB4 OpCxX11agZ3mBzIewjFHASVFuR+l8Ys= From: Borislav Petkov To: LKML Cc: Dionna Glaze , Joerg Roedel , Michael Roth , Nikunj A Dadhania , Peter Gonda , Tom Lendacky , linux-coco@lists.linux.dev, x86@kernel.org Subject: [PATCH -v3 10/11] virt/coco/sev-guest: Double-buffer messages Date: Tue, 7 Mar 2023 20:24:48 +0100 Message-Id: <20230307192449.24732-11-bp@alien8.de> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20230307192449.24732-1-bp@alien8.de> References: <20230307192449.24732-1-bp@alien8.de> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1759741790984579799?= X-GMAIL-MSGID: =?utf-8?q?1759741790984579799?= From: Dionna Glaze The encryption algorithms read and write directly to shared unencrypted memory, which may leak information as well as permit the host to tamper with the message integrity. Instead, copy whole messages in or out as needed before doing any computation on them. Fixes: d5af44dde546 ("x86/sev: Provide support for SNP guest request NAEs") Signed-off-by: Dionna Glaze Signed-off-by: Borislav Petkov (AMD) Link: https://lore.kernel.org/r/20230214164638.1189804-3-dionnaglaze@google.com --- drivers/virt/coco/sev-guest/sev-guest.c | 27 +++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c index 46f1a8d558b0..0c7b47acba2a 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -46,7 +46,15 @@ struct snp_guest_dev { void *certs_data; struct snp_guest_crypto *crypto; + /* request and response are in unencrypted memory */ struct snp_guest_msg *request, *response; + + /* + * Avoid information leakage by double-buffering shared messages + * in fields that are in regular encrypted memory. + */ + struct snp_guest_msg secret_request, secret_response; + struct snp_secrets_page_layout *layout; struct snp_req_data input; u32 *os_area_msg_seqno; @@ -266,14 +274,17 @@ static int dec_payload(struct snp_guest_dev *snp_dev, struct snp_guest_msg *msg, static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *payload, u32 sz) { struct snp_guest_crypto *crypto = snp_dev->crypto; - struct snp_guest_msg *resp = snp_dev->response; - struct snp_guest_msg *req = snp_dev->request; + struct snp_guest_msg *resp = &snp_dev->secret_response; + struct snp_guest_msg *req = &snp_dev->secret_request; struct snp_guest_msg_hdr *req_hdr = &req->hdr; struct snp_guest_msg_hdr *resp_hdr = &resp->hdr; dev_dbg(snp_dev->dev, "response [seqno %lld type %d version %d sz %d]\n", resp_hdr->msg_seqno, resp_hdr->msg_type, resp_hdr->msg_version, resp_hdr->msg_sz); + /* Copy response from shared memory to encrypted memory. */ + memcpy(resp, snp_dev->response, sizeof(*resp)); + /* Verify that the sequence counter is incremented by 1 */ if (unlikely(resp_hdr->msg_seqno != (req_hdr->msg_seqno + 1))) return -EBADMSG; @@ -297,7 +308,7 @@ static int verify_and_dec_payload(struct snp_guest_dev *snp_dev, void *payload, static int enc_payload(struct snp_guest_dev *snp_dev, u64 seqno, int version, u8 type, void *payload, size_t sz) { - struct snp_guest_msg *req = snp_dev->request; + struct snp_guest_msg *req = &snp_dev->secret_request; struct snp_guest_msg_hdr *hdr = &req->hdr; memset(req, 0, sizeof(*req)); @@ -417,13 +428,21 @@ static int handle_guest_request(struct snp_guest_dev *snp_dev, u64 exit_code, in if (!seqno) return -EIO; + /* Clear shared memory's response for the host to populate. */ memset(snp_dev->response, 0, sizeof(struct snp_guest_msg)); - /* Encrypt the userspace provided payload */ + /* Encrypt the userspace provided payload in snp_dev->secret_request. */ rc = enc_payload(snp_dev, seqno, msg_ver, type, req_buf, req_sz); if (rc) return rc; + /* + * Write the fully encrypted request to the shared unencrypted + * request page. + */ + memcpy(snp_dev->request, &snp_dev->secret_request, + sizeof(snp_dev->secret_request)); + rc = __handle_guest_request(snp_dev, exit_code, fw_err); if (rc) { if (rc == -EIO && *fw_err == SNP_GUEST_REQ_INVALID_LEN)