Blame SOURCES/skiboot-6.0.4-77f510d35e8d60faed989496fac2de16663ff332.patch

5917b8
commit 77f510d35e8d60faed989496fac2de16663ff332
5917b8
Author: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
5917b8
Date:   Tue Jun 26 16:50:51 2018 +0530
5917b8
5917b8
    vpd: Sanitize VPD data
5917b8
    
5917b8
    On OpenPower system, VPD keyword size tells us the maximum size of the data.
5917b8
    But they fill trailing end with space (0x20) instead of NULL. Also spec
5917b8
    doesn't stop user to have space (0x20) within actual data.
5917b8
    
5917b8
    This patch discards trailing spaces before populating device tree.
5917b8
    
5917b8
    Reported-by: Pridhiviraj Paidipeddi <ppaidipe@linux.vnet.ibm.com>
5917b8
    Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
5917b8
    [stewart: fixup make check]
5917b8
    Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
5917b8
5917b8
diff --git a/hdata/test/p8-840-spira.dts b/hdata/test/p8-840-spira.dts
5917b8
index e73c691d..428683b1 100644
5917b8
--- a/hdata/test/p8-840-spira.dts
5917b8
+++ b/hdata/test/p8-840-spira.dts
5917b8
@@ -900,7 +900,7 @@
5917b8
 					card-type = [80 b5 00];
5917b8
 					hw-characteristics = [00];
5917b8
 					ccin = "2B08";
5917b8
-					description = "CEC OP PANEL    ";
5917b8
+					description = "CEC OP PANEL";
5917b8
 				};
5917b8
 
5917b8
 				power-supply@3102 {
5917b8
diff --git a/hdata/test/p81-811.spira.dts b/hdata/test/p81-811.spira.dts
5917b8
index 2ca361ee..800468e3 100644
5917b8
--- a/hdata/test/p81-811.spira.dts
5917b8
+++ b/hdata/test/p81-811.spira.dts
5917b8
@@ -2119,7 +2119,7 @@
5917b8
 					card-type = [80 b5 00];
5917b8
 					hw-characteristics = [00];
5917b8
 					ccin = "2B08";
5917b8
-					description = "CEC OP PANEL    ";
5917b8
+					description = "CEC OP PANEL";
5917b8
 				};
5917b8
 
5917b8
 				power-supply@3100 {
5917b8
diff --git a/hdata/vpd.c b/hdata/vpd.c
5917b8
index 038569af..98123e5a 100644
5917b8
--- a/hdata/vpd.c
5917b8
+++ b/hdata/vpd.c
5917b8
@@ -22,6 +22,7 @@
5917b8
 #include <device.h>
5917b8
 #include "hdata.h"
5917b8
 #include <inttypes.h>
5917b8
+#include <mem_region-malloc.h>
5917b8
 
5917b8
 struct card_info {
5917b8
 	const char *ccin; 	/* Customer card identification number */
5917b8
@@ -221,6 +222,32 @@ static const struct card_info *card_info_lookup(char *ccin)
5917b8
 	return NULL;
5917b8
 }
5917b8
 
5917b8
+/* Discard trailing spaces and populate device tree */
5917b8
+static struct dt_property *dt_add_prop_sanitize_val(struct dt_node *node,
5917b8
+			     const char *name, const char *val, int vlen)
5917b8
+{
5917b8
+	char *prop = zalloc(vlen + 1);
5917b8
+	int i;
5917b8
+	struct dt_property *p = NULL;
5917b8
+
5917b8
+	if (!prop)
5917b8
+		return p;
5917b8
+
5917b8
+	memcpy(prop, val, vlen);
5917b8
+	for (i = vlen - 1; i >= 0; i--) {
5917b8
+		if (prop[i] != 0x20) {
5917b8
+			prop[i + 1] = '\0';
5917b8
+			break;
5917b8
+		}
5917b8
+	}
5917b8
+
5917b8
+	if (i >= 0 && !dt_find_property(node, name))
5917b8
+		p = dt_add_property_string(node, name, prop);
5917b8
+
5917b8
+	free(prop);
5917b8
+	return p;
5917b8
+}
5917b8
+
5917b8
 /*
5917b8
  * For OpenPOWER, we only decipher OPFR records. While OP HDAT have VINI
5917b8
  * records too, populating the fields in there is optional. Also, there
5917b8
@@ -235,27 +262,27 @@ static void vpd_opfr_parse(struct dt_node *node,
5917b8
 	/* Vendor Name */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "OPFR", "VN", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "vendor", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "vendor", kw, sz);
5917b8
 
5917b8
 	/* FRU Description */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "OPFR", "DR", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "description", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "description", kw, sz);
5917b8
 
5917b8
 	/* Part number */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "OPFR", "VP", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "part-number", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "part-number", kw, sz);
5917b8
 
5917b8
 	/* Serial number */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "OPFR", "VS", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "serial-number", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "serial-number", kw, sz);
5917b8
 
5917b8
 	/* Build date in BCD */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "OPFR", "MB", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "build-date", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "build-date", kw, sz);
5917b8
 
5917b8
 	return;
5917b8
 }
5917b8
@@ -272,12 +299,12 @@ static void vpd_vrml_parse(struct dt_node *node,
5917b8
 	/* Part number */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VRML", "PN", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "part-number", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "part-number", kw, sz);
5917b8
 
5917b8
 	/* Serial number */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VRML", "SN", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "serial-number", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "serial-number", kw, sz);
5917b8
 
5917b8
 	return;
5917b8
 }
5917b8
@@ -292,47 +319,47 @@ static void vpd_vini_parse(struct dt_node *node,
5917b8
 	/* FRU Stocking Part Number */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "FN", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "fru-number", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "fru-number", kw, sz);
5917b8
 
5917b8
 	/* Serial Number */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "SN", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "serial-number", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "serial-number", kw, sz);
5917b8
 
5917b8
 	/* Part Number */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "PN", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "part-number", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "part-number", kw, sz);
5917b8
 
5917b8
 	/* Vendor Name */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "VN", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "vendor", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "vendor", kw, sz);
5917b8
 
5917b8
 	/* CCIN Extension */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "CE", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "ccin-extension", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "ccin-extension", kw, sz);
5917b8
 
5917b8
 	/* HW Version info */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "HW", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "hw-version", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "hw-version", kw, sz);
5917b8
 
5917b8
 	/* Card type info */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "CT", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "card-type", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "card-type", kw, sz);
5917b8
 
5917b8
 	/* HW characteristics info */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "B3", &sz);
5917b8
 	if (kw)
5917b8
-		dt_add_property_nstr(node, "hw-characteristics", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "hw-characteristics", kw, sz);
5917b8
 
5917b8
 	/* Customer Card Identification Number (CCIN) */
5917b8
 	kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "CC", &sz);
5917b8
 	if (kw) {
5917b8
-		dt_add_property_nstr(node, "ccin", kw, sz);
5917b8
+		dt_add_prop_sanitize_val(node, "ccin", kw, sz);
5917b8
 
5917b8
 		cinfo = card_info_lookup((char *)kw);
5917b8
 		if (cinfo) {
5917b8
@@ -341,7 +368,7 @@ static void vpd_vini_parse(struct dt_node *node,
5917b8
 		} else {
5917b8
 			kw = vpd_find(fruvpd, fruvpd_sz, "VINI", "DR", &sz);
5917b8
 			if (kw) {
5917b8
-				dt_add_property_nstr(node,
5917b8
+				dt_add_prop_sanitize_val(node,
5917b8
 						     "description", kw, sz);
5917b8
 			} else {
5917b8
 				dt_add_property_string(node, "description", "Unknown");
5917b8
@@ -548,13 +575,13 @@ static void sysvpd_parse_opp(const void *sysvpd, unsigned int sysvpd_sz)
5917b8
 
5917b8
 	v = vpd_find(sysvpd, sysvpd_sz, "OSYS", "MM", &sz);
5917b8
 	if (v)
5917b8
-		dt_add_property_nstr(dt_root, "model", v, sz);
5917b8
+		dt_add_prop_sanitize_val(dt_root, "model", v, sz);
5917b8
 	else
5917b8
 		dt_add_property_string(dt_root, "model", "Unknown");
5917b8
 
5917b8
 	v = vpd_find(sysvpd, sysvpd_sz, "OSYS", "SS", &sz);
5917b8
 	if (v)
5917b8
-		dt_add_property_nstr(dt_root, "system-id", v, sz);
5917b8
+		dt_add_prop_sanitize_val(dt_root, "system-id", v, sz);
5917b8
 	else
5917b8
 		dt_add_property_string(dt_root, "system-id", "Unknown");
5917b8
 }
5917b8
@@ -569,19 +596,19 @@ static void sysvpd_parse_legacy(const void *sysvpd, unsigned int sysvpd_sz)
5917b8
 
5917b8
 	model = vpd_find(sysvpd, sysvpd_sz, "VSYS", "TM", &sz);
5917b8
 	if (model)
5917b8
-		dt_add_property_nstr(dt_root, "model", model, sz);
5917b8
+		dt_add_prop_sanitize_val(dt_root, "model", model, sz);
5917b8
 	else
5917b8
 		dt_add_property_string(dt_root, "model", "Unknown");
5917b8
 
5917b8
 	system_id = vpd_find(sysvpd, sysvpd_sz, "VSYS", "SE", &sz);
5917b8
 	if (system_id)
5917b8
-		dt_add_property_nstr(dt_root, "system-id", system_id, sz);
5917b8
+		dt_add_prop_sanitize_val(dt_root, "system-id", system_id, sz);
5917b8
 	else
5917b8
 		dt_add_property_string(dt_root, "system-id", "Unknown");
5917b8
 
5917b8
 	brand = vpd_find(sysvpd, sysvpd_sz, "VSYS", "BR", &sz);
5917b8
 	if (brand)
5917b8
-		dt_add_property_nstr(dt_root, "system-brand", brand, sz);
5917b8
+		dt_add_prop_sanitize_val(dt_root, "system-brand", brand, sz);
5917b8
 	else
5917b8
 		dt_add_property_string(dt_root, "brand", "Unknown");
5917b8
 }