diff options
author | Heinrich Schuchardt <xypron.glpk@gmx.de> | 2018-10-07 05:26:26 +0200 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2018-10-16 15:47:05 +0200 |
commit | 0801d4d2fbceb04b4f1983fdd7c2dd5ae728fd74 (patch) | |
tree | e9654cd7f843b92ec43762d7491f7451a4a7f86c | |
parent | 3ce7829792c50d1e5add3d8ef88883e8298aa4eb (diff) |
efi_loader: correct signature of GetPosition, SetPosition
The UEFI spec requires that file positions are passed as u64 in
GetPosition() and SetPosition().
Check if the file handle points to a directory in GetPosition().
Provide a unit test for GetPosition() and SetPosition().
Fix Coverity warning CID 184079 (CONSTANT_EXPRESSION_RESULT).
Add comments.
Fixes: b6dd57773719 ("efi_loader: use correct types in EFI_FILE_PROTOCOL")
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r-- | include/efi_api.h | 4 | ||||
-rw-r--r-- | lib/efi_loader/efi_file.c | 39 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_block_device.c | 30 |
3 files changed, 61 insertions, 12 deletions
diff --git a/include/efi_api.h b/include/efi_api.h index bea19a5a123..e850b951eb0 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -914,9 +914,9 @@ struct efi_file_handle { efi_status_t (EFIAPI *write)(struct efi_file_handle *file, efi_uintn_t *buffer_size, void *buffer); efi_status_t (EFIAPI *getpos)(struct efi_file_handle *file, - efi_uintn_t *pos); + u64 *pos); efi_status_t (EFIAPI *setpos)(struct efi_file_handle *file, - efi_uintn_t pos); + u64 pos); efi_status_t (EFIAPI *getinfo)(struct efi_file_handle *file, const efi_guid_t *info_type, efi_uintn_t *buffer_size, void *buffer); diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c index 0753a36a20b..c1e285e9f7c 100644 --- a/lib/efi_loader/efi_file.c +++ b/lib/efi_loader/efi_file.c @@ -436,28 +436,51 @@ error: return EFI_EXIT(ret); } +/** + * efi_file_getpos() - get current position in file + * + * This function implements the GetPosition service of the EFI file protocol. + * See the UEFI spec for details. + * + * @file: file handle + * @pos: pointer to file position + * Return: status code + */ static efi_status_t EFIAPI efi_file_getpos(struct efi_file_handle *file, - efi_uintn_t *pos) + u64 *pos) { + efi_status_t ret = EFI_SUCCESS; struct file_handle *fh = to_fh(file); EFI_ENTRY("%p, %p", file, pos); - if (fh->offset <= SIZE_MAX) { - *pos = fh->offset; - return EFI_EXIT(EFI_SUCCESS); - } else { - return EFI_EXIT(EFI_DEVICE_ERROR); + if (fh->isdir) { + ret = EFI_UNSUPPORTED; + goto out; } + + *pos = fh->offset; +out: + return EFI_EXIT(ret); } +/** + * efi_file_setpos() - set current position in file + * + * This function implements the SetPosition service of the EFI file protocol. + * See the UEFI spec for details. + * + * @file: file handle + * @pos: new file position + * Return: status code + */ static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, - efi_uintn_t pos) + u64 pos) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; - EFI_ENTRY("%p, %zu", file, pos); + EFI_ENTRY("%p, %llu", file, pos); if (fh->isdir) { if (pos != 0) { diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c index 1cd13042e90..d4e4fac1c74 100644 --- a/lib/efi_selftest/efi_selftest_block_device.c +++ b/lib/efi_selftest/efi_selftest_block_device.c @@ -308,6 +308,7 @@ static int execute(void) } system_info; efi_uintn_t buf_size; char buf[16] __aligned(ARCH_DMA_MINALIGN); + u64 pos; /* Connect controller to virtual disk */ ret = boottime->connect_controller(disk_handle, NULL, NULL, 1); @@ -392,21 +393,36 @@ static int execute(void) efi_st_error("Failed to open file\n"); return EFI_ST_FAILURE; } + ret = file->setpos(file, 1); + if (ret != EFI_SUCCESS) { + efi_st_error("SetPosition failed\n"); + return EFI_ST_FAILURE; + } buf_size = sizeof(buf) - 1; ret = file->read(file, &buf_size, buf); if (ret != EFI_SUCCESS) { efi_st_error("Failed to read file\n"); return EFI_ST_FAILURE; } - if (buf_size != 13) { + if (buf_size != 12) { efi_st_error("Wrong number of bytes read: %u\n", (unsigned int)buf_size); return EFI_ST_FAILURE; } - if (efi_st_memcmp(buf, "Hello world!", 12)) { + if (efi_st_memcmp(buf, "ello world!", 11)) { efi_st_error("Unexpected file content\n"); return EFI_ST_FAILURE; } + ret = file->getpos(file, &pos); + if (ret != EFI_SUCCESS) { + efi_st_error("GetPosition failed\n"); + return EFI_ST_FAILURE; + } + if (pos != 13) { + efi_st_error("GetPosition returned %u, expected 13\n", + (unsigned int)pos); + return EFI_ST_FAILURE; + } ret = file->close(file); if (ret != EFI_SUCCESS) { efi_st_error("Failed to close file\n"); @@ -434,6 +450,16 @@ static int execute(void) efi_st_error("Failed to close file\n"); return EFI_ST_FAILURE; } + ret = file->getpos(file, &pos); + if (ret != EFI_SUCCESS) { + efi_st_error("GetPosition failed\n"); + return EFI_ST_FAILURE; + } + if (pos != 7) { + efi_st_error("GetPosition returned %u, expected 7\n", + (unsigned int)pos); + return EFI_ST_FAILURE; + } /* Verify file */ boottime->set_mem(buf, sizeof(buf), 0); |