GNOME Bugzilla – Bug 794914
DoS in libxml2 if liblzma-dev is installed (Different from Bug 757466)
Last modified: 2018-07-30 12:52:28 UTC
Created attachment 370463 [details] PoC to trigger Denial of Service Hi, we found a denial of service parsing a specially crafted xml file in libxml2 if liblzma-dev package is enabled. And we have attached a poc file that never finish the parsing process. The reproduction is : ``` mkdir obj-native cd obj-native/ git clone git://git.gnome.org/libxml2 env CFLAGS="-O2 -g -fstack-protector-all" ../configure --enable-static=yes --enable-shared=no make gdb ./xmllint (gdb) r poc -o /tmp/null Starting program: /tmp/libxml2/obj-native/xmllint poc -o /tmp/null Program received signal SIGINT, Interrupt. lzma_code (strm=strm@entry=0x761b08, action=action@entry=LZMA_FINISH) at ../../../../src/liblzma/common/common.c:247 247 ../../../../src/liblzma/common/common.c: No such file or directory. (gdb) info stack
+ Trace 238527
Some simple analysis for the loop: 577 ret = lzma_code(strm, action); 578 if (ret == LZMA_MEM_ERROR) { 579 xz_error(state, LZMA_MEM_ERROR, "out of memory"); 580 return -1; 581 } 582 if (ret == LZMA_DATA_ERROR) { 583 xz_error(state, LZMA_DATA_ERROR, "compressed data error"); 584 return -1; 585 } (gdb) 586 if (ret == LZMA_PROG_ERROR) { 587 xz_error(state, LZMA_PROG_ERROR, "compression error"); 588 return -1; 589 } 590 } while (strm->avail_out && ret != LZMA_STREAM_END); The ret variable in L577 is alway set to LZMA_MEMLIMIT_ERROR and strm->avail_out is not changed. So loop condition always hold true and this loop continues. It is not the same error with Bug 757466 or CVE-2015-8035, but similiar to it. And the patch could be like, + if (ret == LZMA_MEMLIMIT_ERROR) { + xz_error(state, LZMA_MEMLIMIT_ERROR, "memory limit error"); + return -1; + }
``` mkdir obj-native cd obj-native/ git clone git://git.gnome.org/libxml2 ``` => ``` git clone git://git.gnome.org/libxml2 cd libxml2 mkdir obj-native cd obj-native/ ```
Doing a bisect between v2.9.4 and 7a1bd7f6497ac33a9023d556f6f47a48f01deac0 seem to indicate that the hang happens only starting with upstream commit e2a9122b8dde53d320750451e9907a7dcb2ca8bb commit e2a9122b8dde53d320750451e9907a7dcb2ca8bb (refs/bisect/bad) Author: Nick Wellnhofer <wellnhofer@aevum.de> Date: Thu Sep 7 18:36:01 2017 +0200 Set memory limit for LZMA decompression Otherwise malicious LZMA compressed files could consume large amounts of memory when decompressed. According to the xz man page, files compressed with `xz -9` currently require 65 MB to decompress, so set the limit to 100 MB. Should fix bug 786696. $ git describe --contains e2a9122b8dde53d320750451e9907a7dcb2ca8bb v2.9.6-rc1~7
FTR, the scope of CVE-2018-9251 is 'is all builds of libxml2 in which "ret = lzma_code(strm, action)" (shown in 794914) can return the LZMA_MEMLIMIT_ERROR value, and trigger an infinite loop.' and so 'the call to "lzma_auto_decoder(&state->strm, UINT64_MAX, 0)" can never result in an LZMA_MEMLIMIT_ERROR outcome, because there is no way to exceed UINT64_MAX.' The issue fixed by e2a9122b8dde53d320750451e9907a7dcb2ca8bb itself was assigned a second CVE, namely CVE-2017-18258.
Fixed here: https://gitlab.gnome.org/GNOME/libxml2/commit/2240fbf5912054af025fb6e01e26375100275e74 Thanks for the report.