Prevent double free in basic_string

tlknv tlknv@yandex.ru
Thu May 31 14:38:00 GMT 2012


Hi All,
I would like to propose a patch to libstdc++-v3/include/bits/basic_string.h that solves the problem described in the bug 21334 ( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21334 ).
Briefly:
Developers often use non constant methods begin(), end(), operator [], at() for constant operations.
Since developers don’t modify the string they don’t expect that these operations are considered as not constant/modifying operations and can lead to double free if not protected by some mutex/lock.
The problem is caused by a potential delay in _M_grab() between making a positive decision (!_M_is_leaked() && __alloc1 == __alloc2) and performing the corresponding action ( _M_refcopy() ). 
        _CharT*
        _M_grab(const _Alloc& __alloc1, const _Alloc& __alloc2)
        {
         return (!_M_is_leaked() && __alloc1 == __alloc2)
                 ? _M_refcopy() : _M_clone(__alloc1);
        }
Assume that there is std::string s1;
Some thread t2 creates a “copy” of s1: std::string s2(s1);
Copy constructor calls _M_grab. Since _M_refcount == 0 _M_grab decided to call _M_refcopy(). At this moment some other thread t1 calls some non-constant method on s1, e.g. s1.begin(). begin() calls _M_leak .. _M_leak_hard .. _M_set_leaked which sets _M_refcount to -1. Then _M_refcopy() in t2 is going to increment _M_refcount making it 0. Thus each of two basic_string objects think that it owns the object and will eventually free the memory allocated for the string. Which will cause double free and likely crash of the process.

Thanks,
Boris
-------------- next part --------------
A non-text attachment was scrubbed...
Name: basic_string_grab.h.diff
Type: text/x-c++
Size: 2057 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20120531/6c0a2574/attachment.bin>


More information about the Libstdc++ mailing list