[Skiboot] [PATCH v2 1/2] vpd: Sanitize VPD data
ppaidipe
ppaidipe at linux.vnet.ibm.com
Wed Jun 27 23:09:12 AEST 2018
On 2018-06-26 16:50, Vasant Hegde wrote:
> 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 at linux.vnet.ibm.com>
> Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
> ---
Tested-by: Pridhiviraj Paidipeddi <ppaidipe at linux.vnet.ibm.com>
> Changes in v2:
> - Added logic to verify property exists or not before creating new
> one
>
> -Vasant
>
> hdata/vpd.c | 71
> ++++++++++++++++++++++++++++++++++++++++++-------------------
> 1 file changed, 49 insertions(+), 22 deletions(-)
>
> diff --git a/hdata/vpd.c b/hdata/vpd.c
> index 038569af0..98123e5a6 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");
> }
More information about the Skiboot
mailing list