From: Eric Biggers Date: Sat, 30 May 2015 20:48:00 +0000 (-0500) Subject: Fix tagged item parsing infinite loop when 32-bit and len=0xFFFFFFF8 X-Git-Tag: v1.8.2~119 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=fb9de673c23ece7e273d93a46c49e65cbe20a99a Fix tagged item parsing infinite loop when 32-bit and len=0xFFFFFFF8 --- diff --git a/NEWS b/NEWS index 81ae8539..50c21313 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +Version 1.8.2-BETA: + Fixed a bug: on 32-bit systems, the library would enter an infinite loop + if WIM image metadata was malformed in a very specific way. + Version 1.8.1: Fixed a bug in the LZX decompressor: malicious input data could cause out of bounds writes to memory (since wimlib v1.2.2). 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; }