Integer underflow on "uriToStringCharsRequired()"
jinhojun opened this issue · comments
While we are testing libxspf application, we found crash-inducing input and it turned out that the cause may arise from uriparser library. Please check the below report.
libxspf (1.2.0) and uriparser
Vulntype: Interger underflow
Affected component(s)
uriparser project (uriToStringCharsRequiredA function)
and then it affects
libxspf project(makeUriString function),
Attack vector(s)
Adversary sends crafted movie playlist file and victim opens it with media player which is using libxspf library (such as VLC player).
Suggested description of the vulnerability for use in the CVE
makeUriString() function from Xspf class trusts the return values (i.e., int* charsRequired) from uriparser library; thus assumes positive value.
However, "uriparser" library's uriToStringCharsRequired() functions returns negative value on crafted URI string such as "http://example.co@" (actually the function should return NULL).
Due to this integer underflow, the code meets crash with heap alloction failure.
- libxspf
XML_Char * makeUriString(UriUri const & uri) {
XML_Char * uriString;
int charsRequired;
if (uriToStringCharsRequired(&uri, &charsRequired) != URI_SUCCESS) {
// the uriparse should have return NULL!
return NULL;
}
charsRequired++;
// negative value are inserted to charsRequired (e.g., 0xffffffffff9e5331)
// allocator error here!
uriString = new XML_Char[charsRequired];
if (uriToString(uriString, &uri, charsRequired, NULL) != URI_SUCCESS) {
delete [] uriString;
return NULL;
}
return uriString;
}
Discoverer
Jinho Jung (jinho.jung@gatech.edu, Georgia Institute of Technology)
Reference
N/A
Additional Information
-
PoC:
https://ffs.gtisc.gatech.edu/download/ca3502e783138c47/#WQ_4uRrb_CSkyHvA5fpJMg -
How to reproduce
we use example application from libxspf
- find read.cpp file and modify the file name to PoC's
- compile and run the read program
- Another reproduce
- provide bad uri "http://example.co@" to uriToStringCharsRequired()
- the function should not return URI_SUCCESS
==> but it assigns negative value on charsRequired
Hi Jinho,
thanks for the report — I appreciate it! 👍
I'll get back to you on this when I had a chance at a closer look.
Best, Sebastian
Hi!
I had a chance at a first closer look now. What I found:
-
When I parse text
http://example.co@
usinguriParseUriW
and then calluriToStringCharsRequiredW
on the result I get 18 as expected. This is for code on Gitmaster
, i.e. 51bdd9a. -
While
http://example.co@
might look bad, it is a well-formed URI according to RFC 3986:
host is present but empty, user info isexample.co
. It can be seen at https://tools.ietf.org/html/rfc3986#appendix-A where this is the relevant excerpt from the ABNF grammar:
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
authority = [ userinfo "@" ] host [ ":" port ]
host = IP-literal / IPv4address / reg-name
reg-name = *( unreserved / pct-encoded / sub-delims )
For our case we get:
scheme = "http"
userinfo = "example.co"
host = reg-name = ""
-
I am not sure which
read.cpp
you are referring to. I cannot find the code above in libxspf'sexamples/read/read.cpp
. -
The PoC link of Firefox Send says
This link has expired
.
Please help me understand the issue in detail.
Thanks for the checking.
- the
read.cpp
is from here:
https://github.com/ezdev128/libxspf/blob/master/examples/read/read.cpp
I found the problem while taking a look at the libxspf project. The application utilizes uriparser.
- PoC File upload again:
https://gts3.org/~jjung/poc/uriparser/poc_200207
Thanks for the checking.
1. the `read.cpp` is from here: https://github.com/ezdev128/libxspf/blob/master/examples/read/read.cpp
I cannot find any of the makeUriString
code quoted above in there or even something similar. Is this the correct link for the code you tested?
1. PoC File upload again: https://gts3.org/~jjung/poc/uriparser/poc_200207
When I run this file against the read
example I get this error output, no crash:
# ./examples/read/example_read
Error 8 at (line 5, column 39): 'Content of 'http://xspf.org/ns/0/ location' is not a valid URI.'
Error 8 at (line 12, column 0): 'Content of 'http://xspf.org/ns/0/ track' must be whitespace or child elements, not text.'
Track
Album: -
Annotation: 'song'
Creator: 'Lein'
Duration: '271066'
Identifier: 0 entries
Image: 'file:///tmp/tmp.1Q2l4i6fcC/libxspf/http.com/images/P/B000002J0B.01.MZZZZZZZ.jpg'
Info: 'http://example.co@'
Links: 0 entries
Locations: 0 entries
Metas: 0 entries
Title: 'Nr'
TrackNum: -
Error 8 at (line 28, column 0): 'Content of 'http://xspf.org/ns/0/ trackList' must be whitespace or child elements, not text.'
What am I missing?
I just double check all processes to reproduce the crash and still find problem.
- install uriparser (compiled from github source)
- compile libxspf
- in my environment, I changed line 235 (PORT_GETCWD ==> getcwd) and added
#include <unistd.h
to avoid compilation error (libxspf/examples/read/read.cpp
)
- download
poc_200207
file and overwrite asplaylist.xspf
- run
example_read
./example_read
Error 8 at (line 5, column 39): 'Content of 'http://xspf.org/ns/0/ location' is not a valid URI.'
Error 8 at (line 12, column 0): 'Content of 'http://xspf.org/ns/0/ track' must be whitespace or child elements, not text.'
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
[1] 24214 abort (core dumped) ./example_read x
* Environment
- OS release
Ubuntu 18.04.4 LTS
- Kernel
Linux jjung-900X5L 5.3.0-40-generic #32~18.04.1-Ubuntu SMP Mon Feb 3 14:05:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
I cannot confirm any bad allocations or bad memory access, only a memory leak. Here's what I did in precise detail:
# cd "$(mktemp -d)"
# git clone --depth 1 https://github.com/uriparser/uriparser/
# cd uriparser/
# git rev-parse HEAD
51bdd9a3cb70c9020715cfe883f606cd5b995b7a
# ./configure -DCMAKE_INSTALL_PREFIX="$PWD"/../prefix/ -DCMAKE_C_COMPILER=clang-9 -DCMAKE_CXX_COMPILER=clang++-9 CMAKE_C_FLAGS='-O1 -g -fsanitize=address -fno-omit-frame-pointer' -DCMAKE_CXX_FLAGS='-O1 -g -fsanitize=address -fno-omit-frame-pointer' LDFLAGS='-fsanitize=address' -DURIPARSER_BUILD_DOCS=OFF && make install
# cd ..
# git clone --depth 1 https://github.com/ezdev128/libxspf/
# cd libxspf/
# git rev-parse HEAD
ba71431e24293510c44d6581e2c05b901a372880
# wget https://gist.githubusercontent.com/hartwork/fa2bf3ebfbaed32f405e7f267c1a9e5b/raw/2d1fc7f7b6ac6cea533cac3574ed4a5385779342/libxspf-1-2-compile.patch
# patch -p1 < libxspf-1-2-compile.patch
# autoreconf -i -f && PKG_CONFIG_PATH="$PWD"/../prefix/lib64/pkgconfig/ ./configure CC=clang-9 CXX=clang++-9 CFLAGS='-O1 -g -fsanitize=address -fno-omit-frame-pointer' CXXFLAGS='-O1 -g -fsanitize=address -fno-omit-frame-pointer' LDFLAGS='-fsanitize=address' --disable-test && make
# wget -Oplaylist.xspf https://gts3.org/~jjung/poc/uriparser/poc_200207
# LD_LIBRARY_PATH="$PWD"/../prefix/lib64/ ./examples/read/example_read
Error 8 at (line 5, column 39): 'Content of 'http://xspf.org/ns/0/ location' is not a valid URI.'
Error 8 at (line 12, column 0): 'Content of 'http://xspf.org/ns/0/ track' must be whitespace or child elements, not text.'
Track
Album: -
Annotation: 'song'
Creator: 'Lein'
Duration: '271066'
Identifier: 0 entries
Image: 'file:///tmp/tmp.rje08pzEEs/libxspf/http.com/images/P/B000002J0B.01.MZZZZZZZ.jpg'
Info: 'http://example.co@'
Links: 0 entries
Locations: 0 entries
Metas: 0 entries
Title: 'Nr'
TrackNum: -
Error 8 at (line 28, column 0): 'Content of 'http://xspf.org/ns/0/ trackList' must be whitespace or child elements, not text.'
=================================================================
==16704==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 80 byte(s) in 1 object(s) allocated from:
#0 0x4c2e3d in operator new[](unsigned long) /var/tmp/portage/sys-libs/compiler-rt-sanitizers-9.0.1/work/compiler-rt/lib/asan/asan_new_delete.cc:102:3
#1 0x7f6adf239f60 in Xspf::Toolbox::(anonymous namespace)::makeUriString(UriUriStructA const&) /tmp/tmp.rje08pzEEs/libxspf/src/XspfToolbox.cpp:209:14
#2 0x7f6adf2395b5 in Xspf::Toolbox::(anonymous namespace)::allocTransformUri(char const*, char const*, bool) /tmp/tmp.rje08pzEEs/libxspf/src/XspfToolbox.cpp:262:31
#3 0x7f6adf22ea96 in Xspf::XspfReader::handleEndFour(char const*) /tmp/tmp.rje08pzEEs/libxspf/src/XspfReader.cpp:1931:30
#4 0x7f6adf22f49c in Xspf::XspfReader::handleEnd(char const*) /tmp/tmp.rje08pzEEs/libxspf/src/XspfReader.cpp:2074:9
#5 0x7f6adf120a2c (/usr/lib64/libexpat.so.1+0xba2c)
Direct leak of 19 byte(s) in 1 object(s) allocated from:
#0 0x4c2e3d in operator new[](unsigned long) /var/tmp/portage/sys-libs/compiler-rt-sanitizers-9.0.1/work/compiler-rt/lib/asan/asan_new_delete.cc:102:3
#1 0x7f6adf239f60 in Xspf::Toolbox::(anonymous namespace)::makeUriString(UriUriStructA const&) /tmp/tmp.rje08pzEEs/libxspf/src/XspfToolbox.cpp:209:14
#2 0x7f6adf2395b5 in Xspf::Toolbox::(anonymous namespace)::allocTransformUri(char const*, char const*, bool) /tmp/tmp.rje08pzEEs/libxspf/src/XspfToolbox.cpp:262:31
#3 0x7f6adf22ea0d in Xspf::XspfReader::handleEndFour(char const*) /tmp/tmp.rje08pzEEs/libxspf/src/XspfReader.cpp:1943:29
#4 0x7f6adf22f49c in Xspf::XspfReader::handleEnd(char const*) /tmp/tmp.rje08pzEEs/libxspf/src/XspfReader.cpp:2074:9
#5 0x7f6adf120a2c (/usr/lib64/libexpat.so.1+0xba2c)
SUMMARY: AddressSanitizer: 99 byte(s) leaked in 2 allocation(s).
I reproduced with these commands:
$ cd "$(mktemp -d)"
$ git clone https://github.com/uriparser/uriparser/
$ cd uriparser/
$ ./configure -DURIPARSER_BUILD_DOCS=OFF -DURIPARSER_BUILD_TESTS=OFF
$ make && sudo make install
$ cd ..
$ git clone https://github.com/ezdev128/libxspf/
$ cd libxspf/
$ wget https://gts3.org/~jjung/poc/uriparser/libxspf-getcwd.patch
$ patch -p1 < libxspf-getcwd.patch
$ ./configure
$ make
$ cd examples/read
$ wget -Oplaylist.xspf https://gts3.org/~jjung/poc/uriparser/poc_200207
$ ./example_read
- OS release
Ubuntu 18.04.4 LTS
I have tried to reproduce the issue with Ubuntu 18.04.4 now using the Dockerfile
inlined below based on your script — it doesn't crash. Does this crash for you?
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get --yes --no-install-recommends dist-upgrade && \
apt-get install --yes --no-install-recommends \
build-essential \
ca-certificates \
cmake \
file \
git \
libexpat-dev \
libtool \
lsb-release \
pkg-config \
wget
RUN git clone https://github.com/uriparser/uriparser && \
git clone https://github.com/ezdev128/libxspf
RUN cd libxspf/examples/read && \
wget -Oplaylist.xspf https://gts3.org/~jjung/poc/uriparser/poc_200207
RUN cd uriparser/ && \
./configure -DURIPARSER_BUILD_DOCS=OFF -DURIPARSER_BUILD_TESTS=OFF && \
make && make install
RUN cd libxspf/ && \
wget https://gts3.org/~jjung/poc/uriparser/libxspf-getcwd.patch && \
patch -p1 < libxspf-getcwd.patch
RUN cd libxspf/ && \
./configure --disable-test && \
make
RUN lsb_release -a
RUN cd libxspf/examples/read && \
{ LD_LIBRARY_PATH=/usr/local/lib ./example_read || echo $? ; }
Also, could you provide the output of:
ldd ./example_read
gdb -batch -ex run -ex bt --args ./example_read
The output of the latter potentially benefits from a re-build with CFLAGS=-g CXXFLAGS=-g
to get line numbers and function names rather than hex addresses.
Thank you!
I will try Docker when I am available. This is the quick result.
- ldd
linux-vdso.so.1 (0x00007ffd2d1f2000)
libxspf.so.4 => /usr/local/lib/libxspf.so.4 (0x00007f5cda46b000)
liburiparser.so.1 => /usr/lib/x86_64-linux-gnu/liburiparser.so.1 (0x00007f5cda250000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f5cd9ec7000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f5cd9caf000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5cd98be000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007f5cd968c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5cd92ee000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5cda8a0000)
- gdb
Error 8 at (line 5, column 39): 'Content of 'http://xspf.org/ns/0/ location' is not a valid URI.'
Error 8 at (line 12, column 0): 'Content of 'http://xspf.org/ns/0/ track' must be whitespace or child elements, not text.'
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007ffff7037801 in __GI_abort () at abort.c:79
#2 0x00007ffff768c957 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7692ab6 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7692af1 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff7692d24 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6 0x00007ffff769329c in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7 0x00007ffff7bc57bb in Xspf::Toolbox::(anonymous namespace)::makeUriString (uri=...) at src/XspfToolbox.cpp:209
#8 Xspf::Toolbox::(anonymous namespace)::allocTransformUri (sourceUri=sourceUri@entry=0x55555576d0c0 "http://example.co@", baseUri=0x55555576d040 "file:///tmp/tmp.wyuAGRnNeI/libxspf/examples/read/playlist.xspf", addOrRemoveBase=addOrRemoveBase@entry=true) at src/XspfToolbox.cpp:262
#9 0x00007ffff7bc5a7a in Xspf::Toolbox::makeAbsoluteUri (sourceUri=sourceUri@entry=0x55555576d0c0 "http://example.co@", baseUri=<optimized out>) at src/XspfToolbox.cpp:275
#10 0x00007ffff7bbef93 in Xspf::XspfReader::makeAbsoluteUri (this=this@entry=0x7fffffffdd30, sourceUri=sourceUri@entry=0x55555576d0c0 "http://example.co@") at src/XspfReader.cpp:555
#11 0x00007ffff7bbfbe8 in Xspf::XspfReader::handleEndFour (this=this@entry=0x7fffffffdd30) at src/XspfReader.cpp:1943
#12 0x00007ffff7bc2ae6 in Xspf::XspfReader::handleEnd (this=0x7fffffffdd30, fullName=0x55555576c4d0 "http://xspf.org/ns/0/ info") at src/XspfReader.cpp:2074
#13 0x00007ffff6dcfe28 in ?? () from /lib/x86_64-linux-gnu/libexpat.so.1
#14 0x00007ffff6dd0bfc in ?? () from /lib/x86_64-linux-gnu/libexpat.so.1
#15 0x00007ffff6dce823 in ?? () from /lib/x86_64-linux-gnu/libexpat.so.1
#16 0x00007ffff6dcf50b in ?? () from /lib/x86_64-linux-gnu/libexpat.so.1
#17 0x00007ffff6dd30ed in XML_ParseBuffer () from /lib/x86_64-linux-gnu/libexpat.so.1
#18 0x00007ffff7bc1bd4 in Xspf::XspfReader::parseFile (this=0x7fffffffdd30, filename=<optimized out>, callback=<optimized out>, baseUri=<optimized out>) at src/XspfReader.cpp:619
#19 0x00005555555559f6 in main () at examples/read/read.cpp:263
I found the problem. My machine previously installed liburiparser1
before the test.
After I purge the library, I don't see the error message anymore.
To produce the error, please install liburiparser1
thru APT manager.
I found the problem. My machine previously installed
liburiparser1
before the test.After I purge the library, I don't see the error message anymore.
Yes, because this line in ldd
…
liburiparser.so.1 => /usr/lib/x86_64-linux-gnu/liburiparser.so.1 (0x00007f5cda250000)
…indicates that:
- libxspf was linked against uriparser from Ubuntu, likely version 0.8.4-1, not the manual install to
/usr/local/
- uriparser of Git
master
does not trigger this problem — awesome!
There is a pile of changes including security fixes that Ubuntu bionic does not ship with 0.8.4-1, see this this part of Changelog
.
Here's the full Dockerfile
to reproduce the crash case with Ubuntu 18.04 / uriparser 0.8.4-1:
FROM ubuntu:18.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get --yes --no-install-recommends dist-upgrade && \
apt-get install --yes --no-install-recommends \
build-essential \
ca-certificates \
cmake \
file \
gdb \
git \
libexpat-dev \
libtool \
liburiparser-dev \
lsb-release \
pkg-config \
wget
RUN git clone https://github.com/ezdev128/libxspf
RUN cd libxspf/examples/read && \
wget -Oplaylist.xspf https://gts3.org/~jjung/poc/uriparser/poc_200207
RUN cd libxspf/ && \
wget https://gts3.org/~jjung/poc/uriparser/libxspf-getcwd.patch && \
patch -p1 < libxspf-getcwd.patch
RUN cd libxspf/ && \
./configure --disable-test && \
make
RUN lsb_release -a
RUN cd libxspf/examples/read && \
LD_LIBRARY_PATH=../../.libs/ gdb -batch -ex run -ex bt --args ./.libs/example_read
Changing ubuntu:18.04
to debian:buster
"fixes" the problem.
(Reminds me of https://blog.hartwork.org/posts/why-i-recommend-debian-over-ubuntu-by-now/ .)
I'll close this issue as already fixed then.
Thanks for taking care of the issue thoroughly.
I will test with the dev head version later.
For the record, the official libxspf sources at https://gitlab.xiph.org/xiph/libxspf have been updated with the fixes mentioned above and a bit more. So libxspf should now compile out of the box, again.