Skip to content

Commit 630c0e6

Browse files
jan-kiszkagregkh
authored andcommitted
efi: stmm: Fix incorrect buffer allocation method
[ Upstream commit c5e81e6 ] The communication buffer allocated by setup_mm_hdr() is later on passed to tee_shm_register_kernel_buf(). The latter expects those buffers to be contiguous pages, but setup_mm_hdr() just uses kmalloc(). That can cause various corruptions or BUGs, specifically since commit 9aec2fb ("slab: allocate frozen pages"), though it was broken before as well. Fix this by using alloc_pages_exact() instead of kmalloc(). Fixes: c44b6be ("efi: Add tee-based EFI variable driver") Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Acked-by: Sumit Garg <sumit.garg@oss.qualcomm.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent ba82313 commit 630c0e6

File tree

1 file changed

+12
-9
lines changed

1 file changed

+12
-9
lines changed

drivers/firmware/efi/stmm/tee_stmm_efi.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ static efi_status_t mm_communicate(u8 *comm_buf, size_t payload_size)
143143
return var_hdr->ret_status;
144144
}
145145

146+
#define COMM_BUF_SIZE(__payload_size) (MM_COMMUNICATE_HEADER_SIZE + \
147+
MM_VARIABLE_COMMUNICATE_SIZE + \
148+
(__payload_size))
149+
146150
/**
147151
* setup_mm_hdr() - Allocate a buffer for StandAloneMM and initialize the
148152
* header data.
@@ -173,9 +177,8 @@ static void *setup_mm_hdr(u8 **dptr, size_t payload_size, size_t func,
173177
return NULL;
174178
}
175179

176-
comm_buf = kzalloc(MM_COMMUNICATE_HEADER_SIZE +
177-
MM_VARIABLE_COMMUNICATE_SIZE + payload_size,
178-
GFP_KERNEL);
180+
comm_buf = alloc_pages_exact(COMM_BUF_SIZE(payload_size),
181+
GFP_KERNEL | __GFP_ZERO);
179182
if (!comm_buf) {
180183
*ret = EFI_OUT_OF_RESOURCES;
181184
return NULL;
@@ -239,7 +242,7 @@ static efi_status_t get_max_payload(size_t *size)
239242
*/
240243
*size -= 2;
241244
out:
242-
kfree(comm_buf);
245+
free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
243246
return ret;
244247
}
245248

@@ -282,7 +285,7 @@ static efi_status_t get_property_int(u16 *name, size_t name_size,
282285
memcpy(var_property, &smm_property->property, sizeof(*var_property));
283286

284287
out:
285-
kfree(comm_buf);
288+
free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
286289
return ret;
287290
}
288291

@@ -347,7 +350,7 @@ static efi_status_t tee_get_variable(u16 *name, efi_guid_t *vendor,
347350
memcpy(data, (u8 *)var_acc->name + var_acc->name_size,
348351
var_acc->data_size);
349352
out:
350-
kfree(comm_buf);
353+
free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
351354
return ret;
352355
}
353356

@@ -404,7 +407,7 @@ static efi_status_t tee_get_next_variable(unsigned long *name_size,
404407
memcpy(name, var_getnext->name, var_getnext->name_size);
405408

406409
out:
407-
kfree(comm_buf);
410+
free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
408411
return ret;
409412
}
410413

@@ -467,7 +470,7 @@ static efi_status_t tee_set_variable(efi_char16_t *name, efi_guid_t *vendor,
467470
ret = mm_communicate(comm_buf, payload_size);
468471
dev_dbg(pvt_data.dev, "Set Variable %s %d %lx\n", __FILE__, __LINE__, ret);
469472
out:
470-
kfree(comm_buf);
473+
free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
471474
return ret;
472475
}
473476

@@ -507,7 +510,7 @@ static efi_status_t tee_query_variable_info(u32 attributes,
507510
*max_variable_size = mm_query_info->max_variable_size;
508511

509512
out:
510-
kfree(comm_buf);
513+
free_pages_exact(comm_buf, COMM_BUF_SIZE(payload_size));
511514
return ret;
512515
}
513516

0 commit comments

Comments
 (0)