efi_loader: parameter checks BLOCK_IO_PROTOCOL
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@gmx.de>
This commit is contained in:
		
							parent
							
								
									03446987c5
								
							
						
					
					
						commit
						f59f0825e8
					
				|  | @ -74,7 +74,7 @@ static efi_status_t efi_disk_rw_blocks(struct efi_block_io *this, | ||||||
| 
 | 
 | ||||||
| 	/* We only support full block access */ | 	/* We only support full block access */ | ||||||
| 	if (buffer_size & (blksz - 1)) | 	if (buffer_size & (blksz - 1)) | ||||||
| 		return EFI_DEVICE_ERROR; | 		return EFI_BAD_BUFFER_SIZE; | ||||||
| 
 | 
 | ||||||
| 	if (direction == EFI_DISK_READ) | 	if (direction == EFI_DISK_READ) | ||||||
| 		n = blk_dread(desc, lba, blocks, buffer); | 		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; | 	void *real_buffer = buffer; | ||||||
| 	efi_status_t r; | 	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 | #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER | ||||||
| 	if (buffer_size > EFI_LOADER_BOUNCE_BUFFER_SIZE) { | 	if (buffer_size > EFI_LOADER_BOUNCE_BUFFER_SIZE) { | ||||||
| 		r = efi_disk_read_blocks(this, media_id, lba, | 		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; | 	void *real_buffer = buffer; | ||||||
| 	efi_status_t r; | 	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 | #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER | ||||||
| 	if (buffer_size > EFI_LOADER_BOUNCE_BUFFER_SIZE) { | 	if (buffer_size > EFI_LOADER_BOUNCE_BUFFER_SIZE) { | ||||||
| 		r = efi_disk_write_blocks(this, media_id, lba, | 		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) */ | 	/* Fill in EFI IO Media info (for read/write callbacks) */ | ||||||
| 	diskobj->media.removable_media = desc->removable; | 	diskobj->media.removable_media = desc->removable; | ||||||
| 	diskobj->media.media_present = 1; | 	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.block_size = desc->blksz; | ||||||
| 	diskobj->media.io_align = desc->blksz; | 	diskobj->media.io_align = desc->blksz; | ||||||
| 	diskobj->media.last_block = desc->lba - offset; | 	diskobj->media.last_block = desc->lba - offset; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue