From nobody Fri Dec 19 17:57:04 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BC948C6FA8F for ; Wed, 30 Aug 2023 21:32:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241543AbjH3Vco (ORCPT ); Wed, 30 Aug 2023 17:32:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53988 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241577AbjH3Vck (ORCPT ); Wed, 30 Aug 2023 17:32:40 -0400 Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.126]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DD708465DC for ; Wed, 30 Aug 2023 12:36:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1693424161; x=1724960161; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yHkxxHhfcS/p1Zj4sNJBN+HXPs+0Ubf8u2ycubsIO3g=; b=kRRDhxO1xfa5WXeHxjBP+Skoj9EAnfmjwKjetZp/sYsENECWPc65yBeI ITPNCnTtkGoSrNMCdHetHxSYzR1wMfQrcwkUDDnnJN1SCH4I4a7umnhNn TxPCmECT2DY7qToPfB6PStGQTOBaZxFaiUb2GtvStDJRuxNbtTdy1OE+5 Il1raEaK9UI67hYBG0kiYMCY7cxwi9c5xtwI8rrlj9DzeEe0ns1Zp0p30 TUs2rOUIyKOec69dMdVhOdtqEmkY+jfX5iy1tEz8+oYok+OgZuZ7XcytB OIZD+Ma4ssSkL90PvEabddwfgzGwuaSkHl4CYThtrt5VO1VmgyL5EfzTM g==; X-IronPort-AV: E=McAfee;i="6600,9927,10818"; a="360723643" X-IronPort-AV: E=Sophos;i="6.02,214,1688454000"; d="scan'208";a="360723643" Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Aug 2023 12:33:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10818"; a="853844831" X-IronPort-AV: E=Sophos;i="6.02,214,1688454000"; d="scan'208";a="853844831" Received: from nivakuma-mobl.amr.corp.intel.com (HELO dwillia2-xfh.jf.intel.com) ([10.212.238.163]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 30 Aug 2023 12:33:31 -0700 Subject: [PATCH v3 3/5] virt: sevguest: Prep for kernel internal {get, get_ext}_report() From: Dan Williams To: linux-coco@lists.linux.dev Cc: Borislav Petkov , Tom Lendacky , Dionna Glaze , Brijesh Singh , peterz@infradead.org, linux-kernel@vger.kernel.org, tglx@linutronix.de Date: Wed, 30 Aug 2023 12:33:30 -0700 Message-ID: <169342401062.3934343.10039181536465702635.stgit@dwillia2-xfh.jf.intel.com> In-Reply-To: <169342399185.3934343.3035845348326944519.stgit@dwillia2-xfh.jf.intel.com> References: <169342399185.3934343.3035845348326944519.stgit@dwillia2-xfh.jf.intel.com> User-Agent: StGit/0.18-3-g996c MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In preparation for using the configs-tsm facility to convey attestation blobs to userspace, switch to using the 'sockptr' api for copying payloads to provided buffers where 'sockptr' handles user vs kernel buffers. While configfs-tsm is meant to replace existing confidential computing ioctl() implementations for attestation report retrieval the old ioctl() path needs to stick around for a deprecation period. No behavior change intended. Cc: Borislav Petkov Cc: Tom Lendacky Cc: Dionna Glaze Cc: Brijesh Singh Signed-off-by: Dan Williams --- drivers/virt/coco/sev-guest/sev-guest.c | 50 ++++++++++++++++++++-------= ---- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/se= v-guest/sev-guest.c index 97dbe715e96a..c3c9e9ea691f 100644 --- a/drivers/virt/coco/sev-guest/sev-guest.c +++ b/drivers/virt/coco/sev-guest/sev-guest.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include =20 @@ -470,7 +471,13 @@ static int handle_guest_request(struct snp_guest_dev *= snp_dev, u64 exit_code, return 0; } =20 -static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_requ= est_ioctl *arg) +struct snp_req_resp { + sockptr_t req_data; + sockptr_t resp_data; +}; + +static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_requ= est_ioctl *arg, + struct snp_req_resp *io) { struct snp_guest_crypto *crypto =3D snp_dev->crypto; struct snp_report_resp *resp; @@ -479,10 +486,10 @@ static int get_report(struct snp_guest_dev *snp_dev, = struct snp_guest_request_io =20 lockdep_assert_held(&snp_cmd_mutex); =20 - if (!arg->req_data || !arg->resp_data) + if (sockptr_is_null(io->req_data) || sockptr_is_null(io->resp_data)) return -EINVAL; =20 - if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) + if (copy_from_sockptr(&req, io->req_data, sizeof(req))) return -EFAULT; =20 /* @@ -501,7 +508,7 @@ static int get_report(struct snp_guest_dev *snp_dev, st= ruct snp_guest_request_io if (rc) goto e_free; =20 - if (copy_to_user((void __user *)arg->resp_data, resp, sizeof(*resp))) + if (copy_to_sockptr(io->resp_data, resp, sizeof(*resp))) rc =3D -EFAULT; =20 e_free: @@ -550,22 +557,25 @@ static int get_derived_key(struct snp_guest_dev *snp_= dev, struct snp_guest_reque return rc; } =20 -static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_= request_ioctl *arg) +static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_= request_ioctl *arg, + struct snp_req_resp *io) + { struct snp_guest_crypto *crypto =3D snp_dev->crypto; struct snp_ext_report_req req; struct snp_report_resp *resp; int ret, npages =3D 0, resp_len; + sockptr_t certs_address; =20 lockdep_assert_held(&snp_cmd_mutex); =20 - if (!arg->req_data || !arg->resp_data) + if (sockptr_is_null(io->req_data) || sockptr_is_null(io->resp_data)) return -EINVAL; =20 - if (copy_from_user(&req, (void __user *)arg->req_data, sizeof(req))) + if (copy_from_sockptr(&req, io->req_data, sizeof(req))) return -EFAULT; =20 - /* userspace does not want certificate data */ + /* caller does not want certificate data */ if (!req.certs_len || !req.certs_address) goto cmd; =20 @@ -573,8 +583,13 @@ static int get_ext_report(struct snp_guest_dev *snp_de= v, struct snp_guest_reques !IS_ALIGNED(req.certs_len, PAGE_SIZE)) return -EINVAL; =20 - if (!access_ok((const void __user *)req.certs_address, req.certs_len)) - return -EFAULT; + if (sockptr_is_kernel(io->resp_data)) { + certs_address =3D KERNEL_SOCKPTR((void *)req.certs_address); + } else { + certs_address =3D USER_SOCKPTR((void __user *)req.certs_address); + if (!access_ok(certs_address.user, req.certs_len)) + return -EFAULT; + } =20 /* * Initialize the intermediate buffer with all zeros. This buffer @@ -604,21 +619,19 @@ static int get_ext_report(struct snp_guest_dev *snp_d= ev, struct snp_guest_reques if (arg->vmm_error =3D=3D SNP_GUEST_VMM_ERR_INVALID_LEN) { req.certs_len =3D snp_dev->input.data_npages << PAGE_SHIFT; =20 - if (copy_to_user((void __user *)arg->req_data, &req, sizeof(req))) + if (copy_to_sockptr(io->req_data, &req, sizeof(req))) ret =3D -EFAULT; } =20 if (ret) goto e_free; =20 - if (npages && - copy_to_user((void __user *)req.certs_address, snp_dev->certs_data, - req.certs_len)) { + if (npages && copy_to_sockptr(certs_address, snp_dev->certs_data, req.cer= ts_len)) { ret =3D -EFAULT; goto e_free; } =20 - if (copy_to_user((void __user *)arg->resp_data, resp, sizeof(*resp))) + if (copy_to_sockptr(io->resp_data, resp, sizeof(*resp))) ret =3D -EFAULT; =20 e_free: @@ -631,6 +644,7 @@ static long snp_guest_ioctl(struct file *file, unsigned= int ioctl, unsigned long struct snp_guest_dev *snp_dev =3D to_snp_dev(file); void __user *argp =3D (void __user *)arg; struct snp_guest_request_ioctl input; + struct snp_req_resp io; int ret =3D -ENOTTY; =20 if (copy_from_user(&input, argp, sizeof(input))) @@ -651,15 +665,17 @@ static long snp_guest_ioctl(struct file *file, unsign= ed int ioctl, unsigned long return -ENOTTY; } =20 + io.req_data =3D USER_SOCKPTR((void __user *)input.req_data); + io.resp_data =3D USER_SOCKPTR((void __user *)input.resp_data); switch (ioctl) { case SNP_GET_REPORT: - ret =3D get_report(snp_dev, &input); + ret =3D get_report(snp_dev, &input, &io); break; case SNP_GET_DERIVED_KEY: ret =3D get_derived_key(snp_dev, &input); break; case SNP_GET_EXT_REPORT: - ret =3D get_ext_report(snp_dev, &input); + ret =3D get_ext_report(snp_dev, &input, &io); break; default: break;