Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/stand/efiboot Fixup OpenSimpleReadFile usage:



details:   https://anonhg.NetBSD.org/src/rev/7c737396c521
branches:  trunk
changeset: 973847:7c737396c521
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Wed Jul 15 00:51:40 2020 +0000

description:
Fixup OpenSimpleReadFile usage:
 - The "EFI_DEVICE_PATH **FilePath" parameter can change, so do not free
   the output. This was causing crashes on U-Boot when attempting to load
   boot.cfg, even if it didn't exist.
 - Allocate the SIMPLE_READ_FILE in advance and store a pointer to it in
   struct open_file.

diffstat:

 sys/stand/efiboot/efiboot.h |   5 +++--
 sys/stand/efiboot/efidev.c  |  15 ++++++++++++++-
 sys/stand/efiboot/efifile.c |  44 +++++++++++++++++++++++++++-----------------
 3 files changed, 44 insertions(+), 20 deletions(-)

diffs (158 lines):

diff -r 9c759c3041ec -r 7c737396c521 sys/stand/efiboot/efiboot.h
--- a/sys/stand/efiboot/efiboot.h       Tue Jul 14 17:40:10 2020 +0000
+++ b/sys/stand/efiboot/efiboot.h       Wed Jul 15 00:51:40 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: efiboot.h,v 1.12 2020/06/26 03:23:04 thorpej Exp $     */
+/*     $NetBSD: efiboot.h,v 1.13 2020/07/15 00:51:40 jmcneill Exp $    */
 
 /*-
  * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
@@ -82,7 +82,8 @@
 int utf8_to_ucs2(const char *, CHAR16 **, size_t *);
 
 /* efidev.c */
-int efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
+int efi_device_path_depth(EFI_DEVICE_PATH *, int);
+int efi_device_path_count(EFI_DEVICE_PATH *);
 int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int);
 
 /* efinet.c */
diff -r 9c759c3041ec -r 7c737396c521 sys/stand/efiboot/efidev.c
--- a/sys/stand/efiboot/efidev.c        Tue Jul 14 17:40:10 2020 +0000
+++ b/sys/stand/efiboot/efidev.c        Wed Jul 15 00:51:40 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: efidev.c,v 1.1 2018/08/26 21:28:18 jmcneill Exp $      */
+/*     $NetBSD: efidev.c,v 1.2 2020/07/15 00:51:40 jmcneill Exp $      */
 /*     $OpenBSD: efiboot.c,v 1.28 2017/11/25 19:02:07 patrick Exp $    */
 
 /*
@@ -37,6 +37,19 @@
 }
 
 int
+efi_device_path_count(EFI_DEVICE_PATH *dp)
+{
+       int     count;
+
+       for (count = 0; ; dp = NextDevicePathNode(dp), count++) {
+               if (IsDevicePathEnd(dp))
+                       break;
+       }
+
+       return (count);
+}
+
+int
 efi_device_path_ncmp(EFI_DEVICE_PATH *dpa, EFI_DEVICE_PATH *dpb, int deptn)
 {
        int      i, cmp;
diff -r 9c759c3041ec -r 7c737396c521 sys/stand/efiboot/efifile.c
--- a/sys/stand/efiboot/efifile.c       Tue Jul 14 17:40:10 2020 +0000
+++ b/sys/stand/efiboot/efifile.c       Wed Jul 15 00:51:40 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: efifile.c,v 1.4 2020/06/27 17:23:08 jmcneill Exp $ */
+/* $NetBSD: efifile.c,v 1.5 2020/07/15 00:51:40 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2018 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -67,9 +67,9 @@
 int
 efi_file_open(struct open_file *f, ...)
 {
-       EFI_DEVICE_PATH *dp;
-       SIMPLE_READ_FILE srf;
-       EFI_HANDLE device, file;
+       EFI_DEVICE_PATH *file_dp, *dp;
+       SIMPLE_READ_FILE *srf;
+       EFI_HANDLE device;
        EFI_STATUS status;
        UINTN vol;
        const char *fname, *path;
@@ -86,30 +86,37 @@
        if (rv != 0)
                return rv;
 
-       device = efi_vol[vol];
-
        upath = NULL;
        rv = utf8_to_ucs2(path, &upath, &len);
        if (rv != 0)
                return rv;
 
-       dp = FileDevicePath(device, upath);
+       file_dp = FileDevicePath(efi_vol[vol], upath);
        FreePool(upath);
-       if (dp == NULL)
+       if (file_dp == NULL)
                return EINVAL;
 
-       status = OpenSimpleReadFile(TRUE, NULL, 0, &dp, &file, &srf);
-       FreePool(dp);
-       if (EFI_ERROR(status))
+       srf = AllocatePool(sizeof(*srf));
+       if (srf == NULL)
+               return ENOMEM;
+
+       dp = file_dp;
+       status = OpenSimpleReadFile(FALSE, NULL, 0, &dp, &device, srf);
+       FreePool(file_dp);
+       if (EFI_ERROR(status)) {
+               FreePool(srf);
                return status == EFI_NOT_FOUND ? ENOENT : EIO;
+       }
 
        for (n = 0; n < ndevs; n++)
                if (strcmp(DEV_NAME(&devsw[n]), "efifile") == 0) {
                        f->f_dev = &devsw[n];
                        break;
                }
-       if (n == ndevs)
+       if (n == ndevs) {
+               FreePool(srf);
                return ENXIO;
+       }
        f->f_devdata = f;
        f->f_fsdata = srf;
        f->f_flags = F_NODEV | F_READ;
@@ -120,9 +127,10 @@
 int
 efi_file_close(struct open_file *f)
 {
-       SIMPLE_READ_FILE srf = f->f_fsdata;
+       SIMPLE_READ_FILE *srf = f->f_fsdata;
 
-       CloseSimpleReadFile(srf);
+       CloseSimpleReadFile(*srf);
+       FreePool(srf);
 
        return 0;
 }
@@ -131,7 +139,7 @@
 efi_file_strategy(void *devdata, int rw, daddr_t dblk, size_t size, void *buf, size_t *rsize)
 {
        struct open_file *f = devdata;
-       SIMPLE_READ_FILE srf = f->f_fsdata;
+       SIMPLE_READ_FILE *srf = f->f_fsdata;
        EFI_STATUS status;
        UINTN len;
 
@@ -139,7 +147,7 @@
                return EROFS;
 
        len = size;
-       status = ReadSimpleReadFile(srf, f->f_offset, &len, buf);
+       status = ReadSimpleReadFile(*srf, f->f_offset, &len, buf);
        if (EFI_ERROR(status))
                return EIO;
        *rsize = len;
@@ -153,7 +161,9 @@
        UINTN vol;
        int depth;
 
-       depth = efi_device_path_depth(dp, END_DEVICE_PATH_TYPE);
+       depth = efi_device_path_count(dp);
+       if (depth == 0)
+               return ENODEV;
 
        for (vol = 0; vol < efi_nvol; vol++) {
                if (efi_device_path_ncmp(dp, DevicePathFromHandle(efi_vol[vol]), depth) == 0)



Home | Main Index | Thread Index | Old Index