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)