abseil / abseil-cpp

Abseil Common Libraries (C++)

Home Page:https://abseil.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

StrCat("a string", "another") segfaults, wheter using literals or std::string

W35170 opened this issue · comments

Describe the bug

#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    std::string s1 = absl::StrFormat("this is a number: %d", 1);
    cout << s1 << endl;

    std::string s2;
    s2 = absl::StrCat("literal", " to literal");
    // cout << s2 << endl;

    // std::string s2 = " this isnt";
    // std::string s3;
    // s3 = absl::StrCat(s1, s2);
    // cout << s3 << endl;
    return 0;
}

Steps to reproduce the bug

try running the above code. Whether the arguments are literals, strings or a combination of both, StrCat always segfaults

the CMakeLists file:

find_package(absl CONFIG REQUIRED)

add_compile_options(-Wall)
set(CMAKE_CXX_STANDARD 17)

add_executable(strcat-test strcat-test.cpp)
target_link_libraries(strcat-test absl::strings absl::str_format)

What version of Abseil are you using?
20210324 as part of gRPC 1.41

What operating system and version are you using
RHEL 7.9

What compiler and version are you using?

gcc (GCC) 9.3.1 20200408 (Red Hat 9.3.1-2)
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

What build system are you using?

cmake version 3.20.6

CMake suite maintained and supported by Kitware (kitware.com/cmake).

Valgrind output:

valgrind ./strcat-test
==7917== Memcheck, a memory error detector
==7917== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7917== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==7917== Command: ./strcat-test
==7917== 
this is a number: 1
==7917== Invalid read of size 1
==7917==    at 0x4C2EB00: memcpy@@GLIBC_2.14 (vg_replace_strmem.c:1035)
==7917==    by 0x404C40: Append (str_cat.cc:93)
==7917==    by 0x404C40: absl::lts_20210324::StrCat(absl::lts_20210324::AlphaNum const&, absl::lts_20210324::AlphaNum const&) (str_cat.cc:104)
==7917==    by 0x404561: main (strcat-test.cpp:14)
==7917==  Address 0x7 is not stack'd, malloc'd or (recently) free'd
==7917== 
==7917== 
==7917== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==7917==  Access not within mapped region at address 0x7
==7917==    at 0x4C2EB00: memcpy@@GLIBC_2.14 (vg_replace_strmem.c:1035)
==7917==    by 0x404C40: Append (str_cat.cc:93)
==7917==    by 0x404C40: absl::lts_20210324::StrCat(absl::lts_20210324::AlphaNum const&, absl::lts_20210324::AlphaNum const&) (str_cat.cc:104)
==7917==    by 0x404561: main (strcat-test.cpp:14)
==7917==  If you believe this happened as a result of a stack
==7917==  overflow in your program's main thread (unlikely but
==7917==  possible), you can try to increase the size of the
==7917==  main thread stack using the --main-stacksize= flag.
==7917==  The main thread stack size used in this run was 16777216.
==7917== 
==7917== HEAP SUMMARY:
==7917==     in use at exit: 8,663,052 bytes in 2 blocks
==7917==   total heap usage: 2 allocs, 0 frees, 8,663,052 bytes allocated
==7917== 
==7917== LEAK SUMMARY:
==7917==    definitely lost: 0 bytes in 0 blocks
==7917==    indirectly lost: 0 bytes in 0 blocks
==7917==      possibly lost: 0 bytes in 0 blocks
==7917==    still reachable: 8,663,052 bytes in 2 blocks
==7917==                       of which reachable via heuristic:
==7917==                         stdstring          : 8,663,052 bytes in 2 blocks
==7917==         suppressed: 0 bytes in 0 blocks
==7917== Rerun with --leak-check=full to see details of leaked memory
==7917== 
==7917== For lists of detected and suppressed errors, rerun with: -s
==7917== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault

From libasan (full paths omitted):

=================================================================
==9750==ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000423021 at pc 0x2b789ea712e0 bp 0x7ffc3b4f9780 sp 0x7ffc3b4f8f28
READ of size 4338432 at 0x000000423021 thread T0
    #0 0x2b789ea712df  (/lib64/libasan.so.5+0x9a2df)
    #1 0x406950 in Append abseil-cpp/absl/strings/str_cat.cc:93
    #2 0x406950 in absl::lts_20210324::StrCat(absl::lts_20210324::AlphaNum const&, absl::lts_20210324::AlphaNum const&) str_cat.cc:104
    #3 0x40584f in main strcat-test.cpp:14
    #4 0x2b78a006d554 in __libc_start_main (/lib64/libc.so.6+0x22554)
    #5 0x405516  (strcat-test+0x405516)

0x000000423021 is located 0 bytes to the right of global variable 'seq' defined in '/opt/rh/devtoolset-9/root/usr/include/c++/9/pstl/execution_defs.h:112:28' (0x423020) of size 1
  'seq' is ascii string ''
0x000000423021 is located 63 bytes to the left of global variable 'par' defined in '/opt/rh/devtoolset-9/root/usr/include/c++/9/pstl/execution_defs.h:114:27' (0x423060) of size 1
  'par' is ascii string ''
SUMMARY: AddressSanitizer: global-buffer-overflow (/lib64/libasan.so.5+0x9a2df) 
Shadow bytes around the buggy address:
  0x00008007c5b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008007c5c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008007c5d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008007c5e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008007c5f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00008007c600: 00 00 00 00[01]f9 f9 f9 f9 f9 f9 f9 01 f9 f9 f9
  0x00008007c610: f9 f9 f9 f9 01 f9 f9 f9 f9 f9 f9 f9 01 f9 f9 f9
  0x00008007c620: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9
  0x00008007c630: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
  0x00008007c640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x00008007c650: 00 00 05 f9 f9 f9 f9 f9 00 04 f9 f9 f9 f9 f9 f9
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
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==9750==ABORTING