Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buffer overflow caused by exhaustive memory usage #980

Closed
5hadowblad3 opened this issue Aug 9, 2019 · 4 comments
Closed

Buffer overflow caused by exhaustive memory usage #980

5hadowblad3 opened this issue Aug 9, 2019 · 4 comments
Assignees
Labels
notReproducible Reported bugs not confirmed
Milestone

Comments

@5hadowblad3
Copy link

There is a buffer overflow in exiv2 in file types.cpp.

Distributor ID: Ubuntu
Description: Ubuntu 16.04.6 LTS
Release: 16.04
Codename: xenial
gcc: 5.4.0

The compile command is:
cmake ./ ;make

To reproduce the issue, run:
./exiv2 input

Here is the trace reported by asan:

#0 0x7faff55ba631 (/usr/lib/x86_64-linux-gnu/libasan.so.2+0xa0631)
#1 0x7faff55bf5e3 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0xa55e3)
#2 0x7faff5537425 (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x1d425)
#3 0x7faff55bd865 (/usr/lib/x86_64-linux-gnu/libasan.so.2+0xa3865)
#4 0x7faff553cb4d (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x22b4d)
#5 0x7faff55b367e in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9967e)
#6 0x7faff0f63d25 in Exiv2::DataBuf::DataBuf(long) /home/heqing/playground/exiv2-0.27.1-Source-a/src/types.cpp:141
#7 0x7faff0dc8995 in Exiv2::RafImage::readMetadata() /home/heqing/playground/exiv2-0.27.1-Source-a/src/rafimage.cpp:300
#8 0x77b36d in Action::Print::printSummary() /home/heqing/playground/exiv2-0.27.1-Source-a/src/actions.cpp:286
#9 0x79935f in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&) /home/heqing/playground/exiv2-0.27.1-Source-a/src/actions.cpp:246
#10 0x410f18 in main /home/heqing/playground/exiv2-0.27.1-Source-a/src/exiv2.cpp:169
#11 0x7fafecfe282f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#12 0x41abb8 in _start (/home/heqing/playground/exiv2-0.27.1-Source-a/build/bin/exiv2+0x41abb8)

The reason is that DataBuf in types.cpp does not check the malloced buffer is a null pointer or not yet directly use memcpy to write the buffer.
image

The attachment is the poc input.
poc_input2.zip

@5hadowblad3 5hadowblad3 added the bug label Aug 9, 2019
@clanmills clanmills added this to the v0.27.3 milestone Aug 9, 2019
@clanmills clanmills self-assigned this Aug 9, 2019
@clanmills
Copy link
Collaborator

Thank you for reporting this.

I am unable to reproduce your report.

I have build 0.27.1-Source on Ubuntu 18.04
and 0.27.2 (the current release)
and master (the development branch)

rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/exiv2-0.27.1-Source/asan_build$ ls -l /media/psf/Home/Downloads/poc_input2
-rw------- 1 rmills rmills 25 Aug  9 09:45 /media/psf/Home/Downloads/poc_input2
rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/exiv2-0.27.1-Source/asan_build$ bin/exiv2 /media/psf/Home/Downloads/poc_input2
Exiv2 exception in print action for file /media/psf/Home/Downloads/poc_input2:
Failed to read image data
rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/exiv2-0.27.1-Source/asan_build$ 

@5hadowblad3
Copy link
Author

5hadowblad3 commented Aug 9, 2019

This one is reproducible on my server with exiv2 0.27.1.

I use
cmake ../ ; make
to compile the project.

Maybe this related to the system environment?
But the reason is that exiv2 try to allocate a very large memory space from the heap, 0xfffffffffffffff4 bytes without prior checking or failure handling.

