This bug is not present in U-Boot, but happens if you compile the TLV code base
with glibc.
For default or TLV_CODE_VENDOR_EXT types, the decoded value as a string is
incorrect and display only the last byte.
For example, if TLV contains type TLV_CODE_VENDOR_EXT with a length of 6,
and bytes "0x66 0x6F 0x6F 0x62 0x61 0x72", here is the decoded output:
TLV Name Code Len Value
-------------------- ---- --- -----
Vendor Extension 0xFD 6 0x72
The reason (also identified by GCC warning message below) is that the behavior
of glibc sprintf is undefined if copying takes place between objects that
overlap - for example, if s is also given as an argument to be printed under
control of the ‘%s’ conversion.
Fix by using strcat and sprintf with an intermediate variable.
This also has the nice benefit of fixing this warning:
In function ‘sprintf’,
inlined from ‘decode_tlv_value’ at tlv_eeprom.c:343:4:
...stdio2.h:30:10: warning: ‘__builtin___sprintf_chk’ argument 5 overlaps destination object ‘value’ [-Wrestrict]
30 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
value[0] = 0;
for (i = 0; (i < (DECODE_VALUE_MAX / 5)) && (i < tlv->length);
i++) {
- sprintf(value, "%s 0x%02X", value, tlv->value[i]);
+ char dec_val[DECODE_VALUE_MAX];
+
+ sprintf(dec_val, " 0x%02X", tlv->value[i]);
+ strcat(value, dec_val);
}
break;
}