[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250307013700.437505-2-aik@amd.com>
Date: Fri, 7 Mar 2025 12:36:59 +1100
From: Alexey Kardashevskiy <aik@....com>
To: <x86@...nel.org>
CC: <linux-kernel@...r.kernel.org>, Thomas Gleixner <tglx@...utronix.de>,
"Ingo Molnar" <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>, Dave Hansen
<dave.hansen@...ux.intel.com>, "H. Peter Anvin" <hpa@...or.com>, Tom Lendacky
<thomas.lendacky@....com>, Nikunj A Dadhania <nikunj@....com>, Ard Biesheuvel
<ardb@...nel.org>, Pavan Kumar Paluri <papaluri@....com>, Ashish Kalra
<ashish.kalra@....com>, Paolo Bonzini <pbonzini@...hat.com>, Michael Roth
<michael.roth@....com>, Kevin Loughlin <kevinloughlin@...gle.com>,
"Kuppuswamy Sathyanarayanan" <sathyanarayanan.kuppuswamy@...ux.intel.com>,
Brijesh Singh <brijesh.singh@....com>, Liam Merwick
<liam.merwick@...cle.com>, "Alexey Kardashevskiy" <aik@....com>,
<stable@...r.kernel.org>, <andreas.stuehrk@...i.tech>
Subject: [PATCH 1/2] virt: sev-guest: Allocate request data dynamically
From: Nikunj A Dadhania <nikunj@....com>
Commit ae596615d93d ("virt: sev-guest: Reduce the scope of SNP command
mutex") narrowed the command mutex scope to snp_send_guest_request.
However, GET_REPORT, GET_DERIVED_KEY, and GET_EXT_REPORT share the req
structure in snp_guest_dev. Without the mutex protection, concurrent
requests can overwrite each other's data. Fix it by dynamically allocating
the request structure.
Fixes: ae596615d93d ("virt: sev-guest: Reduce the scope of SNP command mutex")
Cc: stable@...r.kernel.org
Reported-by: andreas.stuehrk@...i.tech
Closes: https://github.com/AMDESE/AMDSEV/issues/265
Signed-off-by: Nikunj A Dadhania <nikunj@....com>
---
drivers/virt/coco/sev-guest/sev-guest.c | 24 ++++++++++++--------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/virt/coco/sev-guest/sev-guest.c b/drivers/virt/coco/sev-guest/sev-guest.c
index ddec5677e247..4699fdc9ed44 100644
--- a/drivers/virt/coco/sev-guest/sev-guest.c
+++ b/drivers/virt/coco/sev-guest/sev-guest.c
@@ -39,12 +39,6 @@ struct snp_guest_dev {
struct miscdevice misc;
struct snp_msg_desc *msg_desc;
-
- union {
- struct snp_report_req report;
- struct snp_derived_key_req derived_key;
- struct snp_ext_report_req ext_report;
- } req;
};
/*
@@ -72,7 +66,7 @@ struct snp_req_resp {
static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
{
- struct snp_report_req *report_req = &snp_dev->req.report;
+ struct snp_report_req *report_req __free(kfree) = NULL;
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
struct snp_report_resp *report_resp;
struct snp_guest_req req = {};
@@ -81,6 +75,10 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
if (!arg->req_data || !arg->resp_data)
return -EINVAL;
+ report_req = kzalloc(sizeof(*report_req), GFP_KERNEL_ACCOUNT);
+ if (!report_req)
+ return -ENOMEM;
+
if (copy_from_user(report_req, (void __user *)arg->req_data, sizeof(*report_req)))
return -EFAULT;
@@ -117,7 +115,7 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
{
- struct snp_derived_key_req *derived_key_req = &snp_dev->req.derived_key;
+ struct snp_derived_key_req *derived_key_req __free(kfree) = NULL;
struct snp_derived_key_resp derived_key_resp = {0};
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
struct snp_guest_req req = {};
@@ -137,6 +135,10 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque
if (sizeof(buf) < resp_len)
return -ENOMEM;
+ derived_key_req = kzalloc(sizeof(*derived_key_req), GFP_KERNEL_ACCOUNT);
+ if (!derived_key_req)
+ return -ENOMEM;
+
if (copy_from_user(derived_key_req, (void __user *)arg->req_data,
sizeof(*derived_key_req)))
return -EFAULT;
@@ -169,7 +171,7 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
struct snp_req_resp *io)
{
- struct snp_ext_report_req *report_req = &snp_dev->req.ext_report;
+ struct snp_ext_report_req *report_req __free(kfree) = NULL;
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
struct snp_report_resp *report_resp;
struct snp_guest_req req = {};
@@ -179,6 +181,10 @@ static int get_ext_report(struct snp_guest_dev *snp_dev, struct snp_guest_reques
if (sockptr_is_null(io->req_data) || sockptr_is_null(io->resp_data))
return -EINVAL;
+ report_req = kzalloc(sizeof(*report_req), GFP_KERNEL_ACCOUNT);
+ if (!report_req)
+ return -ENOMEM;
+
if (copy_from_sockptr(report_req, io->req_data, sizeof(*report_req)))
return -EFAULT;
--
2.47.1
Powered by blists - more mailing lists