==182864==WARNING: AddressSanitizer failed to allocate 0xfffffffffffffff4 bytes
==182864==AddressSanitizer's allocator is terminating the process instead of returning 0
==182864==If you don't like this behavior set allocator_may_return_null=1
==182864==AddressSanitizer CHECK failed: ../../../../src/libsanitizer/sanitizer_common/sanitizer_allocator.cc:147 "((0)) != (0)" (0x0, 0x0)
#0 0x7f02ba1ec631 (/usr/lib/x86_64-linux-gnu/libasan.so.2+0xa0631)
#1 0x7f02ba1f15e3 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0xa55e3)
#2 0x7f02ba169425 (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x1d425)
#3 0x7f02ba1ef865 (/usr/lib/x86_64-linux-gnu/libasan.so.2+0xa3865)
#4 0x7f02ba16eb4d (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x22b4d)
#5 0x7f02ba1e567e in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x9967e)
#6 0x7f02b5b95d25 in Exiv2::DataBuf::DataBuf(long) /home/heqing/playground/exiv2-0.27.1-Source-a/src/types.cpp:141
#7 0x7f02b59fa995 in Exiv2::RafImage::readMetadata() /home/heqing/playground/exiv2-0.27.1-Source-a/src/rafimage.cpp:300
#8 0x77b36d in Action::Print::printSummary() /home/heqing/playground/exiv2-0.27.1-Source-a/src/actions.cpp:286
#9 0x79935f in Action::Print::run(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&) /home/heqing/playground/exiv2-0.27.1-Source-a/src/actions.cpp:246
#10 0x410f18 in main /home/heqing/playground/exiv2-0.27.1-Source-a/src/exiv2.cpp:169
#11 0x7f02b1c1482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#12 0x41abb8 in _start (/home/heqing/playground/exiv2-0.27.1-Source-a/build/bin/exiv2+0x41abb8)

image

It cannot produce at the 0.27.2 version with this input, but I have checked the code which is the same to the 0.27.1 version.
I think the reason is that there are some upper-level check for the file format,
however, the unhandled exhaustive memory usage can still cause the problem if this part of the code is reached.

@clanmills
Copy link
Collaborator

Thanks. We're working together.

I've built 0.27.1, 0.27.2 and master without ASAN on Ubuntu and get:
0.27.1

rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/exiv2-0.27.1-Source/build$ bin/exiv2 --version | head -1
exiv2 0.27.1
rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/exiv2-0.27.1-Source/build$ bin/exiv2 /media/psf/Home/Downloads/poc_input2
Uncaught exception: std::bad_alloc

0.27.2

rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/0.27-maintenance/build$ bin/exiv2 --version | head -1
exiv2 0.27.2
rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/0.27-maintenance/build$ bin/exiv2 /media/psf/Home/Downloads/poc_input2
Exiv2 exception in print action for file /media/psf/Home/Downloads/poc_input2:
Failed to read image data
rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/0.27-maintenance/build$

master:

rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/master/build$ bin/exiv2 --version | head -1
exiv2 0.27.99.0
rmills@rmillsmm-ubuntu:~/gnu/github/exiv2/master/build$ bin/exiv2 /media/psf/Home/Downloads/poc_input2
Exiv2 exception in print action for file /media/psf/Home/Downloads/poc_input2:
Failed to read image data

We added a check a couple of years ago:

if (alloc_size > file.size() ) throw crazy_alloc;

I think poc_input2 uses a code path that didn't have that test. And it's been fixed in 0.27.2 and master. I'm going to close this issue. However happy to re-open and continue the discussion if you wish.

Thank You very much for looking into this and the other issue you reported earlier. We take security and crashes very seriously. We have quarterly "dot" releases of Exiv2 v0.27 to ensure that fixes can be adopted quickly in the field.

@clanmills clanmills added notReproducible Reported bugs not confirmed and removed bug labels Aug 9, 2019
@msmeissn
Copy link

Fixed by commit 109d5df
Author: Kevin Backhouse kev@semmle.com
Date: Thu May 16 14:30:12 2019 +0100

Check bounds of jpg_img_off and jpg_img_len. (#858)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
notReproducible Reported bugs not confirmed
Projects
None yet
Development

No branches or pull requests

3 participants