X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Ftagged_items.c;h=1ae227c85f551b6afb65a98aa9c6b694674fb9c3;hp=e3ba53f496612c7d95e8dabaa12d3512865edca6;hb=fb9de673c23ece7e273d93a46c49e65cbe20a99a;hpb=fad3fab0e85346f6c1d5111d84d5ecfb6bc99249;ds=sidebyside diff --git a/src/tagged_items.c b/src/tagged_items.c index e3ba53f4..1ae227c8 100644 --- a/src/tagged_items.c +++ b/src/tagged_items.c @@ -44,12 +44,7 @@ struct tagged_item_header { le32 tag; /* Size of the data of this tagged item, in bytes. This excludes this - * header and should be a multiple of 8. - * - * (Actually, the MS implementation seems to round this up to an 8 byte - * boundary when calculating the offset to the next tagged item, but - * uses this length unmodified when validating the item. We might as - * well do the same.) */ + * header and should be a multiple of 8. */ le32 length; /* Variable length data */ @@ -90,14 +85,16 @@ inode_get_tagged_item(const struct wim_inode *inode, hdr = (struct tagged_item_header *)p; tag = le32_to_cpu(hdr->tag); - len = le32_to_cpu(hdr->length); + len = (le32_to_cpu(hdr->length) + 7) & ~7; + /* Length overflow? */ + if (unlikely(len > len_remaining - sizeof(struct tagged_item_header))) + return NULL; + + /* Matches the item we wanted? */ if (tag == desired_tag && len >= min_data_len) return hdr->data; - len = (len + 7) & ~7; - if (len_remaining <= sizeof(struct tagged_item_header) + len) - return NULL; len_remaining -= sizeof(struct tagged_item_header) + len; p += sizeof(struct tagged_item_header) + len; }