svn commit: r302312 - in head/sys/boot: fdt powerpc/ofw

Nathan Whitehorn nwhitehorn at FreeBSD.org
Fri Jul 1 21:09:31 UTC 2016


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 at 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 */


More information about the svn-src-all mailing list