mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-30 08:07:59 +00:00
efi_loader: prepare for read only OP-TEE variables
We currently have two implementations of UEFI variables: * variables provided via an OP-TEE module * variables stored in the U-Boot environment Read only variables are up to now only implemented in the U-Boot environment implementation. Provide a common interface for both implementations that allows handling read-only variables. As variable access is limited to very few source files put variable related definitions into new include efi_variable.h instead of efi_loader. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
This commit is contained in:
parent
5a8d1f60b2
commit
f2d2b3a11c
6 changed files with 193 additions and 181 deletions
|
@ -93,6 +93,8 @@ Runtime services
|
||||||
Variable services
|
Variable services
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. kernel-doc:: include/efi_variable.h
|
||||||
|
:internal:
|
||||||
.. kernel-doc:: lib/efi_loader/efi_variable.c
|
.. kernel-doc:: lib/efi_loader/efi_variable.c
|
||||||
:internal:
|
:internal:
|
||||||
|
|
||||||
|
|
43
include/efi_variable.h
Normal file
43
include/efi_variable.h
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _EFI_VARIABLE_H
|
||||||
|
#define _EFI_VARIABLE_H
|
||||||
|
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
|
||||||
|
#define EFI_VARIABLE_READ_ONLY BIT(31)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* efi_get_variable() - retrieve value of a UEFI variable
|
||||||
|
*
|
||||||
|
* @variable_name: name of the variable
|
||||||
|
* @vendor: vendor GUID
|
||||||
|
* @attributes: attributes of the variable
|
||||||
|
* @data_size: size of the buffer to which the variable value is copied
|
||||||
|
* @data: buffer to which the variable value is copied
|
||||||
|
* @timep: authentication time (seconds since start of epoch)
|
||||||
|
* Return: status code
|
||||||
|
*/
|
||||||
|
efi_status_t efi_get_variable_int(u16 *variable_name, const efi_guid_t *vendor,
|
||||||
|
u32 *attributes, efi_uintn_t *data_size,
|
||||||
|
void *data, u64 *timep);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* efi_set_variable() - set value of a UEFI variable
|
||||||
|
*
|
||||||
|
* @variable_name: name of the variable
|
||||||
|
* @vendor: vendor GUID
|
||||||
|
* @attributes: attributes of the variable
|
||||||
|
* @data_size: size of the buffer with the variable value
|
||||||
|
* @data: buffer with the variable value
|
||||||
|
* @ro_check: check the read only read only bit in attributes
|
||||||
|
* Return: status code
|
||||||
|
*/
|
||||||
|
efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor,
|
||||||
|
u32 attributes, efi_uintn_t data_size,
|
||||||
|
const void *data, bool ro_check);
|
||||||
|
|
||||||
|
#endif
|
|
@ -35,6 +35,7 @@ obj-y += efi_root_node.o
|
||||||
obj-y += efi_runtime.o
|
obj-y += efi_runtime.o
|
||||||
obj-y += efi_setup.o
|
obj-y += efi_setup.o
|
||||||
obj-$(CONFIG_EFI_UNICODE_COLLATION_PROTOCOL2) += efi_unicode_collation.o
|
obj-$(CONFIG_EFI_UNICODE_COLLATION_PROTOCOL2) += efi_unicode_collation.o
|
||||||
|
obj-y += efi_var_common.o
|
||||||
ifeq ($(CONFIG_EFI_MM_COMM_TEE),y)
|
ifeq ($(CONFIG_EFI_MM_COMM_TEE),y)
|
||||||
obj-y += efi_variable_tee.o
|
obj-y += efi_variable_tee.o
|
||||||
else
|
else
|
||||||
|
|
78
lib/efi_loader/efi_var_common.c
Normal file
78
lib/efi_loader/efi_var_common.c
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* UEFI runtime variable services
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020, Heinrich Schuchardt <xypron.glpk@gmx.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <efi_loader.h>
|
||||||
|
#include <efi_variable.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* efi_efi_get_variable() - retrieve value of a UEFI variable
|
||||||
|
*
|
||||||
|
* This function implements the GetVariable runtime service.
|
||||||
|
*
|
||||||
|
* See the Unified Extensible Firmware Interface (UEFI) specification for
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* @variable_name: name of the variable
|
||||||
|
* @vendor: vendor GUID
|
||||||
|
* @attributes: attributes of the variable
|
||||||
|
* @data_size: size of the buffer to which the variable value is copied
|
||||||
|
* @data: buffer to which the variable value is copied
|
||||||
|
* Return: status code
|
||||||
|
*/
|
||||||
|
efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
|
||||||
|
const efi_guid_t *vendor, u32 *attributes,
|
||||||
|
efi_uintn_t *data_size, void *data)
|
||||||
|
{
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
|
EFI_ENTRY("\"%ls\" %pUl %p %p %p", variable_name, vendor, attributes,
|
||||||
|
data_size, data);
|
||||||
|
|
||||||
|
ret = efi_get_variable_int(variable_name, vendor, attributes,
|
||||||
|
data_size, data, NULL);
|
||||||
|
|
||||||
|
/* Remove EFI_VARIABLE_READ_ONLY flag */
|
||||||
|
if (attributes)
|
||||||
|
*attributes &= EFI_VARIABLE_MASK;
|
||||||
|
|
||||||
|
return EFI_EXIT(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* efi_set_variable() - set value of a UEFI variable
|
||||||
|
*
|
||||||
|
* This function implements the SetVariable runtime service.
|
||||||
|
*
|
||||||
|
* See the Unified Extensible Firmware Interface (UEFI) specification for
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* @variable_name: name of the variable
|
||||||
|
* @vendor: vendor GUID
|
||||||
|
* @attributes: attributes of the variable
|
||||||
|
* @data_size: size of the buffer with the variable value
|
||||||
|
* @data: buffer with the variable value
|
||||||
|
* Return: status code
|
||||||
|
*/
|
||||||
|
efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
|
||||||
|
const efi_guid_t *vendor, u32 attributes,
|
||||||
|
efi_uintn_t data_size, const void *data)
|
||||||
|
{
|
||||||
|
efi_status_t ret;
|
||||||
|
|
||||||
|
EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes,
|
||||||
|
data_size, data);
|
||||||
|
|
||||||
|
/* Make sure that the EFI_VARIABLE_READ_ONLY flag is not set */
|
||||||
|
if (attributes & ~(u32)EFI_VARIABLE_MASK)
|
||||||
|
ret = EFI_INVALID_PARAMETER;
|
||||||
|
else
|
||||||
|
ret = efi_set_variable_int(variable_name, vendor, attributes,
|
||||||
|
data_size, data, true);
|
||||||
|
|
||||||
|
return EFI_EXIT(ret);
|
||||||
|
}
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
|
#include <efi_variable.h>
|
||||||
#include <env.h>
|
#include <env.h>
|
||||||
#include <env_internal.h>
|
#include <env_internal.h>
|
||||||
#include <hexdump.h>
|
#include <hexdump.h>
|
||||||
|
@ -15,7 +16,6 @@
|
||||||
#include <search.h>
|
#include <search.h>
|
||||||
#include <uuid.h>
|
#include <uuid.h>
|
||||||
#include <crypto/pkcs7_parser.h>
|
#include <crypto/pkcs7_parser.h>
|
||||||
#include <linux/bitops.h>
|
|
||||||
#include <linux/compat.h>
|
#include <linux/compat.h>
|
||||||
#include <u-boot/crc.h>
|
#include <u-boot/crc.h>
|
||||||
|
|
||||||
|
@ -30,21 +30,6 @@ static bool efi_secure_boot;
|
||||||
static enum efi_secure_mode efi_secure_mode;
|
static enum efi_secure_mode efi_secure_mode;
|
||||||
static u8 efi_vendor_keys;
|
static u8 efi_vendor_keys;
|
||||||
|
|
||||||
#define READ_ONLY BIT(31)
|
|
||||||
|
|
||||||
static efi_status_t efi_get_variable_common(u16 *variable_name,
|
|
||||||
const efi_guid_t *vendor,
|
|
||||||
u32 *attributes,
|
|
||||||
efi_uintn_t *data_size, void *data,
|
|
||||||
u64 *timep);
|
|
||||||
|
|
||||||
static efi_status_t efi_set_variable_common(u16 *variable_name,
|
|
||||||
const efi_guid_t *vendor,
|
|
||||||
u32 attributes,
|
|
||||||
efi_uintn_t data_size,
|
|
||||||
const void *data,
|
|
||||||
bool ro_check);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mapping between EFI variables and u-boot variables:
|
* Mapping between EFI variables and u-boot variables:
|
||||||
*
|
*
|
||||||
|
@ -155,7 +140,7 @@ static const char *parse_attr(const char *str, u32 *attrp, u64 *timep)
|
||||||
str++;
|
str++;
|
||||||
|
|
||||||
if ((s = prefix(str, "ro"))) {
|
if ((s = prefix(str, "ro"))) {
|
||||||
attr |= READ_ONLY;
|
attr |= EFI_VARIABLE_READ_ONLY;
|
||||||
} else if ((s = prefix(str, "nv"))) {
|
} else if ((s = prefix(str, "nv"))) {
|
||||||
attr |= EFI_VARIABLE_NON_VOLATILE;
|
attr |= EFI_VARIABLE_NON_VOLATILE;
|
||||||
} else if ((s = prefix(str, "boot"))) {
|
} else if ((s = prefix(str, "boot"))) {
|
||||||
|
@ -203,29 +188,29 @@ static efi_status_t efi_set_secure_state(u8 secure_boot, u8 setup_mode,
|
||||||
|
|
||||||
attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS |
|
EFI_VARIABLE_RUNTIME_ACCESS |
|
||||||
READ_ONLY;
|
EFI_VARIABLE_READ_ONLY;
|
||||||
ret = efi_set_variable_common(L"SecureBoot", &efi_global_variable_guid,
|
ret = efi_set_variable_int(L"SecureBoot", &efi_global_variable_guid,
|
||||||
attributes, sizeof(secure_boot),
|
attributes, sizeof(secure_boot),
|
||||||
&secure_boot, false);
|
&secure_boot, false);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ret = efi_set_variable_common(L"SetupMode", &efi_global_variable_guid,
|
ret = efi_set_variable_int(L"SetupMode", &efi_global_variable_guid,
|
||||||
attributes, sizeof(setup_mode),
|
attributes, sizeof(setup_mode),
|
||||||
&setup_mode, false);
|
&setup_mode, false);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ret = efi_set_variable_common(L"AuditMode", &efi_global_variable_guid,
|
ret = efi_set_variable_int(L"AuditMode", &efi_global_variable_guid,
|
||||||
attributes, sizeof(audit_mode),
|
attributes, sizeof(audit_mode),
|
||||||
&audit_mode, false);
|
&audit_mode, false);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
ret = efi_set_variable_common(L"DeployedMode",
|
ret = efi_set_variable_int(L"DeployedMode",
|
||||||
&efi_global_variable_guid, attributes,
|
&efi_global_variable_guid, attributes,
|
||||||
sizeof(deployed_mode), &deployed_mode,
|
sizeof(deployed_mode), &deployed_mode,
|
||||||
false);
|
false);
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +220,7 @@ err:
|
||||||
* @mode: new state
|
* @mode: new state
|
||||||
*
|
*
|
||||||
* Depending on @mode, secure boot related variables are updated.
|
* Depending on @mode, secure boot related variables are updated.
|
||||||
* Those variables are *read-only* for users, efi_set_variable_common()
|
* Those variables are *read-only* for users, efi_set_variable_int()
|
||||||
* is called here.
|
* is called here.
|
||||||
*
|
*
|
||||||
* Return: status code
|
* Return: status code
|
||||||
|
@ -254,10 +239,10 @@ static efi_status_t efi_transfer_secure_state(enum efi_secure_mode mode)
|
||||||
|
|
||||||
efi_secure_boot = true;
|
efi_secure_boot = true;
|
||||||
} else if (mode == EFI_MODE_AUDIT) {
|
} else if (mode == EFI_MODE_AUDIT) {
|
||||||
ret = efi_set_variable_common(L"PK", &efi_global_variable_guid,
|
ret = efi_set_variable_int(L"PK", &efi_global_variable_guid,
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS,
|
EFI_VARIABLE_RUNTIME_ACCESS,
|
||||||
0, NULL, false);
|
0, NULL, false);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -309,8 +294,8 @@ static efi_status_t efi_init_secure_state(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
ret = efi_get_variable_common(L"PK", &efi_global_variable_guid,
|
ret = efi_get_variable_int(L"PK", &efi_global_variable_guid,
|
||||||
NULL, &size, NULL, NULL);
|
NULL, &size, NULL, NULL);
|
||||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||||
if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
|
if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT))
|
||||||
mode = EFI_MODE_USER;
|
mode = EFI_MODE_USER;
|
||||||
|
@ -327,13 +312,13 @@ static efi_status_t efi_init_secure_state(void)
|
||||||
|
|
||||||
ret = efi_transfer_secure_state(mode);
|
ret = efi_transfer_secure_state(mode);
|
||||||
if (ret == EFI_SUCCESS)
|
if (ret == EFI_SUCCESS)
|
||||||
ret = efi_set_variable_common(L"VendorKeys",
|
ret = efi_set_variable_int(L"VendorKeys",
|
||||||
&efi_global_variable_guid,
|
&efi_global_variable_guid,
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS |
|
EFI_VARIABLE_RUNTIME_ACCESS |
|
||||||
READ_ONLY,
|
EFI_VARIABLE_READ_ONLY,
|
||||||
sizeof(efi_vendor_keys),
|
sizeof(efi_vendor_keys),
|
||||||
&efi_vendor_keys, false);
|
&efi_vendor_keys, false);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -599,11 +584,9 @@ static efi_status_t efi_variable_authenticate(u16 *variable,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_EFI_SECURE_BOOT */
|
#endif /* CONFIG_EFI_SECURE_BOOT */
|
||||||
|
|
||||||
static efi_status_t efi_get_variable_common(u16 *variable_name,
|
efi_status_t efi_get_variable_int(u16 *variable_name, const efi_guid_t *vendor,
|
||||||
const efi_guid_t *vendor,
|
u32 *attributes, efi_uintn_t *data_size,
|
||||||
u32 *attributes,
|
void *data, u64 *timep)
|
||||||
efi_uintn_t *data_size, void *data,
|
|
||||||
u64 *timep)
|
|
||||||
{
|
{
|
||||||
char *native_name;
|
char *native_name;
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
@ -684,40 +667,11 @@ static efi_status_t efi_get_variable_common(u16 *variable_name,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (attributes)
|
if (attributes)
|
||||||
*attributes = attr & EFI_VARIABLE_MASK;
|
*attributes = attr;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* efi_efi_get_variable() - retrieve value of a UEFI variable
|
|
||||||
*
|
|
||||||
* This function implements the GetVariable runtime service.
|
|
||||||
*
|
|
||||||
* See the Unified Extensible Firmware Interface (UEFI) specification for
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* @variable_name: name of the variable
|
|
||||||
* @vendor: vendor GUID
|
|
||||||
* @attributes: attributes of the variable
|
|
||||||
* @data_size: size of the buffer to which the variable value is copied
|
|
||||||
* @data: buffer to which the variable value is copied
|
|
||||||
* Return: status code
|
|
||||||
*/
|
|
||||||
efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
|
|
||||||
const efi_guid_t *vendor, u32 *attributes,
|
|
||||||
efi_uintn_t *data_size, void *data)
|
|
||||||
{
|
|
||||||
efi_status_t ret;
|
|
||||||
|
|
||||||
EFI_ENTRY("\"%ls\" %pUl %p %p %p", variable_name, vendor, attributes,
|
|
||||||
data_size, data);
|
|
||||||
|
|
||||||
ret = efi_get_variable_common(variable_name, vendor, attributes,
|
|
||||||
data_size, data, NULL);
|
|
||||||
return EFI_EXIT(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *efi_variables_list;
|
static char *efi_variables_list;
|
||||||
static char *efi_cur_variable;
|
static char *efi_cur_variable;
|
||||||
|
|
||||||
|
@ -881,12 +835,9 @@ efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
|
||||||
return EFI_EXIT(ret);
|
return EFI_EXIT(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static efi_status_t efi_set_variable_common(u16 *variable_name,
|
efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor,
|
||||||
const efi_guid_t *vendor,
|
u32 attributes, efi_uintn_t data_size,
|
||||||
u32 attributes,
|
const void *data, bool ro_check)
|
||||||
efi_uintn_t data_size,
|
|
||||||
const void *data,
|
|
||||||
bool ro_check)
|
|
||||||
{
|
{
|
||||||
char *native_name = NULL, *old_data = NULL, *val = NULL, *s;
|
char *native_name = NULL, *old_data = NULL, *val = NULL, *s;
|
||||||
efi_uintn_t old_size;
|
efi_uintn_t old_size;
|
||||||
|
@ -909,15 +860,15 @@ static efi_status_t efi_set_variable_common(u16 *variable_name,
|
||||||
/* check if a variable exists */
|
/* check if a variable exists */
|
||||||
old_size = 0;
|
old_size = 0;
|
||||||
attr = 0;
|
attr = 0;
|
||||||
ret = efi_get_variable_common(variable_name, vendor, &attr,
|
ret = efi_get_variable_int(variable_name, vendor, &attr,
|
||||||
&old_size, NULL, &time);
|
&old_size, NULL, &time);
|
||||||
append = !!(attributes & EFI_VARIABLE_APPEND_WRITE);
|
append = !!(attributes & EFI_VARIABLE_APPEND_WRITE);
|
||||||
attributes &= ~(u32)EFI_VARIABLE_APPEND_WRITE;
|
attributes &= ~(u32)EFI_VARIABLE_APPEND_WRITE;
|
||||||
delete = !append && (!data_size || !attributes);
|
delete = !append && (!data_size || !attributes);
|
||||||
|
|
||||||
/* check attributes */
|
/* check attributes */
|
||||||
if (old_size) {
|
if (old_size) {
|
||||||
if (ro_check && (attr & READ_ONLY)) {
|
if (ro_check && (attr & EFI_VARIABLE_READ_ONLY)) {
|
||||||
ret = EFI_WRITE_PROTECTED;
|
ret = EFI_WRITE_PROTECTED;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -925,8 +876,8 @@ static efi_status_t efi_set_variable_common(u16 *variable_name,
|
||||||
/* attributes won't be changed */
|
/* attributes won't be changed */
|
||||||
if (!delete &&
|
if (!delete &&
|
||||||
((ro_check && attr != attributes) ||
|
((ro_check && attr != attributes) ||
|
||||||
(!ro_check && ((attr & ~(u32)READ_ONLY)
|
(!ro_check && ((attr & ~(u32)EFI_VARIABLE_READ_ONLY)
|
||||||
!= (attributes & ~(u32)READ_ONLY))))) {
|
!= (attributes & ~(u32)EFI_VARIABLE_READ_ONLY))))) {
|
||||||
ret = EFI_INVALID_PARAMETER;
|
ret = EFI_INVALID_PARAMETER;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -1000,8 +951,8 @@ static efi_status_t efi_set_variable_common(u16 *variable_name,
|
||||||
ret = EFI_OUT_OF_RESOURCES;
|
ret = EFI_OUT_OF_RESOURCES;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
ret = efi_get_variable_common(variable_name, vendor,
|
ret = efi_get_variable_int(variable_name, vendor,
|
||||||
&attr, &old_size, old_data, NULL);
|
&attr, &old_size, old_data, NULL);
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto err;
|
goto err;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1021,7 +972,7 @@ static efi_status_t efi_set_variable_common(u16 *variable_name,
|
||||||
/*
|
/*
|
||||||
* store attributes
|
* store attributes
|
||||||
*/
|
*/
|
||||||
attributes &= (READ_ONLY |
|
attributes &= (EFI_VARIABLE_READ_ONLY |
|
||||||
EFI_VARIABLE_NON_VOLATILE |
|
EFI_VARIABLE_NON_VOLATILE |
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||||
EFI_VARIABLE_RUNTIME_ACCESS |
|
EFI_VARIABLE_RUNTIME_ACCESS |
|
||||||
|
@ -1030,7 +981,7 @@ static efi_status_t efi_set_variable_common(u16 *variable_name,
|
||||||
while (attributes) {
|
while (attributes) {
|
||||||
attr = 1 << (ffs(attributes) - 1);
|
attr = 1 << (ffs(attributes) - 1);
|
||||||
|
|
||||||
if (attr == READ_ONLY) {
|
if (attr == EFI_VARIABLE_READ_ONLY) {
|
||||||
s += sprintf(s, "ro");
|
s += sprintf(s, "ro");
|
||||||
} else if (attr == EFI_VARIABLE_NON_VOLATILE) {
|
} else if (attr == EFI_VARIABLE_NON_VOLATILE) {
|
||||||
s += sprintf(s, "nv");
|
s += sprintf(s, "nv");
|
||||||
|
@ -1084,12 +1035,12 @@ out:
|
||||||
/* update VendorKeys */
|
/* update VendorKeys */
|
||||||
if (vendor_keys_modified & efi_vendor_keys) {
|
if (vendor_keys_modified & efi_vendor_keys) {
|
||||||
efi_vendor_keys = 0;
|
efi_vendor_keys = 0;
|
||||||
ret = efi_set_variable_common(
|
ret = efi_set_variable_int(
|
||||||
L"VendorKeys",
|
L"VendorKeys",
|
||||||
&efi_global_variable_guid,
|
&efi_global_variable_guid,
|
||||||
EFI_VARIABLE_BOOTSERVICE_ACCESS
|
EFI_VARIABLE_BOOTSERVICE_ACCESS
|
||||||
| EFI_VARIABLE_RUNTIME_ACCESS
|
| EFI_VARIABLE_RUNTIME_ACCESS
|
||||||
| READ_ONLY,
|
| EFI_VARIABLE_READ_ONLY,
|
||||||
sizeof(efi_vendor_keys),
|
sizeof(efi_vendor_keys),
|
||||||
&efi_vendor_keys,
|
&efi_vendor_keys,
|
||||||
false);
|
false);
|
||||||
|
@ -1106,36 +1057,6 @@ err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* efi_set_variable() - set value of a UEFI variable
|
|
||||||
*
|
|
||||||
* This function implements the SetVariable runtime service.
|
|
||||||
*
|
|
||||||
* See the Unified Extensible Firmware Interface (UEFI) specification for
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* @variable_name: name of the variable
|
|
||||||
* @vendor: vendor GUID
|
|
||||||
* @attributes: attributes of the variable
|
|
||||||
* @data_size: size of the buffer with the variable value
|
|
||||||
* @data: buffer with the variable value
|
|
||||||
* Return: status code
|
|
||||||
*/
|
|
||||||
efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
|
|
||||||
const efi_guid_t *vendor, u32 attributes,
|
|
||||||
efi_uintn_t data_size, const void *data)
|
|
||||||
{
|
|
||||||
EFI_ENTRY("\"%ls\" %pUl %x %zu %p", variable_name, vendor, attributes,
|
|
||||||
data_size, data);
|
|
||||||
|
|
||||||
/* READ_ONLY bit is not part of API */
|
|
||||||
attributes &= ~(u32)READ_ONLY;
|
|
||||||
|
|
||||||
return EFI_EXIT(efi_set_variable_common(variable_name, vendor,
|
|
||||||
attributes, data_size, data,
|
|
||||||
true));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* efi_query_variable_info() - get information about EFI variables
|
* efi_query_variable_info() - get information about EFI variables
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <efi.h>
|
#include <efi.h>
|
||||||
#include <efi_api.h>
|
#include <efi_api.h>
|
||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
|
#include <efi_variable.h>
|
||||||
#include <tee.h>
|
#include <tee.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <mm_communication.h>
|
#include <mm_communication.h>
|
||||||
|
@ -243,24 +244,9 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
efi_status_t efi_get_variable_int(u16 *variable_name, const efi_guid_t *vendor,
|
||||||
* efi_get_variable() - retrieve value of a UEFI variable
|
u32 *attributes, efi_uintn_t *data_size,
|
||||||
*
|
void *data, u64 *timep)
|
||||||
* This function implements the GetVariable runtime service.
|
|
||||||
*
|
|
||||||
* See the Unified Extensible Firmware Interface (UEFI) specification for
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* @name: name of the variable
|
|
||||||
* @guid: vendor GUID
|
|
||||||
* @attr: attributes of the variable
|
|
||||||
* @data_size: size of the buffer to which the variable value is copied
|
|
||||||
* @data: buffer to which the variable value is copied
|
|
||||||
* Return: status code
|
|
||||||
*/
|
|
||||||
efi_status_t EFIAPI efi_get_variable(u16 *name, const efi_guid_t *guid,
|
|
||||||
u32 *attr, efi_uintn_t *data_size,
|
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
struct smm_variable_access *var_acc;
|
struct smm_variable_access *var_acc;
|
||||||
efi_uintn_t payload_size;
|
efi_uintn_t payload_size;
|
||||||
|
@ -269,15 +255,13 @@ efi_status_t EFIAPI efi_get_variable(u16 *name, const efi_guid_t *guid,
|
||||||
u8 *comm_buf = NULL;
|
u8 *comm_buf = NULL;
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
|
||||||
EFI_ENTRY("\"%ls\" %pUl %p %p %p", name, guid, attr, data_size, data);
|
if (!variable_name || !vendor || !data_size) {
|
||||||
|
|
||||||
if (!name || !guid || !data_size) {
|
|
||||||
ret = EFI_INVALID_PARAMETER;
|
ret = EFI_INVALID_PARAMETER;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check payload size */
|
/* Check payload size */
|
||||||
name_size = u16_strsize(name);
|
name_size = u16_strsize(variable_name);
|
||||||
if (name_size > max_payload_size - MM_VARIABLE_ACCESS_HEADER_SIZE) {
|
if (name_size > max_payload_size - MM_VARIABLE_ACCESS_HEADER_SIZE) {
|
||||||
ret = EFI_INVALID_PARAMETER;
|
ret = EFI_INVALID_PARAMETER;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -300,11 +284,11 @@ efi_status_t EFIAPI efi_get_variable(u16 *name, const efi_guid_t *guid,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Fill in contents */
|
/* Fill in contents */
|
||||||
guidcpy(&var_acc->guid, guid);
|
guidcpy(&var_acc->guid, vendor);
|
||||||
var_acc->data_size = tmp_dsize;
|
var_acc->data_size = tmp_dsize;
|
||||||
var_acc->name_size = name_size;
|
var_acc->name_size = name_size;
|
||||||
var_acc->attr = attr ? *attr : 0;
|
var_acc->attr = attributes ? *attributes : 0;
|
||||||
memcpy(var_acc->name, name, name_size);
|
memcpy(var_acc->name, variable_name, name_size);
|
||||||
|
|
||||||
/* Communicate */
|
/* Communicate */
|
||||||
ret = mm_communicate(comm_buf, payload_size);
|
ret = mm_communicate(comm_buf, payload_size);
|
||||||
|
@ -315,8 +299,8 @@ efi_status_t EFIAPI efi_get_variable(u16 *name, const efi_guid_t *guid,
|
||||||
if (ret != EFI_SUCCESS)
|
if (ret != EFI_SUCCESS)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (attr)
|
if (attributes)
|
||||||
*attr = var_acc->attr;
|
*attributes = var_acc->attr;
|
||||||
if (data)
|
if (data)
|
||||||
memcpy(data, (u8 *)var_acc->name + var_acc->name_size,
|
memcpy(data, (u8 *)var_acc->name + var_acc->name_size,
|
||||||
var_acc->data_size);
|
var_acc->data_size);
|
||||||
|
@ -325,7 +309,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *name, const efi_guid_t *guid,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(comm_buf);
|
free(comm_buf);
|
||||||
return EFI_EXIT(ret);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -415,24 +399,9 @@ out:
|
||||||
return EFI_EXIT(ret);
|
return EFI_EXIT(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
efi_status_t efi_set_variable_int(u16 *variable_name, const efi_guid_t *vendor,
|
||||||
* efi_set_variable() - set value of a UEFI variable
|
u32 attributes, efi_uintn_t data_size,
|
||||||
*
|
const void *data, bool ro_check)
|
||||||
* This function implements the SetVariable runtime service.
|
|
||||||
*
|
|
||||||
* See the Unified Extensible Firmware Interface (UEFI) specification for
|
|
||||||
* details.
|
|
||||||
*
|
|
||||||
* @name: name of the variable
|
|
||||||
* @guid: vendor GUID
|
|
||||||
* @attr: attributes of the variable
|
|
||||||
* @data_size: size of the buffer with the variable value
|
|
||||||
* @data: buffer with the variable value
|
|
||||||
* Return: status code
|
|
||||||
*/
|
|
||||||
efi_status_t EFIAPI efi_set_variable(u16 *name, const efi_guid_t *guid,
|
|
||||||
u32 attr, efi_uintn_t data_size,
|
|
||||||
const void *data)
|
|
||||||
{
|
{
|
||||||
struct smm_variable_access *var_acc;
|
struct smm_variable_access *var_acc;
|
||||||
efi_uintn_t payload_size;
|
efi_uintn_t payload_size;
|
||||||
|
@ -440,9 +409,7 @@ efi_status_t EFIAPI efi_set_variable(u16 *name, const efi_guid_t *guid,
|
||||||
u8 *comm_buf = NULL;
|
u8 *comm_buf = NULL;
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
|
||||||
EFI_ENTRY("\"%ls\" %pUl %x %zu %p", name, guid, attr, data_size, data);
|
if (!variable_name || variable_name[0] == 0 || !vendor) {
|
||||||
|
|
||||||
if (!name || name[0] == 0 || !guid) {
|
|
||||||
ret = EFI_INVALID_PARAMETER;
|
ret = EFI_INVALID_PARAMETER;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -452,7 +419,7 @@ efi_status_t EFIAPI efi_set_variable(u16 *name, const efi_guid_t *guid,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check payload size */
|
/* Check payload size */
|
||||||
name_size = u16_strsize(name);
|
name_size = u16_strsize(variable_name);
|
||||||
payload_size = MM_VARIABLE_ACCESS_HEADER_SIZE + name_size + data_size;
|
payload_size = MM_VARIABLE_ACCESS_HEADER_SIZE + name_size + data_size;
|
||||||
if (payload_size > max_payload_size) {
|
if (payload_size > max_payload_size) {
|
||||||
ret = EFI_INVALID_PARAMETER;
|
ret = EFI_INVALID_PARAMETER;
|
||||||
|
@ -466,11 +433,11 @@ efi_status_t EFIAPI efi_set_variable(u16 *name, const efi_guid_t *guid,
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Fill in contents */
|
/* Fill in contents */
|
||||||
guidcpy(&var_acc->guid, guid);
|
guidcpy(&var_acc->guid, vendor);
|
||||||
var_acc->data_size = data_size;
|
var_acc->data_size = data_size;
|
||||||
var_acc->name_size = name_size;
|
var_acc->name_size = name_size;
|
||||||
var_acc->attr = attr;
|
var_acc->attr = attributes;
|
||||||
memcpy(var_acc->name, name, name_size);
|
memcpy(var_acc->name, variable_name, name_size);
|
||||||
memcpy((u8 *)var_acc->name + name_size, data, data_size);
|
memcpy((u8 *)var_acc->name + name_size, data, data_size);
|
||||||
|
|
||||||
/* Communicate */
|
/* Communicate */
|
||||||
|
@ -478,7 +445,7 @@ efi_status_t EFIAPI efi_set_variable(u16 *name, const efi_guid_t *guid,
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(comm_buf);
|
free(comm_buf);
|
||||||
return EFI_EXIT(ret);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue