virt: sev-guest: Satisfy linear mapping requirement in get_derived_key()

Commit

7ffeb2fc2670 ("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: 7ffeb2fc2670 ("x86/sev: Document requirement for linear mapping of guest request buffers")
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Cc: <stable@kernel.org>
Link: https://lore.kernel.org/9b764ca9fc79199a091aac684c4926e2080ca7a8.1752698495.git.thomas.lendacky@amd.com

authored by Tom Lendacky and committed by Borislav Petkov (AMD) c08ba630 5eb1bcdb

Changed files
+12 -15
drivers
virt
coco
sev-guest
+12 -15
drivers/virt/coco/sev-guest/sev-guest.c
··· 116 116 117 117 static int get_derived_key(struct snp_guest_dev *snp_dev, struct snp_guest_request_ioctl *arg) 118 118 { 119 + struct snp_derived_key_resp *derived_key_resp __free(kfree) = NULL; 119 120 struct snp_derived_key_req *derived_key_req __free(kfree) = NULL; 120 - struct snp_derived_key_resp derived_key_resp = {0}; 121 121 struct snp_msg_desc *mdesc = snp_dev->msg_desc; 122 122 struct snp_guest_req req = {}; 123 123 int rc, resp_len; 124 - /* Response data is 64 bytes and max authsize for GCM is 16 bytes. */ 125 - u8 buf[64 + 16]; 126 124 127 125 if (!arg->req_data || !arg->resp_data) 128 126 return -EINVAL; ··· 130 132 * response payload. Make sure that it has enough space to cover the 131 133 * authtag. 132 134 */ 133 - resp_len = sizeof(derived_key_resp.data) + mdesc->ctx->authsize; 134 - if (sizeof(buf) < resp_len) 135 + resp_len = sizeof(derived_key_resp->data) + mdesc->ctx->authsize; 136 + derived_key_resp = kzalloc(resp_len, GFP_KERNEL_ACCOUNT); 137 + if (!derived_key_resp) 135 138 return -ENOMEM; 136 139 137 140 derived_key_req = kzalloc(sizeof(*derived_key_req), GFP_KERNEL_ACCOUNT); ··· 148 149 req.vmpck_id = mdesc->vmpck_id; 149 150 req.req_buf = derived_key_req; 150 151 req.req_sz = sizeof(*derived_key_req); 151 - req.resp_buf = buf; 152 + req.resp_buf = derived_key_resp; 152 153 req.resp_sz = resp_len; 153 154 req.exit_code = SVM_VMGEXIT_GUEST_REQUEST; 154 155 155 156 rc = snp_send_guest_request(mdesc, &req); 156 157 arg->exitinfo2 = req.exitinfo2; 157 - if (rc) 158 - return rc; 159 - 160 - memcpy(derived_key_resp.data, buf, sizeof(derived_key_resp.data)); 161 - if (copy_to_user((void __user *)arg->resp_data, &derived_key_resp, 162 - sizeof(derived_key_resp))) 163 - rc = -EFAULT; 158 + if (!rc) { 159 + if (copy_to_user((void __user *)arg->resp_data, derived_key_resp, 160 + sizeof(derived_key_resp->data))) 161 + rc = -EFAULT; 162 + } 164 163 165 164 /* The response buffer contains the sensitive data, explicitly clear it. */ 166 - memzero_explicit(buf, sizeof(buf)); 167 - memzero_explicit(&derived_key_resp, sizeof(derived_key_resp)); 165 + memzero_explicit(derived_key_resp, sizeof(*derived_key_resp)); 166 + 168 167 return rc; 169 168 } 170 169