From nobody Fri Dec 19 17:47:45 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 F135DE81818 for ; Tue, 26 Sep 2023 04:17:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233618AbjIZER3 (ORCPT ); Tue, 26 Sep 2023 00:17:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36052 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233098AbjIZERY (ORCPT ); Tue, 26 Sep 2023 00:17:24 -0400 Received: from mgamail.intel.com (mgamail.intel.com [192.55.52.88]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5A359BF for ; Mon, 25 Sep 2023 21:17:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1695701837; x=1727237837; h=subject:from:to:cc:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yHkxxHhfcS/p1Zj4sNJBN+HXPs+0Ubf8u2ycubsIO3g=; b=CSqdrlm67xxNdLS93wEThmfZXIFP/QheO7Win5Nf3sjFAYzt8/1aOQ0i sXxVIC2eM1476TZp6qyi24eDEXZH8xGN3Uj2CM7sLiDQWSBkdfEB7ONb8 Y2BdU6sjsZOR1m/fP6lefz44F8ns5+1xQzzT10OsLVdNGfLYHY8oFukPI PzhW9VY+weMuLYFrQQwfJBXA4GQxiFCpQ+CoT3MrLHoAhQ4TJ/z8b2/cr Wd2LvzE6v7/FZzj+nVzgIJmWpdgpd6tpk4rqbbOcQpjwhMQtATDBaQ4Z+ 02MNJdT7Y+r4mhu8jHy6QuS9XR43N9rswfTyRUbmtFOlENJVgSWpFyALI A==; X-IronPort-AV: E=McAfee;i="6600,9927,10843"; a="412395834" X-IronPort-AV: E=Sophos;i="6.03,177,1694761200"; d="scan'208";a="412395834" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2023 21:17:17 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10843"; a="814314528" X-IronPort-AV: E=Sophos;i="6.03,177,1694761200"; d="scan'208";a="814314528" Received: from fvivekku-mobl.amr.corp.intel.com (HELO dwillia2-xfh.jf.intel.com) ([10.251.18.72]) by fmsmga008-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 25 Sep 2023 21:17:16 -0700 Subject: [PATCH v4 3/6] 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, x86@kernel.org, dave.hansen@linux.intel.com Date: Mon, 25 Sep 2023 21:17:16 -0700 Message-ID: <169570183602.596431.6477217304734993370.stgit@dwillia2-xfh.jf.intel.com> In-Reply-To: <169570181657.596431.6178773442587231200.stgit@dwillia2-xfh.jf.intel.com> References: <169570181657.596431.6178773442587231200.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 Reviewed-by: Kuppuswamy Sathyanarayanan --- 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;