Fix TFTP reading of zero-size files:
authornaddy <naddy@openbsd.org>
Tue, 30 Jan 2018 20:19:06 +0000 (20:19 +0000)
committernaddy <naddy@openbsd.org>
Tue, 30 Jan 2018 20:19:06 +0000 (20:19 +0000)
The AllocatePages EFI call returns an error when the allocation
size is 0.  Skip allocating memory and actually transferring the
file when it is empty.

Properly return the number of unread bytes so that a read() of n
bytes does not return n if no bytes were read.

While here, disallow lseek() beyond the TFTP file buffer for SEEK_CUR
as we already do for SEEK_SET.

ok patrick@

sys/arch/amd64/stand/efiboot/conf.c
sys/arch/amd64/stand/efiboot/efipxe.c
sys/arch/arm64/stand/efiboot/conf.c
sys/arch/arm64/stand/efiboot/efipxe.c

index fae68c7..b91d748 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: conf.c,v 1.12 2017/11/25 19:02:07 patrick Exp $       */
+/*     $OpenBSD: conf.c,v 1.13 2018/01/30 20:19:06 naddy Exp $ */
 
 /*
  * Copyright (c) 1996 Michael Shalayeff
@@ -39,7 +39,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "3.36";
+const char version[] = "3.37";
 
 #ifdef EFI_DEBUG
 int    debug = 0;
index 7488e77..38ae4c7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: efipxe.c,v 1.2 2018/01/21 21:37:01 patrick Exp $      */
+/*     $OpenBSD: efipxe.c,v 1.3 2018/01/30 20:19:06 naddy Exp $        */
 /*
  * Copyright (c) 2017 Patrick Wildt <patrick@blueri.se>
  *
@@ -143,6 +143,9 @@ tftp_open(char *path, struct open_file *f)
        }
        tftpfile->inbufsize = size;
 
+       if (tftpfile->inbufsize == 0)
+               goto out;
+
        status = EFI_CALL(BS->AllocatePages, AllocateAnyPages, EfiLoaderData,
            EFI_SIZE_TO_PAGES(tftpfile->inbufsize), &addr);
        if (status != EFI_SUCCESS) {
@@ -157,7 +160,7 @@ tftp_open(char *path, struct open_file *f)
                free(tftpfile, sizeof(*tftpfile));
                return ENXIO;
        }
-
+out:
        f->f_fsdata = tftpfile;
        return 0;
 }
@@ -167,8 +170,9 @@ tftp_close(struct open_file *f)
 {
        struct tftp_handle *tftpfile = f->f_fsdata;
 
-       EFI_CALL(BS->FreePages, (paddr_t)tftpfile->inbuf,
-           EFI_SIZE_TO_PAGES(tftpfile->inbufsize));
+       if (tftpfile->inbuf != NULL)
+               EFI_CALL(BS->FreePages, (paddr_t)tftpfile->inbuf,
+                   EFI_SIZE_TO_PAGES(tftpfile->inbufsize));
        free(tftpfile, sizeof(*tftpfile));
        return 0;
 }
@@ -184,15 +188,11 @@ tftp_read(struct open_file *f, void *addr, size_t size, size_t *resid)
        else
                toread = size;
 
-       if (toread == 0) {
-               if (resid != NULL)
-                       *resid = 0;
-               return (0);
+       if (toread != 0) {
+               memcpy(addr, tftpfile->inbuf + tftpfile->inbufoff, toread);
+               tftpfile->inbufoff += toread;
        }
 
-       memcpy(addr, tftpfile->inbuf + tftpfile->inbufoff, toread);
-       tftpfile->inbufoff += toread;
-
        if (resid != NULL)
                *resid = size - toread;
        return 0;
@@ -211,7 +211,8 @@ tftp_seek(struct open_file *f, off_t offset, int where)
 
        switch(where) {
        case SEEK_CUR:
-               if (tftpfile->inbufoff + offset < 0) {
+               if (tftpfile->inbufoff + offset < 0 ||
+                   tftpfile->inbufoff + offset > tftpfile->inbufsize) {
                        errno = EOFFSET;
                        break;
                }
index e504d62..d9f9b34 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: conf.c,v 1.10 2018/01/21 21:35:34 patrick Exp $       */
+/*     $OpenBSD: conf.c,v 1.11 2018/01/30 20:19:06 naddy Exp $ */
 
 /*
  * Copyright (c) 1996 Michael Shalayeff
@@ -36,7 +36,7 @@
 #include "efidev.h"
 #include "efipxe.h"
 
-const char version[] = "0.9";
+const char version[] = "0.10";
 int    debug = 0;
 
 struct fs_ops file_system[] = {
index d0684ea..d871744 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: efipxe.c,v 1.1 2018/01/21 21:35:34 patrick Exp $      */
+/*     $OpenBSD: efipxe.c,v 1.2 2018/01/30 20:19:06 naddy Exp $        */
 /*
  * Copyright (c) 2017 Patrick Wildt <patrick@blueri.se>
  *
@@ -139,6 +139,9 @@ tftp_open(char *path, struct open_file *f)
        }
        tftpfile->inbufsize = size;
 
+       if (tftpfile->inbufsize == 0)
+               goto out;
+
        status = EFI_CALL(BS->AllocatePages, AllocateAnyPages, EfiLoaderData,
            EFI_SIZE_TO_PAGES(tftpfile->inbufsize), &addr);
        if (status != EFI_SUCCESS) {
@@ -153,7 +156,7 @@ tftp_open(char *path, struct open_file *f)
                free(tftpfile, sizeof(*tftpfile));
                return ENXIO;
        }
-
+out:
        f->f_fsdata = tftpfile;
        return 0;
 }
@@ -163,8 +166,9 @@ tftp_close(struct open_file *f)
 {
        struct tftp_handle *tftpfile = f->f_fsdata;
 
-       EFI_CALL(BS->FreePages, (paddr_t)tftpfile->inbuf,
-           EFI_SIZE_TO_PAGES(tftpfile->inbufsize));
+       if (tftpfile->inbuf != NULL)
+               EFI_CALL(BS->FreePages, (paddr_t)tftpfile->inbuf,
+                   EFI_SIZE_TO_PAGES(tftpfile->inbufsize));
        free(tftpfile, sizeof(*tftpfile));
        return 0;
 }
@@ -180,15 +184,11 @@ tftp_read(struct open_file *f, void *addr, size_t size, size_t *resid)
        else
                toread = size;
 
-       if (toread == 0) {
-               if (resid != NULL)
-                       *resid = 0;
-               return (0);
+       if (toread != 0) {
+               memcpy(addr, tftpfile->inbuf + tftpfile->inbufoff, toread);
+               tftpfile->inbufoff += toread;
        }
 
-       memcpy(addr, tftpfile->inbuf + tftpfile->inbufoff, toread);
-       tftpfile->inbufoff += toread;
-
        if (resid != NULL)
                *resid = size - toread;
        return 0;
@@ -207,7 +207,8 @@ tftp_seek(struct open_file *f, off_t offset, int where)
 
        switch(where) {
        case SEEK_CUR:
-               if (tftpfile->inbufoff + offset < 0) {
+               if (tftpfile->inbufoff + offset < 0 ||
+                   tftpfile->inbufoff + offset > tftpfile->inbufsize) {
                        errno = EOFFSET;
                        break;
                }