summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2022-12-20 12:50:38 -0500
committerTom Rini <[email protected]>2022-12-20 12:50:48 -0500
commit1154e965d0bd16cf438afdaa4118e1455fd71a44 (patch)
tree9d862e44a520ea50e1cb8b15fd1ffd5675c5a018 /cmd
parent566bc672a7474f4bf67b29514121ed41db21ed71 (diff)
parentad50ca5019ae2b4f6ad5ffb4d62808b640f7b8aa (diff)
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
Diffstat (limited to 'cmd')
-rw-r--r--cmd/eficonfig.c114
-rw-r--r--cmd/eficonfig_sbkey.c38
-rw-r--r--cmd/sound.c41
3 files changed, 116 insertions, 77 deletions
diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
index 394ae67ccea..ce7175a5666 100644
--- a/cmd/eficonfig.c
+++ b/cmd/eficonfig.c
@@ -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,30 +2356,47 @@ 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) {
- for (i = 0; i < count; i++) {
- if (opt[i].size == tmp &&
- memcmp(opt[i].lo, load_option, tmp) == 0) {
- opt[i].exist = true;
- break;
- }
+ 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) {
+ opt[i].exist = true;
+ break;
}
+ }
- if (i == count) {
- ret = delete_boot_option(i);
- if (ret != EFI_SUCCESS) {
- free(load_option);
- goto out;
- }
+ /*
+ * 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) {
+ 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;
}
diff --git a/cmd/eficonfig_sbkey.c b/cmd/eficonfig_sbkey.c
index 6e0bebf1d41..ed39aab0817 100644
--- a/cmd/eficonfig_sbkey.c
+++ b/cmd/eficonfig_sbkey.c
@@ -73,6 +73,28 @@ static bool file_have_auth_header(void *buf, efi_uintn_t size)
}
/**
+ * 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
*
* @data: pointer to the data for each entry
@@ -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 */
diff --git a/cmd/sound.c b/cmd/sound.c
index 20ac3f758e3..cef71be5e34 100644
--- a/cmd/sound.c
+++ b/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) {
- printf("Sound device failed to play (err=%d)\n", ret);
- return CMD_RET_FAILURE;
+ if (ret)
+ goto err;
}
-
return 0;
+
+err:
+ printf("Sound device failed to play (err=%d)\n", ret);
+ return CMD_RET_FAILURE;
}
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"
);