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