[U-Boot] [PATCH 1/4] efi_loader: parameter checks BLOCK_IO_PROTOCOL

Heinrich Schuchardt xypron.glpk at gmx.de
Thu Sep 5 21:22:45 UTC 2019


Check parameters of ReadBlocks() and WriteBlocks().

If the buffer size is not a multiple of the block size, we have to return
EFI_BAD_BUFFER_SIZE.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 lib/efi_loader/efi_disk.c | 37 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 36 insertions(+), 1 deletion(-)

diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 7a6b06821a..0bf436ac66 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -74,7 +74,7 @@ static efi_status_t efi_disk_rw_blocks(struct efi_block_io *this,

 	/* We only support full block access */
 	if (buffer_size & (blksz - 1))
-		return EFI_DEVICE_ERROR;
+		return EFI_BAD_BUFFER_SIZE;

 	if (direction == EFI_DISK_READ)
 		n = blk_dread(desc, lba, blocks, buffer);
@@ -99,6 +99,20 @@ static efi_status_t EFIAPI efi_disk_read_blocks(struct efi_block_io *this,
 	void *real_buffer = buffer;
 	efi_status_t r;

+	if (!this)
+		return EFI_INVALID_PARAMETER;
+	/* TODO: check for media changes */
+	if (media_id != this->media->media_id)
+		return EFI_MEDIA_CHANGED;
+	if (!this->media->media_present)
+		return EFI_NO_MEDIA;
+	/* media->io_align is a power of 2 */
+	if ((uintptr_t)buffer & (this->media->io_align - 1))
+		return EFI_INVALID_PARAMETER;
+	if (lba * this->media->block_size + buffer_size >
+	    this->media->last_block * this->media->block_size)
+		return EFI_INVALID_PARAMETER;
+
 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
 	if (buffer_size > EFI_LOADER_BOUNCE_BUFFER_SIZE) {
 		r = efi_disk_read_blocks(this, media_id, lba,
@@ -134,6 +148,22 @@ static efi_status_t EFIAPI efi_disk_write_blocks(struct efi_block_io *this,
 	void *real_buffer = buffer;
 	efi_status_t r;

+	if (!this)
+		return EFI_INVALID_PARAMETER;
+	if (this->media->read_only)
+		return EFI_WRITE_PROTECTED;
+	/* TODO: check for media changes */
+	if (media_id != this->media->media_id)
+		return EFI_MEDIA_CHANGED;
+	if (!this->media->media_present)
+		return EFI_NO_MEDIA;
+	/* media->io_align is a power of 2 */
+	if ((uintptr_t)buffer & (this->media->io_align - 1))
+		return EFI_INVALID_PARAMETER;
+	if (lba * this->media->block_size + buffer_size >
+	    this->media->last_block * this->media->block_size)
+		return EFI_INVALID_PARAMETER;
+
 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
 	if (buffer_size > EFI_LOADER_BOUNCE_BUFFER_SIZE) {
 		r = efi_disk_write_blocks(this, media_id, lba,
@@ -288,6 +318,11 @@ static efi_status_t efi_disk_add_dev(
 	/* Fill in EFI IO Media info (for read/write callbacks) */
 	diskobj->media.removable_media = desc->removable;
 	diskobj->media.media_present = 1;
+	/*
+	 * MediaID is just an arbitrary counter.
+	 * We have to change it if the medium is removed or changed.
+	 */
+	diskobj->media.media_id = 1;
 	diskobj->media.block_size = desc->blksz;
 	diskobj->media.io_align = desc->blksz;
 	diskobj->media.last_block = desc->lba - offset;
--
2.23.0.rc1



More information about the U-Boot mailing list