[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