Pull request for UEFI sub-system for efi-2021-04-rc2

Bug fixes:
 
 * do not allow creating of files with filenames on FAT file system
 * install UEFI System Partition GUID on ESP handle
 * in dtbdump.efi test tool use GUID to find ESP handle
 
 Documentation:
 
 * man-page for load command
 * describe end of life of plat_auto
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmAcTmoACgkQxIHbvCwF
 GsT0ag/6AjtRtGd8ySYix9lytmDphyztvTTHrd/Bz+UWi64iEIOH6t/RIAPG0yb0
 WJBvTe9eGxbNx5VOx426YtPUGFfzAakMyRaAL5Y4wkQsKgseq3q2sE55wzG4nTiR
 nmweR7TPslSkGtqQQehGGtdMJn//M/alABtTQs5eyjOkJPEc4DzATeksfA64t2Dj
 ijaU4dWbKVHy8spz3xH9cIdF1fvCJGxvSvXCVculN5bfgCf/MJYq6gb2VgXyLL1w
 +6GNklzNKRY8Lk9C4hqq2ktK4dQ4R0qKgqxtihwuSdbZmhV6cScKvmNPCqdYx/1l
 p5ywE067KRm16Hl/41QhKPMVleqn33Td3U4I+CWvO9DPnsH7pY9iRymM6zfRm9+j
 nO4f8++OqG/YXL+oABLkSIZaoYWqGmZd5Nc1bq9sTXthUXHZeC6/V19n0TJYVIV5
 HtIPFJbqn4S4uKjTFxyvudE6OfeW4+HpsY7bQHDRXWY1Kma0fgMYbhFZdUeNyr+6
 N8EFXZ5nKVWqLH9zlAIPOn0AEXzOfvsWad+NU0bILY8f60SqW0AydjvzG8z9CU3e
 vqxx+NxcG26SYscIcANvMI7HxtB6mblBYF2vSqBAkSrQ23Om+dnKkLhHO8pkkNtn
 J4rLpAxEAA1yaqKK/1n67D6pSqvjdWQqOfgL/3E1sqgAGYYOBrc=
 =rQaL
 -----END PGP SIGNATURE-----

Merge tag 'efi-2021-04-rc2' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi

Pull request for UEFI sub-system for efi-2021-04-rc2

Bug fixes:

* do not allow creating of files with filenames on FAT file system
* install UEFI System Partition GUID on ESP handle
* in dtbdump.efi test tool use GUID to find ESP handle

Documentation:

* man-page for load command
* describe end of life of plat_auto
This commit is contained in:
Tom Rini 2021-02-04 17:35:50 -05:00
commit 55ffabec7f
10 changed files with 214 additions and 87 deletions

View File

