Mailinglist Archive: opensuse-bugs (4295 mails)

< Previous Next >
[Bug 1039066] New: VUL-0: libxml2: heap-based buffer overflow (xmlDictComputeFastKey func)
  • From: bugzilla_noreply@xxxxxxxxxx
  • Date: Mon, 15 May 2017 11:38:44 +0000
  • Message-id: <bug-1039066-21960@http.bugzilla.suse.com/>
http://bugzilla.suse.com/show_bug.cgi?id=1039066


Bug ID: 1039066
Summary: VUL-0: libxml2: heap-based buffer overflow
(xmlDictComputeFastKey func)
Classification: openSUSE
Product: openSUSE Distribution
Version: Leap 42.2
Hardware: Other
OS: Other
Status: NEW
Severity: Normal
Priority: P5 - None
Component: Security
Assignee: security-team@xxxxxxx
Reporter: mikhail.kasimov@xxxxxxxxx
QA Contact: qa-bugs@xxxxxxx
Found By: ---
Blocker: ---

Ref: http://seclists.org/oss-sec/2017/q2/258
=============================================
+++++++++++++++++++++++++++++++++++++++++++++++
+ HEAP-BASED BUFFER OVERFLOW IN xmlDictComputeFastKey (NEW)
+ https://bugzilla.gnome.org/show_bug.cgi?id=781205
+++++++++++++++++++++++++++++++++++++++++++++++

We understand that a similar bug report (non-public) was filed before:
https://bugzilla.gnome.org/show_bug.cgi?id=759398
and fixed about a year ago in git revision 45752d2:
https://github.com/GNOME/libxml2/commit/45752d2c334b50016666d8f0ec3691e2d680f0a0

However, the patch was apparently incomplete.

How to reproduce with xmllint:
$ ./xmllint --version
/src/libxml2/.libs/lt-xmllint: using libxml version 20904-GITv2.9.4-16-g0741801
compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP
DTDValid HTML Legacy C14N Catalog XPath
XPointer XInclude Iconv ISO8859X Unicode Regexps Automata Expr Schemas
Schematron Modules Debug


$ printf "%s\x0d%s\x0da\x09%s" '<?l?><!DOCTYPED[<!ENTITY' '%' '"<:0000">%a;' >
bug3.xml
$ ./xmlint --memory --oldxml10 bug3.xml

ASAN says (for libxml2 in trunk):
=================================================================
==18512==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x60200000020f at pc 0x7fb731bca172 bp 0x7ffe8fe8cd10 sp 0x7ffe8fe8cd08
READ of size 1 at 0x60200000020f thread T0
#0 0x7fb731bca171 in xmlDictComputeFastKey /src/libxml2/dict.c:448:13
#1 0x7fb731bca171 in xmlDictLookup__internal_alias /src/libxml2/dict.c:851
#2 0x7fb7315f7760 in xmlParseNameComplex /src/libxml2/parser.c
#3 0x7fb7315f7760 in xmlParseName__internal_alias /src/libxml2/parser.c:3487
#4 0x7fb7316afe66 in xmlParseQName /src/libxml2/parser.c:8900:10
#5 0x7fb7316691c5 in xmlParseStartTag2 /src/libxml2/parser.c:9419:17
#6 0x7fb7316643dc in xmlParseElement__internal_alias
/src/libxml2/parser.c:10179:16
#7 0x7fb73167f758 in xmlParseDocument__internal_alias
/src/libxml2/parser.c:10962:2
#8 0x7fb7316ac7ac in xmlDoRead /src/libxml2/parser.c:15445:5
#9 0x7fb7316aceb4 in xmlReadMemory__internal_alias
/src/libxml2/parser.c:15531:13
#10 0x5214c0 in parseAndPrintFile /src/libxml2/xmllint.c:2371:9
#11 0x5184cd in main /src/libxml2/xmllint.c:3772:7
#12 0x7fb7305ff82f in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#13 0x41d2b8 in _start (/src/libxml2/.libs/lt-xmllint+0x41d2b8)

