Menu

#200 basic_string::assign( _Ptr, _Count) bug in debug mode

5.1
closed-invalid
2
2009-01-09
2009-01-09
Bright Xing
No

While calling
basic_string& assign(
const value_type* _Ptr,
size_type _Count
);
of STLport version 5.1.5, access violation was reported. By checking the dumping stack, I am
sure below codes in _string.h caused it.

_STLP_VERBOSE_ASSERT((__s != 0), _StlMsg_INVALID_ARGUMENT)
_M_check_assign((min) (_Traits::length(__s), __n));

because _Traits::length(__s) was translated as:

static size_t _STLP_CALL length(const char* __s)
{ return strlen(__s); }

While passed in _Ptr is referred to non '0' terminated string, strlen(__s) may read until '0' reached, then reading access violation may be reported. If there are '0' within the range of _Count, only character before '0' would be assigned, but the assign function with this signature, '0' should be valid characters.

please refer http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/032fe3333091799d?hl=en for detailed discussion.

I don't have good ideas to solve this problem, but I suggested that just reading from _Ptr to _Ptr + _Count, so reading access violation may be triggered if invalid arguments are passed in, while some memory debug facilities are used, such as pageheap.

Discussion

  • Petr Ovtchenkov

    Petr Ovtchenkov - 2009-01-09

    1. I don't see sample (and simple) code that demonstrate problem.
    2. Do you change defaults STLport defines during compilation?

    Hint: STLport has two modes: with always present terminated \0 (default)
    and with terminated \0 added only after appropriate access. So test first,
    only after test I will consider this.

     
  • Petr Ovtchenkov

    Petr Ovtchenkov - 2009-01-09
    • priority: 5 --> 2
    • assigned_to: nobody --> complement
    • status: open --> open-works-for-me
     
  • Bright Xing

    Bright Xing - 2009-01-09

    demo STLPort std::string::assign bug, with host.h and user_config.h attached.

     
  • Bright Xing

    Bright Xing - 2009-01-09

    Hi, complement,

    I created a simple project with VC2005 as attached, as well as "user_config.h" and "host.h" used with my environment, but I don't think they the root cause. It's easy to be compiled under other platform with macro "DEBUG", "_DEBUG" and "_STLP_DEBUG".

    While running on Windows system, set Microsoft Global Flags to "Enable page heap" first before running the code. AV alarm should be reported.
    Because, page Heap will allocate non-access page immediately after the memory allocated by program, over-boundary reading will be caught immediately.

    The bug that MAY cause reading access violation could be confirmed with the above test;
    and I take back the assert it can't work with string with internal '\0'.

    File Added: STLportAssignBugDemo.zip

     
  • Petr Ovtchenkov

    Petr Ovtchenkov - 2009-01-09

    1. Configuration defs you used are mutually exclusive.
    2. Test is ill-formed, so it not a test at all:

    char * const charBuffer = new char [bufferAllocLenght];
    charBuffer[0] = 'a';
    charBuffer[1] = 'b';
    charBuffer[2] = 'c';

    std::string target;

    target.assign (charBuffer, 3);

    Issue is closed.

     
  • Petr Ovtchenkov

    Petr Ovtchenkov - 2009-01-09
    • status: open-works-for-me --> closed-invalid
     
  • John V Sichi

    John V Sichi - 2009-04-20

    I encountered this problem also when upgrading STLport. Here is a guaranteed way to reproduce it on Linux:

    #include <unistd.h>
    #include <sys/mman.h>
    #include <string.h>
    #include <string>

    int main(int,char **)
    {
    void *v = ::mmap(
    0,
    getpagesize()*2,
    PROT_READ | PROT_WRITE,
    MAP_PRIVATE | MAP_ANONYMOUS,
    -1,
    0);
    char *p = reinterpret_cast<char *>(v);
    memset(p, 'A', 2*getpagesize());
    ::mprotect(p + getpagesize(), getpagesize(), PROT_NONE);
    std::string s;
    s.assign(p, 10);
    return 0;
    }

    The test works by allocating two pages of virtual memory, and then using mprotect to make the second page read-inaccessible. The first page is still read-accessible, and we only try to read 10 characters from it, but the strlen call searches past that for a zero-terminator and encounters the read-inaccessible page, leading to a segfault.

    Program received signal SIGSEGV, Segmentation fault.
    [Switching to Thread -1226619184 (LWP 1989)]
    0xb6ea4c23 in strlen () from /lib/tls/i686/cmov/libc.so.6
    (gdb) where
    #0 0xb6ea4c23 in strlen () from /lib/tls/i686/cmov/libc.so.6
    #1 0x080589bd in stlpd_std::char_traits<char>::length (__s=0xb7c18000 'A' <repeats 200 times>...) at /home/jvs/open/tpu/thirdparty/stlport/stlport/stl/char_traits.h:237
    #2 0x0805a85d in stlpd_std::basic_string<char, stlpd_std::char_traits<char>, stlpd_std::allocator<char> >::assign (this=0xbfd345a8, __s=0xb7c18000 'A' <repeats 200 times>..., __n=10)
    at /home/jvs/open/tpu/thirdparty/stlport/stlport/stl/debug/_string.h:350

    I would like to request that this issue be reopened and fixed.

     
  • Petr Ovtchenkov

    Petr Ovtchenkov - 2009-04-21

    I made test. Problem not confirmed for current mainstream. Because this part of code wasn't changed since 5.2, I expect that 5.2 is fine too. If you have problem with STLport _before_ 5.2.x, then I will see on it only if _you_ suggest patch and regression test against HEAD in 5.1 branch. I will not consider problems with STLport before 5.1 in any case.

     

Log in to post a comment.