@ -16,6 +16,7 @@
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <part.h>
#include <search.h>
#include <linux/ctype.h>
@ -502,6 +503,10 @@ static const struct {
"Device-Tree Fixup",
EFI_DT_FIXUP_PROTOCOL_GUID,
},
{
"System Partition",
PARTITION_SYSTEM_GUID
},
/* Configuration table GUIDs */
{
"ACPI table",

View File

@ -725,7 +725,7 @@ The steps are:
2. If plat_auto is non-zero, then the platform data space
is allocated. This is only useful for device tree operation, since
otherwise you would have to specific the platform data in the
otherwise you would have to specify the platform data in the
U_BOOT_DRVINFO() declaration. The space is allocated for the device and
zeroed. It will be accessible as dev->plat.
@ -861,8 +861,8 @@ remove it. This performs the probe steps in reverse:
be dynamically allocated, and thus needs to be deallocated during the
remove() method, either:
- if the plat_auto is non-zero, the deallocation
happens automatically within the driver model core; or
- if the plat_auto is non-zero, the deallocation happens automatically
within the driver model core in the unbind stage; or
- when plat_auto is 0, both the allocation (in probe()
or preferably of_to_plat()) and the deallocation in remove()

View File

@ -61,8 +61,3 @@ Examples
pc = 0x56076dd1a0f9, pc_reloc = 0x540f9
resetting ...
Return value
------------
The return value $? is always set to 0 (true).

View File

@ -23,6 +23,7 @@ Shell commands
exit
false
for
load
loady
mbr
pstore

74
doc/usage/load.rst Normal file
View File

@ -0,0 +1,74 @@
.. SPDX-License-Identifier: GPL-2.0+:
load command
============
Synopsis
--------
::
load <interface> [<dev[:part]> [<addr> [<filename> [bytes [pos]]]]]
Description
-----------
The load command is used to read a file from a filesystem into memory.
The number of transferred bytes is saved in the environment variable filesize.
The load address is saved in the environment variable fileaddr.
interface
interface for accessing the block device (mmc, sata, scsi, usb, ....)
dev
device number
part
partition number, defaults to 0 (whole device)
addr
load address, defaults to environment variable loadaddr or if loadaddr is
not set to configuration variable CONFIG_SYS_LOAD_ADDR
filename
path to file, defaults to environment variable bootfile
bytes
maximum number of bytes to load
pos
number of bytes to skip
addr, bytes, pos are hexadecimal numbers.
Example
-------
::
=> load mmc 0:1 ${kernel_addr_r} snp.efi
149280 bytes read in 11 ms (12.9 MiB/s)
=>
=> load mmc 0:1 ${kernel_addr_r} snp.efi 1000000
149280 bytes read in 9 ms (15.8 MiB/s)
=>
=> load mmc 0:1 ${kernel_addr_r} snp.efi 1000000 100
149024 bytes read in 10 ms (14.2 MiB/s)
=>
=> load mmc 0:1 ${kernel_addr_r} snp.efi 10
16 bytes read in 1 ms (15.6 KiB/s)
=>
Configuration
-------------
The load command is only available if CONFIG_CMD_FS_GENERIC=y.
Return value
------------
The return value $? is set to 0 (true) if the file was successfully loaded
even if the number of bytes is less then the specified length.
If an error occurs, the return value $? is set to 1 (false).

View File

@ -1237,12 +1237,38 @@ again:
}
*last_slash_cont = '\0';
*basename = last_slash_cont + 1;
filename = last_slash_cont + 1;
} else {
*dirname = "/"; /* root by default */
*basename = filename;
}
/*
* The FAT32 File System Specification v1.03 requires leading and
* trailing spaces as well as trailing periods to be ignored.
*/
for (; *filename == ' '; ++filename)
;
/* Keep special entries '.' and '..' */
if (filename[0] == '.' &&
(!filename[1] || (filename[1] == '.' && !filename[2])))
goto done;
/* Remove trailing periods and spaces */
for (p = filename + strlen(filename) - 1; p >= filename; --p) {
switch (*p) {
case ' ':
case '.':
*p = 0;
break;
default:
goto done;
}
}
done:
*basename = filename;
return 0;
}
@ -1259,8 +1285,10 @@ again:
static int normalize_longname(char *l_filename, const char *filename)
{
const char *p, illegal[] = "<>:\"/\\|?*";
size_t len;
if (strlen(filename) >= VFAT_MAXLEN_BYTES)
len = strlen(filename);
if (!len || len >= VFAT_MAXLEN_BYTES || filename[len - 1] == '.')
return -1;
for (p = filename; *p; ++p) {
@ -1299,9 +1327,8 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
goto exit;
}
filename = basename;
if (normalize_longname(l_filename, filename)) {
printf("FAT: illegal filename (%s)\n", filename);
if (normalize_longname(l_filename, basename)) {
printf("FAT: illegal filename (%s)\n", basename);
ret = -EINVAL;
goto exit;
}
@ -1349,15 +1376,6 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
char shortname[SHORT_NAME_SIZE];
int ndent;
if (itr->is_root) {
/* root dir cannot have "." or ".." */
if (!strcmp(l_filename, ".") ||
!strcmp(l_filename, "..")) {
ret = -EINVAL;
goto exit;
}
}
if (pos) {
/* No hole allowed */
ret = -EINVAL;
@ -1365,7 +1383,7 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
}
/* Check if long name is needed */
ndent = set_name(itr, filename, shortname);
ndent = set_name(itr, basename, shortname);
if (ndent < 0) {
ret = ndent;
goto exit;
@ -1375,7 +1393,7 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
goto exit;
if (ndent > 1) {
/* Set long name entries */
ret = fill_dir_slot(itr, filename, shortname);
ret = fill_dir_slot(itr, basename, shortname);
if (ret)
goto exit;
}
@ -1611,31 +1629,31 @@ exit:
return ret;
}
int fat_mkdir(const char *new_dirname)
int fat_mkdir(const char *dirname)
{
dir_entry *retdent;
fsdata datablock = { .fatbuf = NULL, };
fsdata *mydata = &datablock;
fat_itr *itr = NULL;
char *dirname_copy, *parent, *dirname;
char *dirname_copy, *parent, *basename;
char l_dirname[VFAT_MAXLEN_BYTES];
int ret = -1;
loff_t actwrite;
unsigned int bytesperclust;
dir_entry *dotdent = NULL;
dirname_copy = strdup(new_dirname);
dirname_copy = strdup(dirname);
if (!dirname_copy)
goto exit;
split_filename(dirname_copy, &parent, &dirname);
if (!strlen(dirname)) {
split_filename(dirname_copy, &parent, &basename);
if (!strlen(basename)) {
ret = -EINVAL;
goto exit;
}
if (normalize_longname(l_dirname, dirname)) {
printf("FAT: illegal filename (%s)\n", dirname);
if (normalize_longname(l_dirname, basename)) {
printf("FAT: illegal filename (%s)\n", basename);
ret = -EINVAL;
goto exit;
}
@ -1678,7 +1696,7 @@ int fat_mkdir(const char *new_dirname)
}
/* Check if long name is needed */
ndent = set_name(itr, dirname, shortname);
ndent = set_name(itr, basename, shortname);
if (ndent < 0) {
ret = ndent;
goto exit;
@ -1688,7 +1706,7 @@ int fat_mkdir(const char *new_dirname)
goto exit;
if (ndent > 1) {
/* Set long name entries */
ret = fill_dir_slot(itr, dirname, shortname);
ret = fill_dir_slot(itr, basename, shortname);
if (ret)
goto exit;
}

View File

@ -244,6 +244,21 @@ static char *dp_media(char *s, struct efi_device_path *dp)
cddp->partition_start, cddp->partition_size);
break;
}
case DEVICE_PATH_SUB_TYPE_VENDOR_PATH: {
int i, n;
struct efi_device_path_vendor *vdp =
(struct efi_device_path_vendor *)dp;
s += sprintf(s, "VenMedia(%pUl", &vdp->guid);
n = (int)vdp->dp.length - sizeof(struct efi_device_path_vendor);
if (n > 0) {
s += sprintf(s, ",");
for (i = 0; i < n; ++i)
s += sprintf(s, "%02x", vdp->vendor_data[i]);
}
s += sprintf(s, ")");
break;
}
case DEVICE_PATH_SUB_TYPE_FILE_PATH: {
struct efi_device_path_file_path *fp =
(struct efi_device_path_file_path *)dp;

View File

@ -19,6 +19,7 @@
struct efi_system_partition efi_system_partition;
const efi_guid_t efi_block_io_guid = EFI_BLOCK_IO_PROTOCOL_GUID;
const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
/**
* struct efi_disk_obj - EFI disk object
@ -362,6 +363,7 @@ static efi_status_t efi_disk_add_dev(
{
struct efi_disk_obj *diskobj;
struct efi_object *handle;
const efi_guid_t *guid = NULL;
efi_status_t ret;
/* Don't add empty devices */
@ -400,6 +402,8 @@ static efi_status_t efi_disk_add_dev(
efi_free_pool(node);
diskobj->offset = part_info->start;
diskobj->media.last_block = part_info->size - 1;
if (part_info->bootable & PART_EFI_SYSTEM_PARTITION)
guid = &efi_system_partition_guid;
} else {
diskobj->dp = efi_dp_from_part(desc, part);
diskobj->offset = 0;
@ -417,7 +421,8 @@ static efi_status_t efi_disk_add_dev(
handle = &diskobj->header;
ret = EFI_CALL(efi_install_multiple_protocol_interfaces(
&handle, &efi_guid_device_path, diskobj->dp,
&efi_block_io_guid, &diskobj->ops, NULL));
&efi_block_io_guid, &diskobj->ops,
guid, NULL, NULL));
if (ret != EFI_SUCCESS)
return ret;
@ -467,13 +472,7 @@ static efi_status_t efi_disk_add_dev(
/* Store first EFI system partition */
if (part && !efi_system_partition.if_type) {
int r;
struct disk_partition info;
r = part_get_info(desc, part, &info);
if (r)
return EFI_DEVICE_ERROR;
if (info.bootable & PART_EFI_SYSTEM_PARTITION) {
if (part_info->bootable & PART_EFI_SYSTEM_PARTITION) {
efi_system_partition.if_type = desc->if_type;
efi_system_partition.devnum = desc->devnum;
efi_system_partition.part = part;

View File

@ -110,6 +110,7 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb,
{
efi_status_t ret;
size_t required_size;
size_t total_size;
bootm_headers_t img = { 0 };
EFI_ENTRY("%p, %p, %p, %d", this, dtb, buffer_size, flags);
@ -124,20 +125,20 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb,
goto out;
}
if (flags & EFI_DT_APPLY_FIXUPS) {
/* Check size */
required_size = fdt_off_dt_strings(dtb) +
fdt_size_dt_strings(dtb) +
0x3000;
} else {
required_size = fdt_totalsize(dtb);
}
if (required_size > *buffer_size) {
*buffer_size = required_size;
ret = EFI_BUFFER_TOO_SMALL;
goto out;
}
fdt_set_totalsize(dtb, *buffer_size);
total_size = fdt_totalsize(dtb);
if (required_size < total_size)
required_size = total_size;
if (required_size > *buffer_size) {
*buffer_size = required_size;
ret = EFI_BUFFER_TOO_SMALL;
goto out;
}
if (flags & EFI_DT_APPLY_FIXUPS) {
fdt_set_totalsize(dtb, *buffer_size);
if (image_setup_libfdt(&img, dtb, 0, NULL)) {
log_err("failed to process device tree\n");
ret = EFI_INVALID_PARAMETER;
@ -147,10 +148,10 @@ efi_dt_fixup(struct efi_dt_fixup_protocol *this, void *dtb,
if (flags & EFI_DT_RESERVE_MEMORY)
efi_carve_out_dt_rsv(dtb);
if (EFI_DT_INSTALL_TABLE) {
if (flags & EFI_DT_INSTALL_TABLE) {
ret = efi_install_configuration_table(&efi_guid_fdt, dtb);
if (ret != EFI_SUCCESS) {
log_err("ERROR: failed to install device tree\n");
log_err("failed to install device tree\n");
goto out;
}
}

View File

@ -9,6 +9,7 @@
#include <common.h>
#include <efi_api.h>
#include <efi_dt_fixup.h>
#include <part.h>
#define BUFFER_SIZE 64
#define ESC 0x17
@ -27,6 +28,7 @@ static efi_handle_t handle;
static struct efi_system_table *systable;
static const efi_guid_t efi_dt_fixup_protocol_guid = EFI_DT_FIXUP_PROTOCOL_GUID;
static const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
static const efi_guid_t efi_system_partition_guid = PARTITION_SYSTEM_GUID;
/**
* print() - print string
@ -230,6 +232,52 @@ void do_help(void)
error(L"exit - exit the shell\r\n");
}
/**
* open_file_system() - open simple file system protocol
*
* file_system: interface of the simple file system protocol
* Return: status code
*/
static efi_status_t
open_file_system(struct efi_simple_file_system_protocol **file_system)
{
struct efi_loaded_image *loaded_image;
efi_status_t ret;
efi_handle_t *handle_buffer = NULL;
efi_uintn_t count;
ret = bs->open_protocol(handle, &loaded_image_guid,
(void **)&loaded_image, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Loaded image protocol not found\r\n");
return ret;
}
/* Open the simple file system protocol on the same partition */
ret = bs->open_protocol(loaded_image->device_handle,
&guid_simple_file_system_protocol,
(void **)file_system, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret == EFI_SUCCESS)
return ret;
/* Open the simple file system protocol on the UEFI system partition */
ret = bs->locate_handle_buffer(BY_PROTOCOL, &efi_system_partition_guid,
NULL, &count, &handle_buffer);
if (ret == EFI_SUCCESS && handle_buffer)
ret = bs->open_protocol(handle_buffer[0],
&guid_simple_file_system_protocol,
(void **)file_system, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS)
error(L"Failed to open simple file system protocol\r\n");
if (handle)
bs->free_pool(handle_buffer);
return ret;
}
/**
* do_load() - load and install device-tree
*
@ -239,7 +287,6 @@ void do_help(void)
efi_status_t do_load(u16 *filename)
{
struct efi_dt_fixup_protocol *dt_fixup_prot;
struct efi_loaded_image *loaded_image;
struct efi_simple_file_system_protocol *file_system;
struct efi_file_handle *root = NULL, *file = NULL;
u64 addr = 0;
@ -258,22 +305,9 @@ efi_status_t do_load(u16 *filename)
filename = skip_whitespace(filename);
ret = bs->open_protocol(handle, &loaded_image_guid,
(void **)&loaded_image, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Loaded image protocol not found\r\n");
return ret;
}
/* Open the simple file system protocol */
ret = bs->open_protocol(loaded_image->device_handle,
&guid_simple_file_system_protocol,
(void **)&file_system, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Failed to open simple file system protocol\r\n");
ret = open_file_system(&file_system);
if (ret != EFI_SUCCESS)
goto out;
}
/* Open volume */
ret = file_system->open_volume(file_system, &root);
@ -389,7 +423,6 @@ out:
*/
efi_status_t do_save(u16 *filename)
{
struct efi_loaded_image *loaded_image;
struct efi_simple_file_system_protocol *file_system;
efi_uintn_t dtb_size;
struct efi_file_handle *root, *file;
@ -409,23 +442,9 @@ efi_status_t do_save(u16 *filename)
filename = skip_whitespace(filename);
ret = bs->open_protocol(handle, &loaded_image_guid,
(void **)&loaded_image, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Loaded image protocol not found\r\n");
ret = open_file_system(&file_system);
if (ret != EFI_SUCCESS)
return ret;
}
/* Open the simple file system protocol */
ret = bs->open_protocol(loaded_image->device_handle,
&guid_simple_file_system_protocol,
(void **)&file_system, NULL, NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
if (ret != EFI_SUCCESS) {
error(L"Failed to open simple file system protocol\r\n");
return ret;
}
/* Open volume */
ret = file_system->open_volume(file_system, &root);