Pull request for UEFI sub-system for efi-2021-04-rc1-3

Bug fixes for UEFI sub-system:
 
 * correct value of  EFI_BLOCK_IO_PROTOCOL.Media.LastBlock
 * correct GUID when closing of EFI_LOAD_FILE_PROTOCOL
 * error handling in mkeficapsule tool
 
 Bug fixes for FAT file system:
 
 * consistent error handling for flush dir()
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAmAMM8AACgkQxIHbvCwF
 GsTryQ//Q1e8uAw+M78k8T1Mhkiz734WPfVooCyn+d+WYeTLQKNPN2AjVNMa7dYq
 HpROrQ++4Q9fdBIRyDe0KAfoJ2TWFa3UARxBTXEvjC9RrMQBgrgeBZTxiFsaLrL2
 GI3a9qVioHfBqrWdwKjlQLD79rL4ZQW0OfG7JgnPIBQvM/12e+C4kxQ9JmBZIxVc
 0ENbr4CttX4Tbp70XvtjXDnrqpv4vv+nv6hDw5rmh8pb37OdCnVeYPuAxqHhpqHP
 KrSF/N/Xmi4XRVxu3UrVJX5g/A2+aM69D8vy3tcl7Es5gs/VoqCOyx4+1/GaalNa
 7cLEfb2DECDy6rIyvCeoFYrRNcT9m6d8COAbGDOonGbRtHFV2WsS/1J1ZkMG18pc
 O6gJcNdMYyK9B9Jt4FmsHIWzz8FFKw+4ro9gKfIm8bMIgPZ1txGkn7/4LRxj/VxS
 qNWLiYEnIJtAPV1aiDIxRINh4icewwM8tteBfJB5AlPVodWmWmc3J+RsbIU0yQcK
 T7pqj8zX4eL0SSMMZYir9pFhqZcr2SQP9V8fuPLdeILFF7V+M83dRlb8kLf0sb3f
 CWC56JDV6iVWkPDpYe0ZolqMUW01FdxDIaa1X3dBvn5PWbl4CubxudPCWtLK69FM
 azoIgrcBaFu3KgYA9sZF8/BXEJ1viYKwe8Qg9Vkl2fBAX8+75jA=
 =S6wx
 -----END PGP SIGNATURE-----

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

Pull request for UEFI sub-system for efi-2021-04-rc1-3

Bug fixes for UEFI sub-system:

* correct value of  EFI_BLOCK_IO_PROTOCOL.Media.LastBlock
* correct GUID when closing of EFI_LOAD_FILE_PROTOCOL
* error handling in mkeficapsule tool

Bug fixes for FAT file system:

* consistent error handling for flush dir()
This commit is contained in:
Tom Rini 2021-01-23 19:07:00 -05:00
commit 69d29fe1c0
8 changed files with 126 additions and 90 deletions

View file

@ -189,14 +189,16 @@ static int do_efi_capsule_res(struct cmd_tbl *cmdtp, int flag,
ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size, NULL));
if (ret == EFI_BUFFER_TOO_SMALL) {
result = malloc(size);
if (!result)
return CMD_RET_FAILURE;
ret = EFI_CALL(RT->get_variable(var_name16, &guid, NULL, &size,
result));
if (ret != EFI_SUCCESS) {
free(result);
printf("Failed to get %ls\n", var_name16);
}
if (ret != EFI_SUCCESS) {
free(result);
printf("Failed to get %ls\n", var_name16);
return CMD_RET_FAILURE;
}
return CMD_RET_FAILURE;
}
printf("Result total size: 0x%x\n", result->variable_total_size);

View file

