12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- From 08ab2774b870de1c7b5a48693df75e8154addae5 Mon Sep 17 00:00:00 2001
- From: Nick Wellnhofer <wellnhofer@aevum.de>
- Date: Thu, 12 Jan 2017 15:39:52 +0100
- Subject: [PATCH] Check for integer overflow in xsltAddTextString
- Limit buffer size in xsltAddTextString to INT_MAX. The issue can be
- exploited to trigger an out of bounds write on 64-bit systems.
- Originally reported to Chromium:
- https://crbug.com/676623
- ---
- libxslt/transform.c | 25 ++++++++++++++++++++++---
- libxslt/xsltInternals.h | 4 ++--
- 2 files changed, 24 insertions(+), 5 deletions(-)
- --- a/libxslt/transform.c
- +++ b/libxslt/transform.c
- @@ -718,13 +718,32 @@ xsltAddTextString(xsltTransformContextPt
- return(target);
-
- if (ctxt->lasttext == target->content) {
- + int minSize;
-
- - if (ctxt->lasttuse + len >= ctxt->lasttsize) {
- + /* Check for integer overflow accounting for NUL terminator. */
- + if (len >= INT_MAX - ctxt->lasttuse) {
- + xsltTransformError(ctxt, NULL, target,
- + "xsltCopyText: text allocation failed\n");
- + return(NULL);
- + }
- + minSize = ctxt->lasttuse + len + 1;
- +
- + if (ctxt->lasttsize < minSize) {
- xmlChar *newbuf;
- int size;
- + int extra;
- +
- + /* Double buffer size but increase by at least 100 bytes. */
- + extra = minSize < 100 ? 100 : minSize;
- +
- + /* Check for integer overflow. */
- + if (extra > INT_MAX - ctxt->lasttsize) {
- + size = INT_MAX;
- + }
- + else {
- + size = ctxt->lasttsize + extra;
- + }
-
- - size = ctxt->lasttsize + len + 100;
- - size *= 2;
- newbuf = (xmlChar *) xmlRealloc(target->content,size);
- if (newbuf == NULL) {
- xsltTransformError(ctxt, NULL, target,
- --- a/libxslt/xsltInternals.h
- +++ b/libxslt/xsltInternals.h
- @@ -1752,8 +1752,8 @@ struct _xsltTransformContext {
- * Speed optimization when coalescing text nodes
- */
- const xmlChar *lasttext; /* last text node content */
- - unsigned int lasttsize; /* last text node size */
- - unsigned int lasttuse; /* last text node use */
- + int lasttsize; /* last text node size */
- + int lasttuse; /* last text node use */
- /*
- * Per Context Debugging
- */
|