https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105078

            Bug ID: 105078
           Summary: Maybe wrong *** buffer overflow detected ***:
                    terminated with -D_FORTIFY_SOURCE
           Product: gcc
           Version: 12.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: marxin at gcc dot gnu.org
                CC: fab...@ritter-vogt.de, siddhesh at gcc dot gnu.org
  Target Milestone: ---

It's what was slightly mentioned here:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104964#c6

Thanks to Fabian for the reduced test-case:

$ cat qt.C
#include <cstdlib> 
#include <cstddef> 
#include <unistd.h> 

struct QArrayData { 
        int size; 
        ptrdiff_t offset; // in bytes from beginning of header 

        void *data() { 
                return reinterpret_cast<char *>(this) + offset; 
        } 

        static QArrayData *allocate(size_t size, size_t alignment) { 
                size_t headerSize = sizeof(QArrayData); 
                headerSize += (alignment - alignof(QArrayData)); 
                QArrayData *header = static_cast<QArrayData
*>(::malloc(headerSize + size)); 
                header->size = size; 
                header->offset = headerSize; 
                return header; 
        } 
}; 

template <class T> 
struct QTypedArrayData : QArrayData { 
        T *data() { return static_cast<T *>(QArrayData::data()); } 
        class AlignmentDummy { QArrayData header; T data; }; 

        static QTypedArrayData *allocate(size_t size) { 
                return static_cast<QTypedArrayData
*>(QArrayData::allocate(size, alignof(AlignmentDummy))); 
        } 
}; 

int main() 
{ 
        int size = 256; 
        auto *data = QTypedArrayData<char>::allocate(size); 
        return readlink("asdf", data->data(), data->size - 1); 
}

$ g++ qt.C -D_FORTIFY_SOURCE=2 -O2 && ./a.out
In file included from /usr/include/features.h:490,
                 from
/home/marxin/bin/gcc/include/c++/12.0.1/x86_64-pc-linux-gnu/bits/os_defines.h:39,
                 from
/home/marxin/bin/gcc/include/c++/12.0.1/x86_64-pc-linux-gnu/bits/c++config.h:655,
                 from /home/marxin/bin/gcc/include/c++/12.0.1/cstdlib:41,
                 from qt.C:1:
In function ‘ssize_t readlink(const char*, char*, size_t)’,
    inlined from ‘int main()’ at qt.C:37:24:
/usr/include/bits/unistd.h:119:10: warning: ‘ssize_t __readlink_alias(const
char*, char*, size_t)’ writing 255 bytes into a region of size 0 overflows the
destination [-Wstringop-overflow=]
  119 |   return __glibc_fortify (readlink, __len, sizeof (char),
      |          ^~~~~~~~~~~~~~~
qt.C: In function ‘int main()’:
qt.C:24:8: note: at offset 16 into destination object
‘QTypedArrayData<char>::<anonymous>’ of size 16
   24 | struct QTypedArrayData : QArrayData {
      |        ^~~~~~~~~~~~~~~
/usr/include/bits/unistd.h:104:16: note: in a call to function ‘ssize_t
__readlink_alias(const char*, char*, size_t)’ declared with attribute ‘access
(write_only, 2, 3)’
  104 | extern ssize_t __REDIRECT_NTH (__readlink_alias,
      |                ^~~~~~~~~~~~~~
In function ‘ssize_t readlink(const char*, char*, size_t)’,
    inlined from ‘int main()’ at qt.C:37:24:
/usr/include/bits/unistd.h:119:10: warning: ‘ssize_t __readlink_chk(const
char*, char*, size_t, size_t)’ writing 255 bytes into a region of size 0
overflows the destination [-Wstringop-overflow=]
  119 |   return __glibc_fortify (readlink, __len, sizeof (char),
      |          ^~~~~~~~~~~~~~~
qt.C: In function ‘int main()’:
qt.C:24:8: note: at offset 16 into destination object
‘QTypedArrayData<char>::<anonymous>’ of size 16
   24 | struct QTypedArrayData : QArrayData {
      |        ^~~~~~~~~~~~~~~
In file included from /usr/include/unistd.h:1214,
                 from qt.C:3:
/usr/include/bits/unistd.h:100:16: note: in a call to function ‘ssize_t
__readlink_chk(const char*, char*, size_t, size_t)’ declared with attribute
‘access (write_only, 2, 3)’
  100 | extern ssize_t __readlink_chk (const char *__restrict __path,
      |                ^~~~~~~~~~~~~~
In function ‘ssize_t readlink(const char*, char*, size_t)’,
    inlined from ‘int main()’ at qt.C:37:24:
/usr/include/bits/unistd.h:119:10: warning: call to ‘__readlink_chk_warn’
declared with attribute warning: readlink called with bigger length than size
of destination buffer [-Wattribute-warning]
  119 |   return __glibc_fortify (readlink, __len, sizeof (char),
      |          ^~~~~~~~~~~~~~~
*** buffer overflow detected ***: terminated
Aborted (core dumped)

Reply via email to