[U-Boot] [PATCH 1/4] efi_loader: EFI_FILE_PROTOCOL.Write() check args

Heinrich Schuchardt xypron.glpk at gmx.de
Sat Sep 7 23:59:47 UTC 2019


Check the parameters passed to Write():

* cannot write to directories (UEFI SCT 2017, 5.7.3.5.15)
* cannot write to file opened read only (UEFI SCT 2017, 5.7.3.5.16)

Add missing comments.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 lib/efi_loader/efi_file.c | 51 +++++++++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 10 deletions(-)

diff --git a/lib/efi_loader/efi_file.c b/lib/efi_loader/efi_file.c
index f4ca5694ee..a13754a558 100644
--- a/lib/efi_loader/efi_file.c
+++ b/lib/efi_loader/efi_file.c
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
- *  EFI utils
+ * EFI_FILE_PROTOCOL
  *
- *  Copyright (c) 2017 Rob Clark
+ * Copyright (c) 2017 Rob Clark
  */

 #include <common.h>
@@ -28,6 +28,7 @@ struct file_handle {
 	struct file_system *fs;
 	loff_t offset;       /* current file position/cursor */
 	int isdir;
+	u64 open_mode;

 	/* for reading a directory: */
 	struct fs_dir_stream *dirs;
@@ -161,13 +162,13 @@ static int efi_create_file(struct file_handle *fh, u64 attributes)
  * @file_name:		path of the file to be opened. '\', '.', or '..' may
  *			be used as modifiers. A leading backslash indicates an
  *			absolute path.
- * @mode:		bit mask indicating the access mode (read, write,
+ * @open_mode:		bit mask indicating the access mode (read, write,
  *			create)
  * @attributes:		attributes for newly created file
  * Returns:		handle to the opened file or NULL
  */
 static struct efi_file_handle *file_open(struct file_system *fs,
-		struct file_handle *parent, u16 *file_name, u64 mode,
+		struct file_handle *parent, u16 *file_name, u64 open_mode,
 		u64 attributes)
 {
 	struct file_handle *fh;
@@ -190,6 +191,7 @@ static struct efi_file_handle *file_open(struct file_system *fs,
 	/* +2 is for null and '/' */
 	fh = calloc(1, sizeof(*fh) + plen + (flen * MAX_UTF8_PER_UTF16) + 2);

+	fh->open_mode = open_mode;
 	fh->base = efi_file_handle_protocol;
 	fh->fs = fs;

@@ -218,9 +220,11 @@ static struct efi_file_handle *file_open(struct file_system *fs,
 			goto error;

 		if (!exists) {
-			if (!(mode & EFI_FILE_MODE_CREATE) ||
+			if (!(open_mode & EFI_FILE_MODE_CREATE) ||
 			    efi_create_file(fh, attributes))
 				goto error;
+			if (set_blk_dev(fh))
+				goto error;
 		}

 		/* figure out if file is a directory: */
@@ -434,6 +438,19 @@ error:
 	return EFI_EXIT(ret);
 }

+/**
+ * efi_file_write() - write to file
+ *
+ * This function implements the Write() service of the EFI_FILE_PROTOCOL.
+ *
+ * See the Unified Extensible Firmware Interface (UEFI) specification for
+ * details.
+ *
+ * @file:		file handle
+ * @buffer_size:	number of bytes to write
+ * @buffer:		buffer with the bytes to write
+ * Return:		status code
+ */
 static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *file,
 					  efi_uintn_t *buffer_size,
 					  void *buffer)
@@ -444,21 +461,35 @@ static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *file,

 	EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer);

+	if (!file || !buffer_size || !buffer) {
+		ret = EFI_INVALID_PARAMETER;
+		goto out;
+	}
+	if (fh->isdir) {
+		ret = EFI_UNSUPPORTED;
+		goto out;
+	}
+	if (!(fh->open_mode & EFI_FILE_MODE_WRITE)) {
+		ret = EFI_ACCESS_DENIED;
+		goto out;
+	}
+
+	if (!*buffer_size)
+		goto out;
+
 	if (set_blk_dev(fh)) {
 		ret = EFI_DEVICE_ERROR;
-		goto error;
+		goto out;
 	}
-
 	if (fs_write(fh->path, map_to_sysmem(buffer), fh->offset, *buffer_size,
 		     &actwrite)) {
 		ret = EFI_DEVICE_ERROR;
-		goto error;
+		goto out;
 	}
-
 	*buffer_size = actwrite;
 	fh->offset += actwrite;

-error:
+out:
 	return EFI_EXIT(ret);
 }

--
2.20.1



More information about the U-Boot mailing list