Opened 8 years ago

Last modified 8 years ago

#10485 assigned Bugs

heap-use-after-free using C++11 range loop

Reported by: iamvfx@… Owned by: Beman Dawes
Milestone: To Be Determined Component: filesystem
Version: Boost 1.54.0 Severity: Problem
Keywords: Cc:

Description

Repro code:

#include <stdio.h>
#include <boost/filesystem.hpp>

int main() {
    boost::filesystem::path dir("/");
    for (char c : dir.filename().string())
        printf("%c\n", c);
}

I know if I want to fix it I should store dir.filename().string() in a variable (and it works), but in this case it will either crash application or print garbage. Here's what Clang Address Sanitizer prints:

=================================================================
==12324==ERROR: AddressSanitizer: heap-use-after-free on address 0x60300000ef50 at pc 0x48448a bp 0x7fff08f73990 sp 0x7fff08f73988
READ of size 8 at 0x60300000ef50 thread T0
    #0 0x484489 in std::string::size() const /usr/bin/../lib/gcc/x86_64-redhat-linux/4.8.3/../../../../include/c++/4.8.3/bits/basic_string.h:716
    #1 0x484489 in ~path /usr/bin/../lib/gcc/x86_64-redhat-linux/4.8.3/../../../../include/c++/4.8.3/bits/basic_string.h:636
    #2 0x484489 in main /run/media/constantine/Space/Boost_1.54.0_Bug_Repro_09.07.2014/main.cpp:6
    #3 0x7f0679cd0d64 in __libc_start_main (/lib64/libc.so.6+0x21d64)
    #4 0x483f1c in _start (/run/media/constantine/Space/Boost_1.54.0_Bug_Repro_09.07.2014/Debug/app+0x483f1c)

0x60300000ef50 is located 0 bytes inside of 26-byte region [0x60300000ef50,0x60300000ef6a)
freed by thread T0 here:
    #0 0x46e7b9 in operator delete(void*) (/run/media/constantine/Space/Boost_1.54.0_Bug_Repro_09.07.2014/Debug/app+0x46e7b9)
    #1 0x4843f2 in std::string::_M_rep() const /usr/bin/../lib/gcc/x86_64-redhat-linux/4.8.3/../../../../include/c++/4.8.3/bits/basic_string.h:249
    #2 0x4843f2 in ~basic_string /usr/bin/../lib/gcc/x86_64-redhat-linux/4.8.3/../../../../include/c++/4.8.3/bits/basic_string.h:539
    #3 0x4843f2 in ~basic_string /usr/bin/../lib/gcc/x86_64-redhat-linux/4.8.3/../../../../include/c++/4.8.3/bits/basic_string.h:539
    #4 0x4843f2 in ~path /usr/include/boost/filesystem/path.hpp:55
    #5 0x4843f2 in main /run/media/constantine/Space/Boost_1.54.0_Bug_Repro_09.07.2014/main.cpp:6
    #6 0x7f0679cd0d64 in __libc_start_main (/lib64/libc.so.6+0x21d64)

previously allocated by thread T0 here:
    #0 0x46e4b9 in operator new(unsigned long) (/run/media/constantine/Space/Boost_1.54.0_Bug_Repro_09.07.2014/Debug/app+0x46e4b9)
    #1 0x7f067a3411d8 (/lib64/libstdc++.so.6+0xbe1d8)
    #2 0x9

SUMMARY: AddressSanitizer: heap-use-after-free /usr/bin/../lib/gcc/x86_64-redhat-linux/4.8.3/../../../../include/c++/4.8.3/bits/basic_string.h:716 std::string::size() const
Shadow bytes around the buggy address:
  0x0c067fff9d90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c067fff9de0: fa fa fa fa fa fa fa fa fa fa[fd]fd fd fd fa fa
  0x0c067fff9df0: 00 00 00 02 fa fa 00 00 00 03 fa fa 00 00 00 02
  0x0c067fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap right redzone:    fb
  Freed heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==12324==ABORTING

Attachments (1)

Boost_1.54.0_Crash_Repro_09.07.2014.zip (1.3 KB ) - added by iamvfx@… 8 years ago.
Repro files

Download all attachments as: .zip

Change History (4)

by iamvfx@…, 8 years ago

Repro files

comment:1 by anonymous, 8 years ago

Component: Nonefilesystem
Owner: set to Beman Dawes
Summary: Boost.Filesystem: heap-use-after-free using C++11 range loopheap-use-after-free using C++11 range loop

comment:2 by Beman Dawes, 8 years ago

Status: newassigned

Ah! Interesting. The File System TS changes the signature of string() to return "std::string" rather than "const std::string&", and that will fix the problem.

To verify that, I first reproduced the error, and then changed the return type and verified that the problem no longer occurs. (Ubuntu Linux and clang 3.5)

I'm in process of modifying Boost filesystem to conform to the TS, and am hoping to have that ready for 1.57.

In the meantime, I'll leave the ticket open until the updated code actually ships.

Thanks for the report,

--Beman

comment:3 by iamvfx@…, 8 years ago

Thank you, Beman!

Note: See TracTickets for help on using tickets.