Skip to content

Commit c08ba63

Browse files
tlendackybp3tk0v
authored andcommitted
virt: sev-guest: Satisfy linear mapping requirement in get_derived_key()
Commit 7ffeb2f ("x86/sev: Document requirement for linear mapping of guest request buffers") added a check that requires the guest request buffers to be in the linear mapping. The get_derived_key() function was passing a buffer that was allocated on the stack, resulting in the call to snp_send_guest_request() returning an error. Update the get_derived_key() function to use an allocated buffer instead of a stack buffer. Fixes: 7ffeb2f ("x86/sev: Document requirement for linear mapping of guest request buffers") Signed-off-by: Tom Lendacky <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Cc: <[email protected]> Link: https://lore.kernel.org/9b764ca9fc79199a091aac684c4926e2080ca7a8.1752698495.git.thomas.lendacky@amd.com
1 parent 5eb1bcd commit c08ba63

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed

drivers/virt/coco/sev-guest/sev-guest.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,11 @@ static int get_report(struct snp_guest_dev *snp_dev, struct snp_guest_request_io
116116

117117
static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg)
118118
{
119+
struct snp_derived_key_resp *derived_key_resp __free(kfree) = NULL;
119120
struct snp_derived_key_req *derived_key_req __free(kfree) = NULL;
120-
struct snp_derived_key_resp derived_key_resp = {0};
121121
struct snp_msg_desc *mdesc = snp_dev->msg_desc;
122122
struct snp_guest_req req = {};
123123
int rc, resp_len;
124-
/* Response data is 64 bytes and max authsize for GCM is 16 bytes. */
125-
u8 buf[64 + 16];
126124

127125
if (!arg->req_data || !arg->resp_data)
128126
return -EINVAL;
@@ -132,8 +130,9 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque
132130
* response payload. Make sure that it has enough space to cover the
133131
* authtag.
134132
*/
135-
resp_len = sizeof(derived_key_resp.data) + mdesc->ctx->authsize;
136-
if (sizeof(buf) < resp_len)
133+
resp_len = sizeof(derived_key_resp->data) + mdesc->ctx->authsize;
134+
derived_key_resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT);
135+
if (!derived_key_resp)
137136
return -ENOMEM;
138137

139138
derived_key_req = kzalloc(sizeof(*derived_key_req), GFP_KERNEL_ACCOUNT);
@@ -149,23 +148,21 @@ static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_reque
149148
req.vmpck_id = mdesc->vmpck_id;
150149
req.req_buf = derived_key_req;
151150
req.req_sz = sizeof(*derived_key_req);
152-
req.resp_buf = buf;
151+
req.resp_buf = derived_key_resp;
153152
req.resp_sz = resp_len;
154153
req.exit_code = SVM_VMGEXIT_GUEST_REQUEST;
155154

156155
rc = snp_send_guest_request(mdesc, &req);
157156
arg->exitinfo2 = req.exitinfo2;
158-
if (rc)
159-
return rc;
160-
161-
memcpy(derived_key_resp.data, buf, sizeof(derived_key_resp.data));
162-
if (copy_to_user((void __user *)arg->resp_data, &derived_key_resp,
163-
sizeof(derived_key_resp)))
164-
rc = -EFAULT;
157+
if (!rc) {
158+
if (copy_to_user((void __user *)arg->resp_data, derived_key_resp,
159+
sizeof(derived_key_resp->data)))
160+
rc = -EFAULT;
161+
}
165162

166163
/* The response buffer contains the sensitive data, explicitly clear it. */
167-
memzero_explicit(buf, sizeof(buf));
168-
memzero_explicit(&derived_key_resp, sizeof(derived_key_resp));
164+
memzero_explicit(derived_key_resp, sizeof(*derived_key_resp));
165+
169166
return rc;
170167
}
171168

0 commit comments

Comments
 (0)