[U-Boot] [PATCH 1/1] efi_loader: correct signature of GetPosition, SetPosition

Heinrich Schuchardt xypron.glpk at gmx.de
Sun Oct 7 03:26:26 UTC 2018


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 at gmx.de>
---
 include/efi_api.h                            |  4 +-
 lib/efi_loader/efi_file.c                    | 39 ++++++++++++++++----
 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 e6566bb358..3194db3517 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -1175,9 +1175,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 f3226a8dc0..beb4fba917 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -443,28 +443,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 1cd13042e9..d4e4fac1c7 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);
-- 
2.19.0



More information about the U-Boot mailing list