@ -123,16 +123,16 @@ static void get_name(dir_entry *dirent, char *s_name)
{
char *ptr;
memcpy(s_name, dirent->name, 8);
memcpy(s_name, dirent->nameext.name, 8);
s_name[8] = '\0';
ptr = s_name;
while (*ptr && *ptr != ' ')
ptr++;
if (dirent->lcase & CASE_LOWER_BASE)
downcase(s_name, (unsigned)(ptr - s_name));
if (dirent->ext[0] && dirent->ext[0] != ' ') {
if (dirent->nameext.ext[0] && dirent->nameext.ext[0] != ' ') {
*ptr++ = '.';
memcpy(ptr, dirent->ext, 3);
memcpy(ptr, dirent->nameext.ext, 3);
if (dirent->lcase & CASE_LOWER_EXT)
downcase(ptr, 3);
ptr[3] = '\0';
@ -472,16 +472,15 @@ static int slot2str(dir_slot *slotptr, char *l_name, int *idx)
}
/* Calculate short name checksum */
static __u8 mkcksum(const char name[8], const char ext[3])
static __u8 mkcksum(struct nameext *nameext)
{
int i;
u8 *pos = (void *)nameext;
__u8 ret = 0;
for (i = 0; i < 8; i++)
ret = (((ret & 1) << 7) | ((ret & 0xfe) >> 1)) + name[i];
for (i = 0; i < 3; i++)
ret = (((ret & 1) << 7) | ((ret & 0xfe) >> 1)) + ext[i];
for (i = 0; i < 11; i++)
ret = (((ret & 1) << 7) | ((ret & 0xfe) >> 1)) + pos[i];
return ret;
}
@ -896,7 +895,7 @@ static dir_entry *next_dent(fat_itr *itr)
}
/* have we reached the last valid entry? */
if (itr->dent->name[0] == 0)
if (itr->dent->nameext.name[0] == 0)
return NULL;
return itr->dent;
@ -905,7 +904,7 @@ static dir_entry *next_dent(fat_itr *itr)
static dir_entry *extract_vfat_name(fat_itr *itr)
{
struct dir_entry *dent = itr->dent;
int seqn = itr->dent->name[0] & ~LAST_LONG_ENTRY_MASK;
int seqn = itr->dent->nameext.name[0] & ~LAST_LONG_ENTRY_MASK;
u8 chksum, alias_checksum = ((dir_slot *)dent)->alias_checksum;
int n = 0;
@ -932,18 +931,19 @@ static dir_entry *extract_vfat_name(fat_itr *itr)
* We are now at the short file name entry.
* If it is marked as deleted, just skip it.
*/
if (dent->name[0] == DELETED_FLAG ||
dent->name[0] == aRING)
if (dent->nameext.name[0] == DELETED_FLAG ||
dent->nameext.name[0] == aRING)
return NULL;
itr->l_name[n] = '\0';
chksum = mkcksum(dent->name, dent->ext);
chksum = mkcksum(&dent->nameext);
/* checksum mismatch could mean deleted file, etc.. skip it: */
if (chksum != alias_checksum) {
debug("** chksum=%x, alias_checksum=%x, l_name=%s, s_name=%8s.%3s\n",
chksum, alias_checksum, itr->l_name, dent->name, dent->ext);
chksum, alias_checksum, itr->l_name, dent->nameext.name,
dent->nameext.ext);
return NULL;
}
@ -984,12 +984,12 @@ static int fat_itr_next(fat_itr *itr)
itr->dent_rem = itr->remaining;
itr->dent_start = itr->dent;
itr->dent_clust = itr->clust;
if (dent->name[0] == DELETED_FLAG)
if (dent->nameext.name[0] == DELETED_FLAG)
continue;
if (dent->attr & ATTR_VOLUME) {
if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
(dent->name[0] & LAST_LONG_ENTRY_MASK)) {
(dent->nameext.name[0] & LAST_LONG_ENTRY_MASK)) {
/* long file name */
dent = extract_vfat_name(itr);
/*

View file

@ -275,7 +275,7 @@ static int fat_find_empty_dentries(fat_itr *itr, int count)
log_debug("Not enough directory entries available\n");
return -ENOSPC;
}
switch (itr->dent->name[0]) {
switch (itr->dent->nameext.name[0]) {
case 0x00:
case DELETED_FLAG:
if (!n) {
@ -399,7 +399,7 @@ fill_dir_slot(fat_itr *itr, const char *l_name, const char *shortname)
int idx = 0, ret;
/* Get short file name checksum value */
checksum = mkcksum(shortname, shortname + 8);
checksum = mkcksum((void *)shortname);
do {
memset(slotptr, 0x00, sizeof(dir_slot));
@ -418,8 +418,12 @@ fill_dir_slot(fat_itr *itr, const char *l_name, const char *shortname)
slotptr--;
counter--;
if (itr->remaining == 0)
flush_dir(itr);
if (!itr->remaining) {
/* Write directory table to device */
ret = flush_dir(itr);
if (ret)
return ret;
}
next_dent(itr);
if (!itr->dent)
@ -639,15 +643,23 @@ set_cluster(fsdata *mydata, u32 clustnum, u8 *buffer, u32 size)
buffer, size);
}
static int
flush_dir(fat_itr *itr)
/**
* flush_dir() - flush directory
*
* @itr: directory iterator
* Return: 0 for success, -EIO on error
*/
static int flush_dir(fat_itr *itr)
{
fsdata *mydata = itr->fsdata;
u32 startsect, sect_offset, nsects;
int ret;
if (!itr->is_root || mydata->fatsize == 32)
return set_cluster(mydata, itr->clust, itr->block,
mydata->clust_size * mydata->sect_size);
if (!itr->is_root || mydata->fatsize == 32) {
ret = set_cluster(mydata, itr->clust, itr->block,
mydata->clust_size * mydata->sect_size);
goto out;
}
sect_offset = itr->clust * mydata->clust_size;
startsect = mydata->rootdir_sect + sect_offset;
@ -655,8 +667,14 @@ flush_dir(fat_itr *itr)
nsects = min_t(u32, mydata->clust_size,
mydata->rootdir_size - sect_offset);
return set_sectors(mydata, startsect, itr->block,
nsects * mydata->sect_size);
ret = set_sectors(mydata, startsect, itr->block,
nsects * mydata->sect_size);
out:
if (ret) {
log_err("Error: writing directory entry\n");
return -EIO;
}
return 0;
}
/*
@ -1151,7 +1169,7 @@ static void fill_dentry(fsdata *mydata, dir_entry *dentptr,
dentptr->attr = attr;
memcpy(dentptr->name, shortname, SHORT_NAME_SIZE);
memcpy(&dentptr->nameext, shortname, SHORT_NAME_SIZE);
}
/**
@ -1176,7 +1194,7 @@ static dir_entry *find_directory_entry(fat_itr *itr, char *filename)
if (!match)
continue;
if (itr->dent->name[0] == '\0')
if (itr->dent->nameext.name[0] == '\0')
return NULL;
else
return itr->dent;
@ -1390,10 +1408,6 @@ int file_fat_write_at(const char *filename, loff_t pos, void *buffer,
/* Write directory table to device */
ret = flush_dir(itr);
if (ret) {
printf("Error: writing directory entry\n");
ret = -EIO;
}
exit:
free(filename_copy);
@ -1456,14 +1470,10 @@ static int delete_single_dentry(fat_itr *itr)
struct dir_entry *dent = itr->dent;
memset(dent, 0, sizeof(*dent));
dent->name[0] = DELETED_FLAG;
dent->nameext.name[0] = DELETED_FLAG;
if (!itr->remaining) {
if (flush_dir(itr)) {
printf("error: writing directory entry\n");
return -EIO;
}
}
if (!itr->remaining)
return flush_dir(itr);
return 0;
}
@ -1476,7 +1486,7 @@ static int delete_single_dentry(fat_itr *itr)
static int delete_long_name(fat_itr *itr)
{
struct dir_entry *dent = itr->dent;
int seqn = itr->dent->name[0] & ~LAST_LONG_ENTRY_MASK;
int seqn = itr->dent->nameext.name[0] & ~LAST_LONG_ENTRY_MASK;
while (seqn--) {
int ret;
@ -1521,7 +1531,7 @@ static int delete_dentry_long(fat_itr *itr)
dent = itr->dent_start;
/* Delete long name */
if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
(dent->name[0] & LAST_LONG_ENTRY_MASK)) {
(dent->nameext.name[0] & LAST_LONG_ENTRY_MASK)) {
int ret;
ret = delete_long_name(itr);
@ -1530,12 +1540,7 @@ static int delete_dentry_long(fat_itr *itr)
}
/* Delete short name */
delete_single_dentry(itr);
if (flush_dir(itr)) {
printf("error: writing directory entry\n");
return -EIO;
}
return 0;
return flush_dir(itr);
}
int fat_unlink(const char *filename)
@ -1707,12 +1712,10 @@ int fat_mkdir(const char *new_dirname)
}
memset(dotdent, 0, bytesperclust);
memcpy(dotdent[0].name, ". ", 8);
memcpy(dotdent[0].ext, " ", 3);
memcpy(&dotdent[0].nameext, ". ", 11);
dotdent[0].attr = ATTR_DIR | ATTR_ARCH;
memcpy(dotdent[1].name, ".. ", 8);
memcpy(dotdent[1].ext, " ", 3);
memcpy(&dotdent[1].nameext, ".. ", 11);
dotdent[1].attr = ATTR_DIR | ATTR_ARCH;
if (itr->is_root)
@ -1739,13 +1742,12 @@ int fat_mkdir(const char *new_dirname)
ret = flush_dirty_fat_buffer(mydata);
if (ret) {
printf("Error: flush fat buffer\n");
ret = -EIO;
goto exit;
}
/* Write directory table to device */
ret = flush_dir(itr);
if (ret)
printf("Error: writing directory entry\n");
exit:
free(dirname_copy);

