https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112850
Bug ID: 112850 Summary: -Wanalyzer-tainted-allocation-size false positive seen in Linux kernel's sound/core/rawmidi.c Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: analyzer Assignee: dmalcolm at gcc dot gnu.org Reporter: dmalcolm at gcc dot gnu.org Blocks: 106358 Target Milestone: --- False positive at -O1 and above with: /* { dg-do compile } */ /* { dg-options "-fanalyzer -O2" } */ /* { dg-require-effective-target analyzer } */ typedef unsigned long __kernel_ulong_t; typedef __kernel_ulong_t __kernel_size_t; typedef __kernel_size_t size_t; typedef unsigned int gfp_t; extern unsigned long copy_from_user(void* to, const void* from, unsigned long n); extern __attribute__((__alloc_size__(1))) __attribute__((__malloc__)) void* kvzalloc(size_t size, gfp_t flags); struct snd_rawmidi_params { int stream; size_t buffer_size; }; char *newbuf; static int resize_runtime_buffer(struct snd_rawmidi_params* params) { if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) return -22; newbuf = kvzalloc(params->buffer_size, /* { dg-bogus "use of attacker-controlled value '\\*params.buffer_size' as allocation size without upper-bounds checking" } */ (((gfp_t)(0x400u | 0x800u)) | ((gfp_t)0x40u) | ((gfp_t)0x80u))); if (!newbuf) return -12; return 0; } long snd_rawmidi_ioctl(unsigned long arg) { void* argp = (void*)arg; struct snd_rawmidi_params params; if (copy_from_user(¶ms, argp, sizeof(struct snd_rawmidi_params))) return -14; return resize_runtime_buffer(¶ms); } with the analyzer_kernel_plugin.so: gcc/testsuite/gcc.dg/plugin/taint-sound-core-rawmidi.c:30:12: warning: use of attacker-controlled value ‘*params.buffer_size’ as allocation size without upper-bounds checking [CWE-789] [-Wanalyzer-tainted-allocation-size] 30 | newbuf = kvzalloc(params->buffer_size, /* { dg-bogus "use of attacker-controlled value '\\*params.buffer_size' as allocation size without upper-bounds checking" } */ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31 | (((gfp_t)(0x400u | 0x800u)) | ((gfp_t)0x40u) | ((gfp_t)0x80u))); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ‘snd_rawmidi_ioctl’: events 1-4 | | 38 | snd_rawmidi_ioctl(unsigned long arg) | | ^~~~~~~~~~~~~~~~~ | | | | | (1) entry to ‘snd_rawmidi_ioctl’ |...... | 42 | if (copy_from_user(¶ms, argp, sizeof(struct snd_rawmidi_params))) | | ~ | | | | | (2) following ‘false’ branch... | 43 | return -14; | 44 | return resize_runtime_buffer(¶ms); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (3) ...to here | | (4) calling ‘resize_runtime_buffer’ from ‘snd_rawmidi_ioctl’ | +--> ‘resize_runtime_buffer’: events 5-8 | | 26 | resize_runtime_buffer(struct snd_rawmidi_params* params) | | ^~~~~~~~~~~~~~~~~~~~~ | | | | | (5) entry to ‘resize_runtime_buffer’ | 27 | { | 28 | if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) | | ~ | | | | | (6) following ‘false’ branch... | 29 | return -22; | 30 | newbuf = kvzalloc(params->buffer_size, /* { dg-bogus "use of attacker-controlled value '\\*params.buffer_size' as allocation size without upper-bounds checking" } */ | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | | | (7) ...to here | | (8) use of attacker-controlled value ‘*params.buffer_size’ as allocation size without upper-bounds checking | 31 | (((gfp_t)(0x400u | 0x800u)) | ((gfp_t)0x40u) | ((gfp_t)0x80u))); | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Reduced from sound/core/rawmidi.c in Linux kernel Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106358 [Bug 106358] [meta-bug] tracker bug for building the Linux kernel with -fanalyzer