From 08c51fff30cca0e834a4819a9d9bb684a919fa7e Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Wed, 9 Oct 2019 16:19:52 +0900 Subject: [PATCH 1/7] efi_loader: device_path: check against file path length device_path strcuture has 2 bytes of "length" field, and so file path length should not exceed this limit, 65535. Signed-off-by: AKASHI Takahiro Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_device_path.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 897fc1b2e8..ac5e6f7e14 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -15,6 +15,7 @@ #include #include #include +#include /* U16_MAX */ #ifdef CONFIG_SANDBOX const efi_guid_t efi_guid_host_dev = U_BOOT_HOST_DEV_GUID; @@ -888,13 +889,16 @@ struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, { struct efi_device_path_file_path *fp; void *buf, *start; - unsigned dpsize = 0, fpsize; + size_t dpsize = 0, fpsize; if (desc) dpsize = dp_part_size(desc, part); fpsize = sizeof(struct efi_device_path) + 2 * (utf8_utf16_strlen(path) + 1); + if (fpsize > U16_MAX) + return NULL; + dpsize += fpsize; start = buf = dp_alloc(dpsize + sizeof(END)); @@ -908,7 +912,7 @@ struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, fp = buf; fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH; - fp->dp.length = fpsize; + fp->dp.length = (u16)fpsize; path_to_uefi(fp->str, path); buf += fpsize; @@ -1070,5 +1074,8 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, *file = efi_dp_from_file(((!is_net && device) ? desc : NULL), part, filename); + if (!file) + return EFI_INVALID_PARAMETER; + return EFI_SUCCESS; } From 64f49eb7d0697b73fa271a69832069e591c07acc Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Mon, 7 Oct 2019 14:59:35 +0900 Subject: [PATCH 2/7] fs: export fs_close() fs_close() closes the connection to a file system which opened with either fs_set_blk_dev() or fs_set_dev_with_part(). Many file system functions implicitly call fs_close(), e.g. fs_closedir(), fs_exist(), fs_ln(), fs_ls(), fs_mkdir(), fs_read(), fs_size(), fs_write() and fs_unlink(). So just export it. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- fs/fs.c | 2 +- include/fs.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/fs.c b/fs/fs.c index d8a4ced469..64ba25fea8 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -389,7 +389,7 @@ int fs_set_blk_dev_with_part(struct blk_desc *desc, int part) return -1; } -static void fs_close(void) +void fs_close(void) { struct fstype_info *info = fs_get_info(fs_type); diff --git a/include/fs.h b/include/fs.h index 7601b0343b..5a1244d57f 100644 --- a/include/fs.h +++ b/include/fs.h @@ -37,6 +37,13 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype); */ int fs_set_blk_dev_with_part(struct blk_desc *desc, int part); +/** + * fs_close() - Unset current block device and partition + * + * Should be paired with either fs_set_blk_dev() or fs_set_dev_with_part() + */ +void fs_close(void); + /** * fs_get_type_name() - Get type of current filesystem * From e4bad9f9f0532d2980eed21be07c8799a0f4b818 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 13 Oct 2019 10:26:26 +0200 Subject: [PATCH 3/7] fs: update fs_close() description Provide a more detailed description of fs_close(). Signed-off-by: Heinrich Schuchardt --- include/fs.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/fs.h b/include/fs.h index 5a1244d57f..247e954053 100644 --- a/include/fs.h +++ b/include/fs.h @@ -40,7 +40,12 @@ int fs_set_blk_dev_with_part(struct blk_desc *desc, int part); /** * fs_close() - Unset current block device and partition * - * Should be paired with either fs_set_blk_dev() or fs_set_dev_with_part() + * fs_close() closes the connection to a file system opened with either + * fs_set_blk_dev() or fs_set_dev_with_part(). + * + * Many file functions implicitly call fs_close(), e.g. fs_closedir(), + * fs_exist(), fs_ln(), fs_ls(), fs_mkdir(), fs_read(), fs_size(), fs_write(), + * fs_unlink(). */ void fs_close(void); From 185aed7855573214794b13f20e597d36c6dc5760 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Mon, 7 Oct 2019 14:59:36 +0900 Subject: [PATCH 4/7] fs: clean up around fs_type fs_ls(), fs_mkdir() and fs_unlink() sets fs_type to FS_TYPE_ANY explicitly, but it is redundant as they call fs_close(). So just remove those lines. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- fs/fs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/fs/fs.c b/fs/fs.c index 64ba25fea8..b17b76a46a 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -413,7 +413,6 @@ int fs_ls(const char *dirname) ret = info->ls(dirname); - fs_type = FS_TYPE_ANY; fs_close(); return ret; @@ -597,7 +596,6 @@ int fs_unlink(const char *filename) ret = info->unlink(filename); - fs_type = FS_TYPE_ANY; fs_close(); return ret; @@ -611,7 +609,6 @@ int fs_mkdir(const char *dirname) ret = info->mkdir(dirname); - fs_type = FS_TYPE_ANY; fs_close(); return ret; From b7cd95627baac05b7023b014c802be309be636a0 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Mon, 7 Oct 2019 14:59:37 +0900 Subject: [PATCH 5/7] fs: add fs_get_type() for current filesystem type This function is a variant of fs_get_type_name() and returns a filesystem type with which the current device is associated. We don't want to export fs_type variable directly because we have to take care of it consistently within fs.c. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- fs/fs.c | 13 +++++++++++++ include/fs.h | 10 ++++++++++ 2 files changed, 23 insertions(+) diff --git a/fs/fs.c b/fs/fs.c index b17b76a46a..0c66d60477 100644 --- a/fs/fs.c +++ b/fs/fs.c @@ -307,6 +307,19 @@ static struct fstype_info *fs_get_info(int fstype) return info; } +/** + * fs_get_type() - Get type of current filesystem + * + * Return: filesystem type + * + * Returns filesystem type representing the current filesystem, or + * FS_TYPE_ANY for any unrecognised filesystem. + */ +int fs_get_type(void) +{ + return fs_type; +} + /** * fs_get_type_name() - Get type of current filesystem * diff --git a/include/fs.h b/include/fs.h index 247e954053..742a535b5f 100644 --- a/include/fs.h +++ b/include/fs.h @@ -49,6 +49,16 @@ int fs_set_blk_dev_with_part(struct blk_desc *desc, int part); */ void fs_close(void); +/** + * fs_get_type() - Get type of current filesystem + * + * Return: filesystem type + * + * Returns filesystem type representing the current filesystem, or + * FS_TYPE_ANY for any unrecognised filesystem. + */ +int fs_get_type(void); + /** * fs_get_type_name() - Get type of current filesystem * From 867400677cda0fac4a411f1549fe3a61bb5ed172 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Mon, 7 Oct 2019 14:59:38 +0900 Subject: [PATCH 6/7] efi_loader: disk: install FILE_SYSTEM_PROTOCOL only if available In the current implementation, EFI_SIMPLEFILE_SYSTEM_PROTOCOL is always installed to all the partitions even if some of them may house no file system. With this patch, that protocol will be installed only if any file system exists. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- lib/efi_loader/efi_disk.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 9007a5f77f..861fcaf374 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -262,6 +263,27 @@ efi_fs_from_path(struct efi_device_path *full_path) return handler->protocol_interface; } +/** + * efi_fs_exists() - check if a partition bears a file system + * + * @desc: block device descriptor + * @part: partition number + * Return: 1 if a file system exists on the partition + * 0 otherwise + */ +static int efi_fs_exists(struct blk_desc *desc, int part) +{ + if (fs_set_blk_dev_with_part(desc, part)) + return 0; + + if (fs_get_type() == FS_TYPE_ANY) + return 0; + + fs_close(); + + return 1; +} + /* * Create a handle for a partition or disk * @@ -315,7 +337,7 @@ static efi_status_t efi_disk_add_dev( diskobj->dp); if (ret != EFI_SUCCESS) return ret; - if (part >= 1) { + if (part >= 1 && efi_fs_exists(desc, part)) { diskobj->volume = efi_simple_file_system(desc, part, diskobj->dp); ret = efi_add_protocol(&diskobj->header, From 5cc349bb09eefaf43e250b2c7a8fc5a61c595715 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 13 Oct 2019 11:54:20 +0200 Subject: [PATCH 7/7] efi_loader: enable CONFIG_CMD_NVEDIT_EFI on QEMU To reduce the default image size CONFIG_CMD_NVEDIT_EFI was disabled by default. Re-enable it on the QEMU platforms supporting the UEFI sub-system. Signed-off-by: Heinrich Schuchardt --- configs/qemu-riscv32_defconfig | 1 + configs/qemu-riscv32_smode_defconfig | 1 + configs/qemu-riscv64_defconfig | 1 + configs/qemu-riscv64_smode_defconfig | 1 + configs/qemu-x86_64_defconfig | 1 + configs/qemu-x86_defconfig | 1 + configs/qemu_arm64_defconfig | 1 + configs/qemu_arm_defconfig | 1 + 8 files changed, 8 insertions(+) diff --git a/configs/qemu-riscv32_defconfig b/configs/qemu-riscv32_defconfig index fe09a0da88..231068a8c6 100644 --- a/configs/qemu-riscv32_defconfig +++ b/configs/qemu-riscv32_defconfig @@ -6,5 +6,6 @@ CONFIG_FIT=y CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_MII is not set CONFIG_OF_PRIOR_STAGE=y diff --git a/configs/qemu-riscv32_smode_defconfig b/configs/qemu-riscv32_smode_defconfig index 7103324421..b0451fd9f0 100644 --- a/configs/qemu-riscv32_smode_defconfig +++ b/configs/qemu-riscv32_smode_defconfig @@ -7,5 +7,6 @@ CONFIG_FIT=y CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_MII is not set CONFIG_OF_PRIOR_STAGE=y diff --git a/configs/qemu-riscv64_defconfig b/configs/qemu-riscv64_defconfig index ef84dfded2..6f5297321a 100644 --- a/configs/qemu-riscv64_defconfig +++ b/configs/qemu-riscv64_defconfig @@ -7,5 +7,6 @@ CONFIG_FIT=y CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_MII is not set CONFIG_OF_PRIOR_STAGE=y diff --git a/configs/qemu-riscv64_smode_defconfig b/configs/qemu-riscv64_smode_defconfig index 1c7a2d150c..7e1e5a7791 100644 --- a/configs/qemu-riscv64_smode_defconfig +++ b/configs/qemu-riscv64_smode_defconfig @@ -8,5 +8,6 @@ CONFIG_FIT=y CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_MII is not set CONFIG_OF_PRIOR_STAGE=y diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig index 05ff001da9..a1c383c40d 100644 --- a/configs/qemu-x86_64_defconfig +++ b/configs/qemu-x86_64_defconfig @@ -34,6 +34,7 @@ CONFIG_SPL_PCH_SUPPORT=y CONFIG_SPL_RTC_SUPPORT=y CONFIG_CMD_CPU=y CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_IDE=y CONFIG_CMD_SPI=y diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig index e71b8a0ee1..9ba4f8f4ec 100644 --- a/configs/qemu-x86_defconfig +++ b/configs/qemu-x86_defconfig @@ -19,6 +19,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_LAST_STAGE_INIT=y CONFIG_CMD_CPU=y CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_NVEDIT_EFI=y # CONFIG_CMD_FLASH is not set CONFIG_CMD_IDE=y CONFIG_CMD_SPI=y diff --git a/configs/qemu_arm64_defconfig b/configs/qemu_arm64_defconfig index 7237819909..533195bc05 100644 --- a/configs/qemu_arm64_defconfig +++ b/configs/qemu_arm64_defconfig @@ -9,6 +9,7 @@ CONFIG_PREBOOT="pci enum" # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_PCI=y CONFIG_CMD_USB=y CONFIG_OF_BOARD=y diff --git a/configs/qemu_arm_defconfig b/configs/qemu_arm_defconfig index 7c95892d98..6491a5e29e 100644 --- a/configs/qemu_arm_defconfig +++ b/configs/qemu_arm_defconfig @@ -10,6 +10,7 @@ CONFIG_PREBOOT="pci enum" # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_BOARDINFO is not set CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_NVEDIT_EFI=y CONFIG_CMD_PCI=y CONFIG_CMD_USB=y CONFIG_OF_BOARD=y