View file

@ -132,8 +132,13 @@ typedef struct volume_info
#define CASE_LOWER_BASE 8 /* base (name) is lower case */
#define CASE_LOWER_EXT 16 /* extension is lower case */
struct nameext {
char name[8];
char ext[3];
};
typedef struct dir_entry {
char name[8],ext[3]; /* Name and extension */
struct nameext nameext; /* Name and extension */
__u8 attr; /* Attribute bits */
__u8 lcase; /* Case for name and ext (CASE_LOWER_x) */
__u8 ctime_ms; /* Creation time, milliseconds */

View file

@ -687,8 +687,15 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
return EFI_INVALID_PARAMETER;
}
/*
* The UEFI specification requires event notification levels to be
* > TPL_APPLICATION and <= TPL_HIGH_LEVEL.
*
* Parameter NotifyTpl should not be checked if it is not used.
*/
if ((type & (EVT_NOTIFY_WAIT | EVT_NOTIFY_SIGNAL)) &&
(!notify_function || is_valid_tpl(notify_tpl) != EFI_SUCCESS))
(!notify_function || is_valid_tpl(notify_tpl) != EFI_SUCCESS ||
notify_tpl == TPL_APPLICATION))
return EFI_INVALID_PARAMETER;
ret = efi_allocate_pool(pool_type, sizeof(struct efi_event),
@ -1990,10 +1997,7 @@ efi_status_t efi_load_image_from_path(bool boot_policy,
if (ret != EFI_SUCCESS)
efi_free_pages(addr, pages);
out:
if (load_file_protocol)
EFI_CALL(efi_close_protocol(device,
&efi_guid_load_file2_protocol,
efi_root, NULL));
EFI_CALL(efi_close_protocol(device, guid, efi_root, NULL));
if (ret == EFI_SUCCESS) {
*buffer = (void *)(uintptr_t)addr;
*size = buffer_size;

View file

@ -764,7 +764,7 @@ static efi_status_t efi_capsule_scan_dir(u16 ***files, unsigned int *num)
goto err;
/* make a list */
tmp_files = malloc(count * sizeof(*files));
tmp_files = malloc(count * sizeof(*tmp_files));
if (!tmp_files) {
ret = EFI_OUT_OF_RESOURCES;
goto err;

View file

@ -343,7 +343,7 @@ static int efi_fs_exists(struct blk_desc *desc, int part)
* @if_typename: interface name for block device
* @desc: internal block device
* @dev_index: device index for block device
* @offset: offset into disk for simple partitions
* @part_info: partition info
* @part: partition
* @disk: pointer to receive the created handle
* Return: disk object
@ -354,7 +354,7 @@ static efi_status_t efi_disk_add_dev(
const char *if_typename,
struct blk_desc *desc,
int dev_index,
lbaint_t offset,
struct disk_partition *part_info,
unsigned int part,
struct efi_disk_obj **disk)
{
@ -374,7 +374,7 @@ static efi_status_t efi_disk_add_dev(
efi_add_handle(&diskobj->header);
/* Fill in object data */
if (part) {
if (part_info) {
struct efi_device_path *node = efi_dp_part_node(desc, part);
struct efi_handler *handler;
void *protocol_interface;
@ -396,8 +396,12 @@ static efi_status_t efi_disk_add_dev(
diskobj->dp = efi_dp_append_node(dp_parent, node);
efi_free_pool(node);
diskobj->offset = part_info->start;
diskobj->media.last_block = part_info->size - 1;
} else {
diskobj->dp = efi_dp_from_part(desc, part);
diskobj->offset = 0;
diskobj->media.last_block = desc->lba - 1;
}
diskobj->part = part;
@ -432,7 +436,6 @@ static efi_status_t efi_disk_add_dev(
diskobj->ops = block_io_disk_template;
diskobj->ifname = if_typename;
diskobj->dev_index = dev_index;
diskobj->offset = offset;
diskobj->desc = desc;
/* Fill in EFI IO Media info (for read/write callbacks) */
@ -445,13 +448,21 @@ static efi_status_t efi_disk_add_dev(
diskobj->media.media_id = 1;
diskobj->media.block_size = desc->blksz;
diskobj->media.io_align = desc->blksz;
diskobj->media.last_block = desc->lba - offset;
if (part)
diskobj->media.logical_partition = 1;
diskobj->ops.media = &diskobj->media;
if (disk)
*disk = diskobj;
EFI_PRINT("BlockIO: part %u, present %d, logical %d, removable %d"
", offset " LBAF ", last_block %llu\n",
diskobj->part,
diskobj->media.media_present,
diskobj->media.logical_partition,
diskobj->media.removable_media,
diskobj->offset,
diskobj->media.last_block);
/* Store first EFI system partition */
if (part && !efi_system_partition.if_type) {
int r;
@ -493,7 +504,6 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
{
int disks = 0;
char devname[32] = { 0 }; /* dp->str is u16[32] long */
struct disk_partition info;
int part;
struct efi_device_path *dp = NULL;
efi_status_t ret;
@ -506,12 +516,14 @@ int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
/* Add devices for each partition */
for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
struct disk_partition info;
if (part_get_info(desc, part, &info))
continue;
snprintf(devname, sizeof(devname), "%s:%d", pdevname,
part);
ret = efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
info.start, part, NULL);
&info, part, NULL);
if (ret != EFI_SUCCESS) {
log_err("Adding partition %s failed\n", pdevname);
continue;
@ -553,7 +565,7 @@ efi_status_t efi_disk_register(void)
/* Add block device for the full device */
log_info("Scanning disk %s...\n", dev->name);
ret = efi_disk_add_dev(NULL, NULL, if_typename,
desc, desc->devnum, 0, 0, &disk);
desc, desc->devnum, NULL, 0, &disk);
if (ret == EFI_NOT_READY) {
log_notice("Disk %s not ready\n", dev->name);
continue;
@ -599,7 +611,7 @@ efi_status_t efi_disk_register(void)
/* Add block device for the full device */
ret = efi_disk_add_dev(NULL, NULL, if_typename, desc,
i, 0, 0, &disk);
i, NULL, 0, &disk);
if (ret == EFI_NOT_READY) {
log_notice("Disk %s not ready\n", devname);
continue;

View file

@ -137,8 +137,8 @@ static int add_public_key(const char *pkey_file, const char *dtb_file,
bool overlay)
{
int ret;
int srcfd = 0;
int destfd = 0;
int srcfd = -1;
int destfd = -1;
void *sptr = NULL;
void *dptr = NULL;
off_t src_size;
@ -150,6 +150,7 @@ static int add_public_key(const char *pkey_file, const char *dtb_file,
if (srcfd == -1) {
fprintf(stderr, "%s: Can't open %s: %s\n",
__func__, pkey_file, strerror(errno));
ret = -1;
goto err;
}
@ -157,6 +158,7 @@ static int add_public_key(const char *pkey_file, const char *dtb_file,
if (ret == -1) {
fprintf(stderr, "%s: Can't stat %s: %s\n",
__func__, pkey_file, strerror(errno));
ret = -1;
goto err;
}
@ -164,9 +166,10 @@ static int add_public_key(const char *pkey_file, const char *dtb_file,
/* mmap the public key esl file */
sptr = mmap(0, src_size, PROT_READ, MAP_SHARED, srcfd, 0);
if ((sptr == MAP_FAILED) || (errno != 0)) {
if (sptr == MAP_FAILED) {
fprintf(stderr, "%s: Failed to mmap %s:%s\n",
__func__, pkey_file, strerror(errno));
ret = -1;
goto err;
}
@ -175,6 +178,7 @@ static int add_public_key(const char *pkey_file, const char *dtb_file,
if (destfd == -1) {
fprintf(stderr, "%s: Can't open %s: %s\n",
__func__, dtb_file, strerror(errno));
ret = -1;
goto err;
}
@ -189,21 +193,24 @@ static int add_public_key(const char *pkey_file, const char *dtb_file,
if (ftruncate(destfd, dtb.st_size)) {
fprintf(stderr, "%s: Can't expand %s: %s\n",
__func__, dtb_file, strerror(errno));
goto err;;
ret = -1;
goto err;
}
errno = 0;
/* mmap the dtb file */
dptr = mmap(0, dtb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED,
destfd, 0);
if ((dptr == MAP_FAILED) || (errno != 0)) {
if (dptr == MAP_FAILED) {
fprintf(stderr, "%s: Failed to mmap %s:%s\n",
__func__, dtb_file, strerror(errno));
ret = -1;
goto err;
}
if (fdt_check_header(dptr)) {
fprintf(stderr, "%s: Invalid FDT header\n", __func__);
ret = -1;
goto err;
}
@ -211,6 +218,7 @@ static int add_public_key(const char *pkey_file, const char *dtb_file,
if (ret) {
fprintf(stderr, "%s: Cannot expand FDT: %s\n",
__func__, fdt_strerror(ret));
ret = -1;
goto err;
}
@ -219,10 +227,11 @@ static int add_public_key(const char *pkey_file, const char *dtb_file,
if (ret < 0) {
fprintf(stderr, "%s: Unable to add public key to the FDT\n",
__func__);
ret = -1;
goto err;
}
return 0;
ret = 0;
err:
if (sptr)
@ -231,13 +240,13 @@ err:
if (dptr)
munmap(dptr, dtb.st_size);
if (srcfd >= 0)
if (srcfd != -1)
close(srcfd);
if (destfd >= 0)
if (destfd != -1)
close(destfd);
return -1;
return ret;
}
static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
@ -310,6 +319,9 @@ static int create_fwbin(char *path, char *bin, efi_guid_t *guid,
image.version = 0x00000003;
memcpy(&image.update_image_type_id, guid, sizeof(*guid));
image.update_image_index = index;
image.reserved[0] = 0;
image.reserved[1] = 0;
image.reserved[2] = 0;
image.update_image_size = bin_stat.st_size;
image.update_vendor_code_size = 0; /* none */
image.update_hardware_instance = instance;
@ -421,26 +433,25 @@ int main(int argc, char **argv)
/* need a fit image file or raw image file */
if (!file && !pkey_file && !dtb_file) {
printf("%s: %d\n", __func__, __LINE__);
print_usage();
return -1;
exit(EXIT_FAILURE);
}
if (pkey_file && dtb_file) {
ret = add_public_key(pkey_file, dtb_file, overlay);
if (ret == -1) {
printf("Adding public key to the dtb failed\n");
return -1;
exit(EXIT_FAILURE);
} else {
return 0;
exit(EXIT_SUCCESS);
}
}
if (create_fwbin(argv[optind], file, guid, index, instance)
< 0) {
printf("Creating firmware capsule failed\n");
return -1;
exit(EXIT_FAILURE);
}
return 0;
exit(EXIT_SUCCESS);
}