Author: nwhitehorn
Date: Fri Jul  1 21:09:30 2016
New Revision: 302312
URL: https://svnweb.freebsd.org/changeset/base/302312

Log:
  Clean up some FDT-related code in the PowerPC bootloader, improving error
  checking and robustness. Prevents errors and crashes in FDT commands on
  PowerMac G5 systems.
  
  Approved by:  re (gjb)

Modified:
  head/sys/boot/fdt/fdt_loader_cmd.c
  head/sys/boot/powerpc/ofw/ofwfdt.c

Modified: head/sys/boot/fdt/fdt_loader_cmd.c
==============================================================================
--- head/sys/boot/fdt/fdt_loader_cmd.c  Fri Jul  1 20:25:59 2016        
(r302311)
+++ head/sys/boot/fdt/fdt_loader_cmd.c  Fri Jul  1 21:09:30 2016        
(r302312)
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
 #endif
 
 #define FDT_CWD_LEN    256
-#define FDT_MAX_DEPTH  6
+#define FDT_MAX_DEPTH  12
 
 #define FDT_PROP_SEP   " = "
 
@@ -1029,7 +1029,7 @@ fdt_cmd_ls(int argc, char *argv[])
        const char *prevname[FDT_MAX_DEPTH] = { NULL };
        const char *name;
        char *path;
-       int i, o, depth, len;
+       int i, o, depth;
 
        path = (argc > 2) ? argv[2] : NULL;
        if (path == NULL)
@@ -1045,7 +1045,7 @@ fdt_cmd_ls(int argc, char *argv[])
            (o >= 0) && (depth >= 0);
            o = fdt_next_node(fdtp, o, &depth)) {
 
-               name = fdt_get_name(fdtp, o, &len);
+               name = fdt_get_name(fdtp, o, NULL);
 
                if (depth > FDT_MAX_DEPTH) {
                        printf("max depth exceeded: %d\n", depth);

Modified: head/sys/boot/powerpc/ofw/ofwfdt.c
==============================================================================
--- head/sys/boot/powerpc/ofw/ofwfdt.c  Fri Jul  1 20:25:59 2016        
(r302311)
+++ head/sys/boot/powerpc/ofw/ofwfdt.c  Fri Jul  1 21:09:30 2016        
(r302312)
@@ -33,24 +33,37 @@ __FBSDID("$FreeBSD$");
 #include <libfdt.h>
 #include "bootstrap.h"
 
+extern int command_fdt_internal(int argc, char *argv[]);
+
 static int
 OF_hasprop(phandle_t node, const char *prop)
 {
-       return (OF_getproplen(node, prop) > 0);
+       return (OF_getproplen(node, (char *)prop) > 0);
 }
 
 static void
 add_node_to_fdt(void *buffer, phandle_t node, int fdt_offset)
 {
-        int i, child_offset, error;
-        char name[2048], *lastprop, *subname;
+       int i, child_offset, error;
+       char name[255], *lastprop, *subname;
        void *propbuf;
-       size_t proplen;
+       ssize_t proplen;
 
        lastprop = NULL;
        while (OF_nextprop(node, lastprop, name) > 0) {
                proplen = OF_getproplen(node, name);
+
+               /* Detect and correct for errors and strangeness */
+               if (proplen < 0)
+                       proplen = 0;
+               if (proplen > 1024)
+                       proplen = 1024;
+
                propbuf = malloc(proplen);
+               if (propbuf == NULL) {
+                       printf("Cannot allocate memory for prop %s\n", name);
+                       return;
+               }
                OF_getprop(node, name, propbuf, proplen);
                error = fdt_setprop(buffer, fdt_offset, name, propbuf, proplen);
                free(propbuf);
@@ -64,7 +77,7 @@ add_node_to_fdt(void *buffer, phandle_t 
            && !OF_hasprop(node, "ibm,phandle"))
                fdt_setprop(buffer, fdt_offset, "phandle", &node, sizeof(node));
 
-        for (node = OF_child(node); node > 0; node = OF_peer(node)) {
+       for (node = OF_child(node); node > 0; node = OF_peer(node)) {
                OF_package_to_path(node, name, sizeof(name));
                subname = strrchr(name, '/');
                subname++;
@@ -76,7 +89,7 @@ add_node_to_fdt(void *buffer, phandle_t 
                }
        
                 add_node_to_fdt(buffer, node, child_offset);
-        }
+       }
 }
 
 static void
@@ -123,18 +136,16 @@ ofwfdt_fixups(void *fdtp)
                fdt_add_mem_rsv(fdtp, base, len);
        } else {
                /*
-                * Remove /memory/available properties, which reflect long-gone 
OF
-                * state. Note that this doesn't work if we need RTAS still, 
since
-                * that's part of the firmware.
+                * Remove /memory/available properties, which reflect long-gone
+                * OF state. Note that this doesn't work if we need RTAS still,
+                * since that's part of the firmware.
                 */
-
                offset = fdt_path_offset(fdtp, "/memory@0");
                if (offset > 0)
                        fdt_delprop(fdtp, offset, "available");
        }
-               
-       /*
 
+       
        /*
         * Convert stored ihandles under /chosen to xref phandles
         */
@@ -158,7 +169,8 @@ ofwfdt_fixups(void *fdtp)
                                        OF_getprop(node, "ibm,phandle", &node,
                                            sizeof(node));
                                node = cpu_to_fdt32(node);
-                               fdt_setprop(fdtp, offset, chosenprops[i], 
&node,                                    sizeof(node));
+                               fdt_setprop(fdtp, offset, chosenprops[i], &node,
+                                   sizeof(node));
                        }
 
                        /* Refind node in case it moved */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to