Author: imp
Date: Fri Sep 30 15:41:12 2016
New Revision: 306504
URL: https://svnweb.freebsd.org/changeset/base/306504

Log:
  Fix a cluster of bugs in list EFI environment variables:
  1. Size returned for variable name is in bytes, not CHAR16 (the
     UEFI standard is unclear on this, where it is clear on the size of
     the variable).
  2. Dynamically allocate the buffers so we can grow them if someone
     defines a super-long variable name.
  
  These two fixes allow me to examine all the variables in my BIOS and
  also removes the repeated printing of variables.

Modified:
  head/sys/boot/efi/loader/main.c

Modified: head/sys/boot/efi/loader/main.c
==============================================================================
--- head/sys/boot/efi/loader/main.c     Fri Sep 30 14:00:23 2016        
(r306503)
+++ head/sys/boot/efi/loader/main.c     Fri Sep 30 15:41:12 2016        
(r306504)
@@ -814,8 +814,10 @@ command_efi_show(int argc, char *argv[])
        EFI_GUID        varguid = { 0,0,0,{0,0,0,0,0,0,0,0} };
        EFI_GUID        matchguid = { 0,0,0,{0,0,0,0,0,0,0,0} };
        uint32_t        uuid_status;
-       CHAR16          varname[128];
+       CHAR16          *varname;
+       CHAR16          *newnm;
        CHAR16          varnamearg[128];
+       UINTN           varalloc;
        UINTN           varsz;
 
        while ((ch = getopt(argc, argv, "ag:lv:")) != -1) {
@@ -910,10 +912,33 @@ command_efi_show(int argc, char *argv[])
         * to specify the initial call must be a poiner to a NULL
         * character.
         */
-       varsz = nitems(varname);
+       varalloc = 1024;
+       varname = malloc(varalloc);
+       if (varname == NULL) {
+               printf("Can't allocate memory to get variables\n");
+               pager_close();
+               return (CMD_ERROR);
+       }
        varname[0] = 0;
-       while ((status = RS->GetNextVariableName(&varsz, varname, &varguid)) !=
-           EFI_NOT_FOUND) {
+       while (1) {
+               varsz = varalloc;
+               status = RS->GetNextVariableName(&varsz, varname, &varguid);
+               if (status == EFI_BUFFER_TOO_SMALL) {
+                       varalloc = varsz;
+                       newnm = malloc(varalloc);
+                       if (newnm == NULL) {
+                               printf("Can't allocate memory to get 
variables\n");
+                               free(varname);
+                               pager_close();
+                               return (CMD_ERROR);
+                       }
+                       memcpy(newnm, varname, varsz);
+                       free(varname);
+                       varname = newnm;
+                       continue; /* Try again with bigger buffer */
+               }
+               if (status != EFI_SUCCESS)
+                       break;
                if (aflag) {
                        if (efi_print_var(varname, &varguid, lflag) != CMD_OK)
                                break;
@@ -934,6 +959,7 @@ command_efi_show(int argc, char *argv[])
                        }
                }
        }
+       free(varname);
        pager_close();
 
        return (CMD_OK);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to