On 12 Jan 2023, at 21:06, Vineet Gupta<vineetg@xxxxxxxxxxxx> wrote:
+static int
+decode_uleb128_safe(unsigned char **dpp, u32 *val, const unsigned char *p_end)
+{
+ unsigned char *bp = *dpp;
+ unsigned char byte;
+ unsigned int shift = 0;
+ u32 result = 0;
+ int ok = 0;Why not just do the return here?
+
+ while (bp < p_end) {
+ byte = *bp++;
+ result |= (byte & 0x7f) << shift;
+ if ((byte & 0x80) == 0) {
+ ok = 1;
+ break;
+Constructing such a p is UB, check s_len before instead.
+ case RV_ATTR_TAG_arch:
+ str = p;
+ s_len = strnlen(p, p_end - p) + 1;
+ p += s_len;
+ if (p > p_end)
+ goto bad_attr;From the ratified spec:
+ rv_elf_attr_str(tag, str);
+ break;
+
+ default:
+ if (decode_uleb128_safe(&p, &val, p_end))
"RISC-V attributes have a string value if the tag number is odd and an integer value if the tag number is even."
+This will hide bugs from sanitisers...
+ memset(buf, 0, RV_ATTR_SEC_SZ);
+ pos = phdr->p_offset;What if n is 0?
+ n = kernel_read(f, &buf, phdr->p_filesz, &pos);
+
+ if (n < 0)
+ return -EIO;
+
+ p = buf;
+ p_end = p + n;
+
+ /* sanity check format-version */
+ if (*p++ != 'A')
+ goto bad_elf;u32?
+
+ /*
+ * elf attribute section organized as Vendor sub-sections(s)
+ * {sub-section length, vendor name, vendor data}
+ * Vendor data organized as sub-subsection(s)
+ * {tag, sub-subsection length, attributes contents}
+ * Attribute contents organized as
+ * {tag, value} pair(s).
+ */
+ while ((p_end - p) >= 4) {
+ int sub_len, vname_len;
+n is the total amount read in, not the remaining amount.
+ sub_len = get_unaligned_le32(p);
+ if (sub_len <= 4 || sub_len > n)
+Confusing naming for sub-subsection variables.
+ /* Vendor data: sub-subsections(s) */
+ while (sub_len > 0) {
+ u32 tag, content_len;
+ unsigned char *sub_end, *sub_start = p;