0x60200000020f is located 1 bytes to the left of 6-byte region
[0x602000000210,0x602000000216)
allocated by thread T0 here:
#0 0x4d8018 in malloc
/src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:66
#1 0x7fb7315f9fe3 in xmlNewBlanksWrapperInputStream
/src/libxml2/parser.c:2477:14
#2 0x7fb731642dd6 in xmlParsePEReference__internal_alias
/src/libxml2/parser.c:8122:14
#3 0x7fb73164218b in xmlParseMarkupDecl__internal_alias
/src/libxml2/parser.c:7031:2
#4 0x7fb731680e66 in xmlParseInternalSubset /src/libxml2/parser.c:8482:6
#5 0x7fb73167eec4 in xmlParseDocument__internal_alias
/src/libxml2/parser.c:10930:6
#6 0x7fb7316ac7ac in xmlDoRead /src/libxml2/parser.c:15445:5
#7 0x7fb7316aceb4 in xmlReadMemory__internal_alias
/src/libxml2/parser.c:15531:13
#8 0x5214c0 in parseAndPrintFile /src/libxml2/xmllint.c:2371:9
#9 0x5184cd in main /src/libxml2/xmllint.c:3772:7
#10 0x7fb7305ff82f in __libc_start_main
(/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /src/libxml2/dict.c:448:13 in
xmlDictComputeFastKey

Valgrind says (for my installed version of xmllint)
$ xmllint --version
xmllint: using libxml version 20903
compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP
DTDValid HTML Legacy C14N Catalog XPath
XPointer XInclude Iconv ISO8859X Unicode Regexps Automata Expr Schemas
Schematron Modules Debug Zlib Lzma

==38641== Invalid read of size 1
==38641== at 0x4F75CE8: xmlDictLookup (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E7C523: xmlParseName (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8503C: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E852EB: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8CE2E: xmlParseElement (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8D949: xmlParseDocument (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E947BD: xmlReadMemory (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x111F98: ??? (in /usr/bin/xmllint)
==38641== by 0x10EDFE: ??? (in /usr/bin/xmllint)
==38641== by 0x521582F: (below main) (libc-start.c:291)
==38641== Address 0x8303e7f is 1 bytes before a block of size 6 alloc'd
==38641== at 0x4C2DB8F: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==38641== by 0x4E75FCB: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8871F: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E88954: xmlParseMarkupDecl (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E89214: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8DB4E: xmlParseDocument (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E947BD: xmlReadMemory (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x111F98: ??? (in /usr/bin/xmllint)
==38641== by 0x10EDFE: ??? (in /usr/bin/xmllint)
==38641== by 0x521582F: (below main) (libc-start.c:291)
==38641==
==38641== Invalid read of size 1
==38641== at 0x4C32758: memcpy@@GLIBC_2.14 (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==38641== by 0x4F74FBD: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4F75C3C: xmlDictLookup (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E7C523: xmlParseName (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8503C: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E852EB: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8CE2E: xmlParseElement (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8D949: xmlParseDocument (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E947BD: xmlReadMemory (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x111F98: ??? (in /usr/bin/xmllint)
==38641== by 0x10EDFE: ??? (in /usr/bin/xmllint)
==38641== by 0x521582F: (below main) (libc-start.c:291)
==38641== Address 0x8303e7f is 1 bytes before a block of size 6 alloc'd
==38641== at 0x4C2DB8F: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==38641== by 0x4E75FCB: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8871F: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E88954: xmlParseMarkupDecl (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E89214: ??? (in /usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E8DB4E: xmlParseDocument (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x4E947BD: xmlReadMemory (in
/usr/lib/x86_64-linux-gnu/libxml2.so.2.9.3)
==38641== by 0x111F98: ??? (in /usr/bin/xmllint)
==38641== by 0x10EDFE: ??? (in /usr/bin/xmllint)
==38641== by 0x521582F: (below main) (libc-start.c:291)
==38641==
=============================================



=============================================
PATCHED BY:
--- a/parser.c
+++ a/parser.c
@@ -3312,6 +3312,7 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
int len = 0, l;
int c;
int count = 0;
+ size_t startPosition = 0;

#ifdef DEBUG
nbParseNameComplex++;
@@ -3323,6 +3324,7 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
GROW;
if (ctxt->instate == XML_PARSER_EOF)
return(NULL);
+ startPosition = CUR_PTR - BASE_PTR;
c = CUR_CHAR(l);
if ((ctxt->options & XML_PARSE_OLD10) == 0) {
/*
@@ -3420,9 +3422,11 @@ xmlParseNameComplex(xmlParserCtxtPtr ctxt) {
xmlFatalErr(ctxt, XML_ERR_NAME_TOO_LONG, "Name");
return(NULL);
}
- if ((*ctxt->input->cur == '\n') && (ctxt->input->cur[-1] == '\r'))
- return(xmlDictLookup(ctxt->dict, ctxt->input->cur - (len + 1), len));
- return(xmlDictLookup(ctxt->dict, ctxt->input->cur - len, len));
+
+ if (BASE_PTR + startPosition + len > ctxt->input->end)
+ return(NULL);
+
+ return(xmlDictLookup(ctxt->dict, BASE_PTR + startPosition, len));
}

/**

=============================================

(open-)SUSE: https://software.opensuse.org/package/libxml2

2.9.4 (TW, 42.2, official repo)
2.9.1 (42.1, official repo)

Upstream report -- https://bugzilla.gnome.org/show_bug.cgi?id=781205 -- has
'private' status.

--
You are receiving this mail because:
You are on the CC list for the bug.
< Previous Next >
This Thread
  • No further messages