When this is built with -D_FORTIFY_SOURCE=3 *and* -O2 (or -O1 even), it issues the same warning:
$ gcc foo.c -o foo -D_FORTIFY_SOURCE=3 -O2
<command-line>: warning: "_FORTIFY_SOURCE" redefined
<built-in>: note: this is the location of the previous definition
foo.c: In function ‘main’:
foo.c:14:13: warning: ‘read’ writing 1 byte into a region of size 0 overflows the destination [-Wstringop-overflow=]
14 | count = read(fd, test_info, sizeof(test_info));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
foo.c:9:20: note: destination object ‘test_info’ of size 0
9 | struct test_st test_info[16];
| ^~~~~~~~~
In file included from /usr/include/unistd.h:1214, from foo.c:2:
/usr/include/x86_64-linux-gnu/bits/unistd.h:26:1: note: in a call to function ‘read’ declared with attribute ‘access (write_only, 2)’
26 | read (int __fd, void *__buf, size_t __nbytes)
| ^~~~
But note that read(2) with a count of zero will not overflow the target, as nothing will be read, so this seems like a bug in gcc. And indeed, there are several[1] such bug reports in gcc's bugzilla. Where it got the "1 byte" I don't know.
I think this is a false positive. Here is a quick reproducer on amd64:
#include <stdio.h>
#include <unistd.h>
int main(void) {
struct test_st {};
int fd = 0;
int count = 0;
struct test_st test_info[16];
printf("Hello world\n");
printf("sizeof struct test_st: %ld\n", sizeof(struct test_st));
printf("sizeof test_info[16]: %ld\n", sizeof(test_info));
count = read(fd, test_info, sizeof(test_info)); /* invalid fd, don't care */
printf("count is %d\n", count);
return(0);
}
When this is built with -D_FORTIFY_SOURCE=3 *and* -O2 (or -O1 even), it issues the same warning: overflow= ] ~~~~~~~ ~~~~~~~ ~~~~~~~ ~~~~~~~ ~~~ unistd. h:1214,
from foo.c:2: x86_64- linux-gnu/ bits/unistd. h:26:1: note: in a call to function ‘read’ declared with attribute ‘access (write_only, 2)’
$ gcc foo.c -o foo -D_FORTIFY_SOURCE=3 -O2
<command-line>: warning: "_FORTIFY_SOURCE" redefined
<built-in>: note: this is the location of the previous definition
foo.c: In function ‘main’:
foo.c:14:13: warning: ‘read’ writing 1 byte into a region of size 0 overflows the destination [-Wstringop-
14 | count = read(fd, test_info, sizeof(test_info));
| ^~~~~~~
foo.c:9:20: note: destination object ‘test_info’ of size 0
9 | struct test_st test_info[16];
| ^~~~~~~~~
In file included from /usr/include/
/usr/include/
26 | read (int __fd, void *__buf, size_t __nbytes)
| ^~~~
But note that read(2) with a count of zero will not overflow the target, as nothing will be read, so this seems like a bug in gcc. And indeed, there are several[1] such bug reports in gcc's bugzilla. Where it got the "1 byte" I don't know.
1. https:/ /gcc.gnu. org/bugzilla/ buglist. cgi?quicksearch =writing% 201%20byte% 20into% 20a%20region% 20of%20size% 200