mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-25 06:00:43 +00:00
efi_loader: variable: keep temporary buffer during the authentication
This is a bug fix; Setting an authenticated variable may fail due to a memory corruption in the authentication. A temporary buffer will, if needed, be allocated to parse a variable's authentication data, and some portion of buffer, specifically signer's certificates, will be referenced by efi_signature_verify(). So the buffer should be kept valid until the authentication process is finished. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Tested-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
parent
bc78d22d0f
commit
0658bb29b0
1 changed files with 20 additions and 7 deletions
|
@ -37,16 +37,21 @@ static u8 pkcs7_hdr[] = {
|
|||
* efi_variable_parse_signature - parse a signature in variable
|
||||
* @buf: Pointer to variable's value
|
||||
* @buflen: Length of @buf
|
||||
* @tmpbuf: Pointer to temporary buffer
|
||||
*
|
||||
* Parse a signature embedded in variable's value and instantiate
|
||||
* a pkcs7_message structure. Since pkcs7_parse_message() accepts only
|
||||
* pkcs7's signedData, some header needed be prepended for correctly
|
||||
* parsing authentication data, particularly for variable's.
|
||||
* A temporary buffer will be allocated if needed, and it should be
|
||||
* kept valid during the authentication because some data in the buffer
|
||||
* will be referenced by efi_signature_verify().
|
||||
*
|
||||
* Return: Pointer to pkcs7_message structure on success, NULL on error
|
||||
*/
|
||||
static struct pkcs7_message *efi_variable_parse_signature(const void *buf,
|
||||
size_t buflen)
|
||||
size_t buflen,
|
||||
u8 **tmpbuf)
|
||||
{
|
||||
u8 *ebuf;
|
||||
size_t ebuflen, len;
|
||||
|
@ -59,7 +64,9 @@ static struct pkcs7_message *efi_variable_parse_signature(const void *buf,
|
|||
if (buflen > sizeof(pkcs7_hdr) &&
|
||||
!memcmp(&((u8 *)buf)[4], &pkcs7_hdr[4], 11)) {
|
||||
msg = pkcs7_parse_message(buf, buflen);
|
||||
goto out;
|
||||
if (IS_ERR(msg))
|
||||
return NULL;
|
||||
return msg;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -94,12 +101,12 @@ static struct pkcs7_message *efi_variable_parse_signature(const void *buf,
|
|||
|
||||
msg = pkcs7_parse_message(ebuf, ebuflen);
|
||||
|
||||
free(ebuf);
|
||||
|
||||
out:
|
||||
if (IS_ERR(msg))
|
||||
if (IS_ERR(msg)) {
|
||||
free(ebuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*tmpbuf = ebuf;
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
@ -136,6 +143,7 @@ static efi_status_t efi_variable_authenticate(u16 *variable,
|
|||
struct efi_time timestamp;
|
||||
struct rtc_time tm;
|
||||
u64 new_time;
|
||||
u8 *ebuf;
|
||||
enum efi_auth_var_type var_type;
|
||||
efi_status_t ret;
|
||||
|
||||
|
@ -143,6 +151,7 @@ static efi_status_t efi_variable_authenticate(u16 *variable,
|
|||
truststore = NULL;
|
||||
truststore2 = NULL;
|
||||
regs = NULL;
|
||||
ebuf = NULL;
|
||||
ret = EFI_SECURITY_VIOLATION;
|
||||
|
||||
if (*data_size < sizeof(struct efi_variable_authentication_2))
|
||||
|
@ -204,9 +213,12 @@ static efi_status_t efi_variable_authenticate(u16 *variable,
|
|||
/* variable's signature list */
|
||||
if (auth->auth_info.hdr.dwLength < sizeof(auth->auth_info))
|
||||
goto err;
|
||||
|
||||
/* ebuf should be kept valid during the authentication */
|
||||
var_sig = efi_variable_parse_signature(auth->auth_info.cert_data,
|
||||
auth->auth_info.hdr.dwLength
|
||||
- sizeof(auth->auth_info));
|
||||
- sizeof(auth->auth_info),
|
||||
&ebuf);
|
||||
if (!var_sig) {
|
||||
EFI_PRINT("Parsing variable's signature failed\n");
|
||||
goto err;
|
||||
|
@ -262,6 +274,7 @@ err:
|
|||
efi_sigstore_free(truststore);
|
||||
efi_sigstore_free(truststore2);
|
||||
pkcs7_free_message(var_sig);
|
||||
free(ebuf);
|
||||
free(regs);
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue