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