Closed Bug 1274777 (CVE-2016-9063) Opened 9 years ago Closed 8 years ago

Possible integer overflow to fix inside XML_Parse in expat

Categories

(Core :: XML, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla50
Tracking Status
firefox50 --- fixed

People

(Reporter: gustavo.grieco, Assigned: erahm)

Details

(Keywords: csectype-intoverflow, sec-low, Whiteboard: [adv-main50+] btpp-active)

Attachments

(1 file)

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0) Gecko/20100101 Firefox/46.0 Build ID: 20160425115534 Steps to reproduce: Possible integer overflow in XML_Parse: https://github.com/mozilla/gecko-dev/blob/7b9ea8afc579378606ecf3593b04fc2aaba7daec/parser/expat/lib/xmlparse.c#L1568
Added erahm, since he told me to create a different report for this possible issue here: https://bugzilla.mozilla.org/show_bug.cgi?id=1236923#c41
Summary: Possible integer overflow to fix inside XML_Parse in expat 2.1.0 → Possible integer overflow to fix inside XML_Parse in expat
Attached patch Check for oveflow (deleted) — Splinter Review
Attachment #8755538 - Flags: review?(peterv)
Assignee: nobody → erahm
Status: UNCONFIRMED → ASSIGNED
Ever confirmed: true
Group: core-security → dom-core-security
Comment on attachment 8755538 [details] [diff] [review] Check for oveflow Review of attachment 8755538 [details] [diff] [review]: ----------------------------------------------------------------- It seems that there are other checks to do in this file. I just gave a quick glance, but there are many sizes done like: int neededSize = len + (int)(bufferEnd - bufferPtr); Maybe would be nice to fix/check/analyze them too in a follow up. ::: parser/expat/lib/xmlparse.c @@ +1568,3 @@ > char *temp; > +/* BEGIN MOZILLA CHANGE (check for overflow) */ > + int newLen = len * 2; CheckedInt<int> @@ +1586,5 @@ > eventPtr = eventEndPtr = NULL; > processor = errorProcessor; > return XML_STATUS_ERROR; > } > + bufferLim = buffer + newLen; Also this can overflow. We should use: CheckedInt<int> buffer; buffer += newLen; if (!buffer.isValid()) { something; } bufferLim = buffer.value();
(In reply to Andrea Marchesini (:baku) from comment #3) > Comment on attachment 8755538 [details] [diff] [review] > Check for oveflow > > Review of attachment 8755538 [details] [diff] [review]: > ----------------------------------------------------------------- > > It seems that there are other checks to do in this file. I just gave a quick > glance, but there are many sizes done like: > int neededSize = len + (int)(bufferEnd - bufferPtr); > > Maybe would be nice to fix/check/analyze them too in a follow up. > > ::: parser/expat/lib/xmlparse.c > @@ +1568,3 @@ > > char *temp; > > +/* BEGIN MOZILLA CHANGE (check for overflow) */ > > + int newLen = len * 2; > > CheckedInt<int> This is C. > > @@ +1586,5 @@ > > eventPtr = eventEndPtr = NULL; > > processor = errorProcessor; > > return XML_STATUS_ERROR; > > } > > + bufferLim = buffer + newLen; > > Also this can overflow. We should use: > > CheckedInt<int> buffer; > buffer += newLen; > if (!buffer.isValid()) { > something; > } > > bufferLim = buffer.value(); I thought about this, I can't imagine a situation where the allocator can allocate a block of memory that extends past the addressable heap.
Whiteboard: btpp-active
Comment on attachment 8755538 [details] [diff] [review] Check for oveflow Review of attachment 8755538 [details] [diff] [review]: ----------------------------------------------------------------- ::: parser/expat/lib/xmlparse.c @@ +1576,3 @@ > temp = (buffer == NULL > + ? (char *)MALLOC(newLen) > + : (char *)REALLOC(buffer, newLen)); Hmm, I think we normally put all changes inside the MOZILLA CHANGE comments and ifdef out the old code. So something like: /* BEGIN MOZILLA CHANGE (check for overflow) */ #if 0 temp = (buffer == NULL ? (char *)MALLOC(len * 2) : (char *)REALLOC(buffer, len * 2)); #else int newLen = len * 2; if (newLen < 0) { errorCode = XML_ERROR_NO_MEMORY; return XML_STATUS_ERROR; } temp = (buffer == NULL ? (char *)MALLOC(newLen) : (char *)REALLOC(buffer, newLen)); #endif /* END MOZILLA CHANGE */ That way if the change does get merged back from upstream the diff shoul donly show removal. @@ +1586,5 @@ > eventPtr = eventEndPtr = NULL; > processor = errorProcessor; > return XML_STATUS_ERROR; > } > + bufferLim = buffer + newLen; buffer and bufferLim are const char*, so I'm not sure what you mean.
Attachment #8755538 - Flags: review?(peterv) → review+
Oh that pattern makes sense now, I'll update with the ifdef.
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla50
Group: dom-core-security → core-security-release
Flags: sec-bounty?
Minusing for a bounty without demonstration. If expat has had a FIXME for years and no one's exploited it or filed a bug it may not be reachable in practice.
Flags: sec-bounty? → sec-bounty-
Gustavo, Did this bug get a CVE elsewhere? Did you report this to Expat directly?
Flags: needinfo?(gustavo.grieco)
> Did this bug get a CVE elsewhere? Nop > Did you report this to Expat directly? Yes, but for some reason they haven't changed the code. I think they said it was unreachable ..
Flags: needinfo?(gustavo.grieco)
Whiteboard: btpp-active → [adv-main50+] btpp-active
Alias: CVE-2016-9063
Group: core-security-release
Flags: sec-bounty-hof-
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: