Pull request for efi-2023-01-rc5
UEFI: * Improve parameter checking in efi_get_next_variable_name_mem() * Fix a bugs in management of security database via the eficonfig command Other: * Allow sound command to play multiple sounds -----BEGIN PGP SIGNATURE----- iQJWBAABCABAFiEEK7wKXt3/btL6/yA+hO4vgnE3U0sFAmOh4MsiHGhlaW5yaWNo LnNjaHVjaGFyZHRAY2Fub25pY2FsLmNvbQAKCRCE7i+CcTdTS6WLEADGtNSMvG+x qNBH+2jZc8PnslzXY3FfugSpk29FOFKj4SHwt3p/Du1VPhw1KHWl5gOYTTw/GizI t7yfHavyttzUuHoCa2uKUTYN6RDTCHUgzpyGaXCuh89ls1xilzq3YxVcQ9RYeKM1 lmNIC9rGmTxsWui5VgczkrBzsp8gBj2hs0C+nqJIP+JPGQT1XlA5KXmECsZn8+fi GRvGuuflSDzszHOdRClzrtWNt6kLTpNu8D6UormIrTGrHSdDBwO9QFXOyt9qOnA+ /aboHSd5Oc5BApatTUtRwGoxm0Jm7hujA1EhX6wDsILE/+zMXjmsXS/mbRegYFXY Xzu/Wif4ARexECMe0zxHPHf+VA8QYi9QmELzic8Xen5WzHSRBVQd8BtLK/1ItYDT LrgPtoyY5eWd3gcjlhgimPPUEqsK45aYXftsv7NcH8K64Yj7UolJL1fcJm8tMkHt 0ziiO4ZKZjJkJc4c4XUkWQadCnjqDciJkWfAp922PjoV2jBbf7EtNaynUnsiM/R8 C4oZ7bD1m5gVFLvDsJ9OBy6qHdwRJTn/ETG5H8BlIJ60I9ZZxT4VoUqit+1HQjLx zvH98T8OM/N6d/+Q1fJvKg1QIQQxKHnExYBUBn/WxbeWupVe6K77C7TRE7HTz0tO A+VslTXg5i2XB1SfFrvvF7EpUtX/kqMOMQ== =d09r -----END PGP SIGNATURE----- Merge tag 'efi-2023-01-rc5' of https://source.denx.de/u-boot/custodians/u-boot-efi Pull request for efi-2023-01-rc5 UEFI: * Improve parameter checking in efi_get_next_variable_name_mem() * Fix a bugs in management of security database via the eficonfig command Other: * Allow sound command to play multiple sounds
This commit is contained in:
commit
1154e965d0
11 changed files with 225 additions and 84 deletions
|
@ -1683,7 +1683,7 @@ static efi_status_t eficonfig_show_boot_selection(unsigned int *selected)
|
|||
u32 i;
|
||||
u16 *bootorder;
|
||||
efi_status_t ret;
|
||||
u16 *var_name16 = NULL, *p;
|
||||
u16 *var_name16 = NULL;
|
||||
efi_uintn_t num, size, buf_size;
|
||||
struct efimenu *efi_menu;
|
||||
struct list_head *pos, *n;
|
||||
|
@ -1718,24 +1718,12 @@ static efi_status_t eficonfig_show_boot_selection(unsigned int *selected)
|
|||
int index;
|
||||
efi_guid_t guid;
|
||||
|
||||
size = buf_size;
|
||||
ret = efi_get_next_variable_name_int(&size, var_name16, &guid);
|
||||
ret = efi_next_variable_name(&buf_size, &var_name16, &guid);
|
||||
if (ret == EFI_NOT_FOUND)
|
||||
break;
|
||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||
buf_size = size;
|
||||
p = realloc(var_name16, buf_size);
|
||||
if (!p) {
|
||||
free(var_name16);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
var_name16 = p;
|
||||
ret = efi_get_next_variable_name_int(&size, var_name16, &guid);
|
||||
}
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(var_name16);
|
||||
return ret;
|
||||
}
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
if (efi_varname_is_load_option(var_name16, &index)) {
|
||||
/* If the index is included in the BootOrder, skip it */
|
||||
if (search_bootorder(bootorder, num, index, NULL))
|
||||
|
@ -2026,7 +2014,7 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
|
|||
u32 i;
|
||||
char *title;
|
||||
efi_status_t ret;
|
||||
u16 *var_name16 = NULL, *p;
|
||||
u16 *var_name16 = NULL;
|
||||
efi_uintn_t size, buf_size;
|
||||
|
||||
/* list the load option in the order of BootOrder variable */
|
||||
|
@ -2054,19 +2042,9 @@ static efi_status_t eficonfig_create_change_boot_order_entry(struct efimenu *efi
|
|||
break;
|
||||
|
||||
size = buf_size;
|
||||
ret = efi_get_next_variable_name_int(&size, var_name16, &guid);
|
||||
ret = efi_next_variable_name(&buf_size, &var_name16, &guid);
|
||||
if (ret == EFI_NOT_FOUND)
|
||||
break;
|
||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||
buf_size = size;
|
||||
p = realloc(var_name16, buf_size);
|
||||
if (!p) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
var_name16 = p;
|
||||
ret = efi_get_next_variable_name_int(&size, var_name16, &guid);
|
||||
}
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
|
@ -2332,14 +2310,15 @@ out:
|
|||
efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_option *opt,
|
||||
efi_status_t count)
|
||||
{
|
||||
u32 i;
|
||||
efi_uintn_t size;
|
||||
void *load_option;
|
||||
u32 i, list_size = 0;
|
||||
struct efi_load_option lo;
|
||||
u16 *var_name16 = NULL, *p;
|
||||
u16 *var_name16 = NULL;
|
||||
u16 varname[] = u"Boot####";
|
||||
efi_status_t ret = EFI_SUCCESS;
|
||||
efi_uintn_t varname_size, buf_size;
|
||||
u16 *delete_index_list = NULL, *p;
|
||||
efi_uintn_t buf_size;
|
||||
|
||||
buf_size = 128;
|
||||
var_name16 = malloc(buf_size);
|
||||
|
@ -2352,24 +2331,18 @@ efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_op
|
|||
efi_guid_t guid;
|
||||
efi_uintn_t tmp;
|
||||
|
||||
varname_size = buf_size;
|
||||
ret = efi_get_next_variable_name_int(&varname_size, var_name16, &guid);
|
||||
if (ret == EFI_NOT_FOUND)
|
||||
ret = efi_next_variable_name(&buf_size, &var_name16, &guid);
|
||||
if (ret == EFI_NOT_FOUND) {
|
||||
/*
|
||||
* EFI_NOT_FOUND indicates we retrieved all EFI variables.
|
||||
* This should be treated as success.
|
||||
*/
|
||||
ret = EFI_SUCCESS;
|
||||
break;
|
||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||
buf_size = varname_size;
|
||||
p = realloc(var_name16, buf_size);
|
||||
if (!p) {
|
||||
free(var_name16);
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
var_name16 = p;
|
||||
ret = efi_get_next_variable_name_int(&varname_size, var_name16, &guid);
|
||||
}
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(var_name16);
|
||||
return ret;
|
||||
}
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
if (!efi_varname_is_load_option(var_name16, &index))
|
||||
continue;
|
||||
|
||||
|
@ -2383,8 +2356,8 @@ efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_op
|
|||
if (ret != EFI_SUCCESS)
|
||||
goto next;
|
||||
|
||||
if (size >= sizeof(efi_guid_bootmenu_auto_generated)) {
|
||||
if (guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated) == 0) {
|
||||
if (size >= sizeof(efi_guid_bootmenu_auto_generated) &&
|
||||
!guidcmp(lo.optional_data, &efi_guid_bootmenu_auto_generated)) {
|
||||
for (i = 0; i < count; i++) {
|
||||
if (opt[i].size == tmp &&
|
||||
memcmp(opt[i].lo, load_option, tmp) == 0) {
|
||||
|
@ -2393,20 +2366,37 @@ efi_status_t eficonfig_delete_invalid_boot_option(struct eficonfig_media_boot_op
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The entire list of variables must be retrieved by
|
||||
* efi_get_next_variable_name_int() before deleting the invalid
|
||||
* boot option, just save the index here.
|
||||
*/
|
||||
if (i == count) {
|
||||
ret = delete_boot_option(i);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
free(load_option);
|
||||
p = realloc(delete_index_list, sizeof(u32) *
|
||||
(list_size + 1));
|
||||
if (!p) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
delete_index_list = p;
|
||||
delete_index_list[list_size++] = index;
|
||||
}
|
||||
}
|
||||
next:
|
||||
free(load_option);
|
||||
}
|
||||
|
||||
/* delete all invalid boot options */
|
||||
for (i = 0; i < list_size; i++) {
|
||||
ret = delete_boot_option(delete_index_list[i]);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
free(var_name16);
|
||||
free(delete_index_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,28 @@ static bool file_have_auth_header(void *buf, efi_uintn_t size)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* file_is_null_key() - check the file is an authenticated and signed null key
|
||||
*
|
||||
* @auth: pointer to the file
|
||||
* @size: file size
|
||||
* @null_key: pointer to store the result
|
||||
* Return: status code
|
||||
*/
|
||||
static efi_status_t file_is_null_key(struct efi_variable_authentication_2 *auth,
|
||||
efi_uintn_t size, bool *null_key)
|
||||
{
|
||||
efi_uintn_t auth_size =
|
||||
sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength;
|
||||
|
||||
if (size < auth_size)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
*null_key = (size == auth_size);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* eficonfig_process_enroll_key() - enroll key into signature database
|
||||
*
|
||||
|
@ -84,6 +106,7 @@ static efi_status_t eficonfig_process_enroll_key(void *data)
|
|||
char *buf = NULL;
|
||||
efi_uintn_t size;
|
||||
efi_status_t ret;
|
||||
bool null_key = false;
|
||||
struct efi_file_handle *f = NULL;
|
||||
struct efi_device_path *full_dp = NULL;
|
||||
struct eficonfig_select_file_info file_info;
|
||||
|
@ -149,13 +172,24 @@ static efi_status_t eficonfig_process_enroll_key(void *data)
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = file_is_null_key((struct efi_variable_authentication_2 *)buf,
|
||||
size, &null_key);
|
||||
if (ret != EFI_SUCCESS) {
|
||||
eficonfig_print_msg("ERROR! Invalid file format.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
attr = EFI_VARIABLE_NON_VOLATILE |
|
||||
EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
EFI_VARIABLE_RUNTIME_ACCESS |
|
||||
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
|
||||
|
||||
/* PK can enroll only one certificate */
|
||||
if (u16_strcmp(data, u"PK")) {
|
||||
/*
|
||||
* PK can enroll only one certificate.
|
||||
* The signed null key is used to clear KEK, db and dbx.
|
||||
* EFI_VARIABLE_APPEND_WRITE attribute must not be set in these cases.
|
||||
*/
|
||||
if (u16_strcmp(data, u"PK") && !null_key) {
|
||||
efi_uintn_t db_size = 0;
|
||||
|
||||
/* check the variable exists. If exists, add APPEND_WRITE attribute */
|
||||
|
|
41
cmd/sound.c
41
cmd/sound.c
|
@ -39,26 +39,39 @@ static int do_play(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||
int ret = 0;
|
||||
int msec = 1000;
|
||||
int freq = 400;
|
||||
|
||||
if (argc > 1)
|
||||
msec = dectoul(argv[1], NULL);
|
||||
if (argc > 2)
|
||||
freq = dectoul(argv[2], NULL);
|
||||
bool first = true;
|
||||
|
||||
ret = uclass_first_device_err(UCLASS_SOUND, &dev);
|
||||
if (!ret)
|
||||
if (ret)
|
||||
goto err;
|
||||
--argc;
|
||||
++argv;
|
||||
while (argc || first) {
|
||||
first = false;
|
||||
if (argc && *argv[0] != '-') {
|
||||
msec = dectoul(argv[0], NULL);
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
if (argc && *argv[0] != '-') {
|
||||
freq = dectoul(argv[0], NULL);
|
||||
--argc;
|
||||
++argv;
|
||||
}
|
||||
ret = sound_beep(dev, msec, freq);
|
||||
if (ret) {
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
printf("Sound device failed to play (err=%d)\n", ret);
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cmd_tbl cmd_sound_sub[] = {
|
||||
U_BOOT_CMD_MKENT(init, 0, 1, do_init, "", ""),
|
||||
U_BOOT_CMD_MKENT(play, 2, 1, do_play, "", ""),
|
||||
U_BOOT_CMD_MKENT(play, INT_MAX, 1, do_play, "", ""),
|
||||
};
|
||||
|
||||
/* process sound command */
|
||||
|
@ -83,8 +96,10 @@ static int do_sound(struct cmd_tbl *cmdtp, int flag, int argc,
|
|||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
sound, 4, 1, do_sound,
|
||||
sound, INT_MAX, 1, do_sound,
|
||||
"sound sub-system",
|
||||
"init - initialise the sound driver\n"
|
||||
"sound play [len [freq]] - play a sound for len ms at freq Hz\n"
|
||||
"sound play [[[-q|-s] len [freq]] ...] - play sounds\n"
|
||||
" len - duration in ms\n"
|
||||
" freq - frequency in Hz\n"
|
||||
);
|
||||
|
|
|
@ -78,7 +78,7 @@ variable and how to specify a vendor GUID:
|
|||
=>
|
||||
|
||||
Configuration
|
||||
=============
|
||||
-------------
|
||||
|
||||
UEFI variables are only supported if CONFIG_CMD_NVEDIT_EFI=y. The value of UEFI
|
||||
variables can only be displayed if CONFIG_HEXDUMP=y.
|
||||
|
|
|
@ -10,12 +10,12 @@ Synopsis
|
|||
::
|
||||
|
||||
sound init
|
||||
sound play [len [freq]]
|
||||
sound play [[len freq] ...] [len [freq]]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The *sound* command is used to play a beep sound.
|
||||
The *sound* command is used to play one or multiple beep sounds.
|
||||
|
||||
sound init
|
||||
initializes the sound driver.
|
||||
|
@ -30,6 +30,25 @@ len
|
|||
freq
|
||||
frequency of the sound in Hz, defaults to 400 Hz
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Beep at 400 Hz for 1000 ms::
|
||||
|
||||
sound play
|
||||
|
||||
Beep at 400 Hz for 600 ms::
|
||||
|
||||
sound play 600
|
||||
|
||||
Beep at 500 Hz for 600 ms::
|
||||
|
||||
sound play 600 500
|
||||
|
||||
Play melody::
|
||||
|
||||
sound play 500 1047 500 880 500 0 500 1047 500 880 500 0 500 784 500 698 500 784 1000 698
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
|
|
|
@ -708,6 +708,8 @@ int algo_to_len(const char *algo);
|
|||
int efi_link_dev(efi_handle_t handle, struct udevice *dev);
|
||||
int efi_unlink_dev(efi_handle_t handle);
|
||||
bool efi_varname_is_load_option(u16 *var_name16, int *index);
|
||||
efi_status_t efi_next_variable_name(efi_uintn_t *size, u16 **buf,
|
||||
efi_guid_t *guid);
|
||||
|
||||
/**
|
||||
* efi_size_in_pages() - convert size in bytes to size in pages
|
||||
|
|
|
@ -268,7 +268,8 @@ const efi_guid_t *efi_auth_var_get_guid(const u16 *name);
|
|||
* efi_get_next_variable_name_mem() - Runtime common code across efi variable
|
||||
* implementations for GetNextVariable()
|
||||
* from the cached memory copy
|
||||
* @variable_name_size: size of variable_name buffer in byte
|
||||
*
|
||||
* @variable_name_size: size of variable_name buffer in bytes
|
||||
* @variable_name: name of uefi variable's name in u16
|
||||
* @vendor: vendor's guid
|
||||
*
|
||||
|
|
|
@ -223,3 +223,37 @@ bool efi_varname_is_load_option(u16 *var_name16, int *index)
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_next_variable_name() - get next variable name
|
||||
*
|
||||
* This function is a wrapper of efi_get_next_variable_name_int().
|
||||
* If efi_get_next_variable_name_int() returns EFI_BUFFER_TOO_SMALL,
|
||||
* @size and @buf are updated by new buffer size and realloced buffer.
|
||||
*
|
||||
* @size: pointer to the buffer size
|
||||
* @buf: pointer to the buffer
|
||||
* @guid: pointer to the guid
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t efi_next_variable_name(efi_uintn_t *size, u16 **buf, efi_guid_t *guid)
|
||||
{
|
||||
u16 *p;
|
||||
efi_status_t ret;
|
||||
efi_uintn_t buf_size = *size;
|
||||
|
||||
ret = efi_get_next_variable_name_int(&buf_size, *buf, guid);
|
||||
if (ret == EFI_NOT_FOUND)
|
||||
return ret;
|
||||
if (ret == EFI_BUFFER_TOO_SMALL) {
|
||||
p = realloc(*buf, buf_size);
|
||||
if (!p)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
*buf = p;
|
||||
*size = buf_size;
|
||||
ret = efi_get_next_variable_name_int(&buf_size, *buf, guid);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -315,14 +315,14 @@ efi_get_next_variable_name_mem(efi_uintn_t *variable_name_size,
|
|||
u16 *variable_name, efi_guid_t *vendor)
|
||||
{
|
||||
struct efi_var_entry *var;
|
||||
efi_uintn_t old_size;
|
||||
efi_uintn_t len, old_size;
|
||||
u16 *pdata;
|
||||
|
||||
if (!variable_name_size || !variable_name || !vendor)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (u16_strnlen(variable_name, *variable_name_size) ==
|
||||
*variable_name_size)
|
||||
len = *variable_name_size >> 1;
|
||||
if (u16_strnlen(variable_name, len) == len)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (!efi_var_mem_find(vendor, variable_name, &var) && *variable_name)
|
||||
|
|
|
@ -141,6 +141,41 @@ static int execute(void)
|
|||
return EFI_ST_FAILURE;
|
||||
}
|
||||
/* Enumerate variables */
|
||||
|
||||
ret = runtime->get_next_variable_name(NULL, u"efi_st_var1", &guid);
|
||||
if (ret != EFI_INVALID_PARAMETER) {
|
||||
efi_st_error("GetNextVariableName missing parameter check\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
len = 24;
|
||||
ret = runtime->get_next_variable_name(&len, NULL, &guid);
|
||||
if (ret != EFI_INVALID_PARAMETER) {
|
||||
efi_st_error("GetNextVariableName missing parameter check\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
len = 24;
|
||||
ret = runtime->get_next_variable_name(&len, u"efi_st_var1", NULL);
|
||||
if (ret != EFI_INVALID_PARAMETER) {
|
||||
efi_st_error("GetNextVariableName missing parameter check\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
len = 1;
|
||||
ret = runtime->get_next_variable_name(&len, u"", &guid);
|
||||
if (ret != EFI_INVALID_PARAMETER) {
|
||||
efi_st_error("GetNextVariableName missing parameter check\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
len = 16;
|
||||
ret = runtime->get_next_variable_name(&len, u"efi_st_var1", &guid);
|
||||
if (ret != EFI_INVALID_PARAMETER) {
|
||||
efi_st_error("GetNextVariableName missing parameter check\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
|
||||
boottime->set_mem(&guid, 16, 0);
|
||||
*varname = 0;
|
||||
flag = 0;
|
||||
|
|
|
@ -67,6 +67,17 @@ static int unicode_test_u16_strlen(struct unit_test_state *uts)
|
|||
}
|
||||
UNICODE_TEST(unicode_test_u16_strlen);
|
||||
|
||||
static int unicode_test_u16_strnlen(struct unit_test_state *uts)
|
||||
{
|
||||
ut_asserteq(0, u16_strnlen(c1, 0));
|
||||
ut_asserteq(4, u16_strnlen(c1, 4));
|
||||
ut_asserteq(6, u16_strnlen(c1, 6));
|
||||
ut_asserteq(6, u16_strnlen(c1, 7));
|
||||
|
||||
return 0;
|
||||
}
|
||||
UNICODE_TEST(unicode_test_u16_strnlen);
|
||||
|
||||
static int unicode_test_u16_strdup(struct unit_test_state *uts)
|
||||
{
|
||||
u16 *copy = u16_strdup(c4);
|
||||
|
|
Loading…
Reference in a new issue