https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104793
Bug ID: 104793
Summary: -Wanalyzer-write-to-const and
-Wanalyzer-write-to-string-literal should respect
attribute((access, write)
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: analyzer
Assignee: dmalcolm at gcc dot gnu.org
Reporter: dmalcolm at gcc dot gnu.org
Target Milestone: ---
As of GCC 10 (I believe):
__attribute__ ((access (MODE, REF_INDEX[, SIZE_INDEX])))
can be used to mark function decls with info on what buffers they access:
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
Given the following:
#include <stdio.h>
#include <features.h>
ssize_t getrandom (void *__buffer, size_t __length,
unsigned int __flags)
__attribute__ ((access (__write_only__, 1, 2)));
#define GRND_RANDOM 0x02
const char *test = "test";
int main(void)
{
const char buf[5] = { 0 };
if (getrandom(test, sizeof(buf), GRND_RANDOM))
printf("%s\n", buf);
return 0;
}
When it runs, this is in the strace:
getrandom(0x402010, 5, GRND_RANDOM) = -1 EFAULT (Bad address)
trunk (for gcc 12) correctly complains about:
test.c: In function ‘main’:
test.c:16:23: warning: passing argument 1 of ‘getrandom’ discards ‘const’
qualifier from pointer target type [-Wdiscarded-qualifiers]
16 | if (getrandom(test, sizeof(buf), GRND_RANDOM))
| ^~~~
test.c:4:26: note: expected ‘void *’ but argument is of type ‘const char *’
4 | ssize_t getrandom (void *__buffer, size_t __length,
| ~~~~~~^~~~~~~~
However, -fanalyzer doesn't complain. It would be good if the analyzer took
account of the access attribute to notice the attempt to write to the string
literal "test", and emitted -Wanalyzer-write-to-string-literal on the above
code.
Note that glibc doesn't yet mark getrandom with that attribute:
https://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/sys/random.h
(Would be nice to statically bounds-check the accesses as well, but that's a
different issue)