xref: /qemu/scripts/coverity-scan/model.c (revision 9d7a4c6690ef9962a3b20034f65008f1ea15c1d6)
1e40cdb0eSPaolo Bonzini /* Coverity Scan model
2e40cdb0eSPaolo Bonzini  *
3e40cdb0eSPaolo Bonzini  * Copyright (C) 2014 Red Hat, Inc.
4e40cdb0eSPaolo Bonzini  *
5e40cdb0eSPaolo Bonzini  * Authors:
6e40cdb0eSPaolo Bonzini  *  Markus Armbruster <armbru@redhat.com>
7e40cdb0eSPaolo Bonzini  *  Paolo Bonzini <pbonzini@redhat.com>
8e40cdb0eSPaolo Bonzini  *
9e40cdb0eSPaolo Bonzini  * This work is licensed under the terms of the GNU GPL, version 2 or, at your
10e40cdb0eSPaolo Bonzini  * option, any later version.  See the COPYING file in the top-level directory.
11e40cdb0eSPaolo Bonzini  */
12e40cdb0eSPaolo Bonzini 
13e40cdb0eSPaolo Bonzini 
14e40cdb0eSPaolo Bonzini /*
15e40cdb0eSPaolo Bonzini  * This is the source code for our Coverity user model file.  The
16e40cdb0eSPaolo Bonzini  * purpose of user models is to increase scanning accuracy by explaining
17e40cdb0eSPaolo Bonzini  * code Coverity can't see (out of tree libraries) or doesn't
18e40cdb0eSPaolo Bonzini  * sufficiently understand.  Better accuracy means both fewer false
19e40cdb0eSPaolo Bonzini  * positives and more true defects.  Memory leaks in particular.
20e40cdb0eSPaolo Bonzini  *
21e40cdb0eSPaolo Bonzini  * - A model file can't import any header files.  Some built-in primitives are
22e40cdb0eSPaolo Bonzini  *   available but not wchar_t, NULL etc.
23e40cdb0eSPaolo Bonzini  * - Modeling doesn't need full structs and typedefs. Rudimentary structs
24e40cdb0eSPaolo Bonzini  *   and similar types are sufficient.
25e40cdb0eSPaolo Bonzini  * - An uninitialized local variable signifies that the variable could be
26e40cdb0eSPaolo Bonzini  *   any value.
27e40cdb0eSPaolo Bonzini  *
28e40cdb0eSPaolo Bonzini  * The model file must be uploaded by an admin in the analysis settings of
29e40cdb0eSPaolo Bonzini  * http://scan.coverity.com/projects/378
30e40cdb0eSPaolo Bonzini  */
31e40cdb0eSPaolo Bonzini 
32e40cdb0eSPaolo Bonzini #define NULL ((void *)0)
33e40cdb0eSPaolo Bonzini 
34e40cdb0eSPaolo Bonzini typedef unsigned char uint8_t;
35e40cdb0eSPaolo Bonzini typedef char int8_t;
36e40cdb0eSPaolo Bonzini typedef unsigned int uint32_t;
37e40cdb0eSPaolo Bonzini typedef int int32_t;
38e40cdb0eSPaolo Bonzini typedef long ssize_t;
39e40cdb0eSPaolo Bonzini typedef unsigned long long uint64_t;
40e40cdb0eSPaolo Bonzini typedef long long int64_t;
41e40cdb0eSPaolo Bonzini typedef _Bool bool;
42e40cdb0eSPaolo Bonzini 
43e40cdb0eSPaolo Bonzini /* exec.c */
44e40cdb0eSPaolo Bonzini 
45e40cdb0eSPaolo Bonzini typedef struct AddressSpace AddressSpace;
46e40cdb0eSPaolo Bonzini typedef uint64_t hwaddr;
47e40cdb0eSPaolo Bonzini 
48e40cdb0eSPaolo Bonzini static void __write(uint8_t *buf, ssize_t len)
49e40cdb0eSPaolo Bonzini {
50e40cdb0eSPaolo Bonzini     int first, last;
51e40cdb0eSPaolo Bonzini     __coverity_negative_sink__(len);
52e40cdb0eSPaolo Bonzini     if (len == 0) return;
53e40cdb0eSPaolo Bonzini     buf[0] = first;
54e40cdb0eSPaolo Bonzini     buf[len-1] = last;
55e40cdb0eSPaolo Bonzini     __coverity_writeall__(buf);
56e40cdb0eSPaolo Bonzini }
57e40cdb0eSPaolo Bonzini 
58e40cdb0eSPaolo Bonzini static void __read(uint8_t *buf, ssize_t len)
59e40cdb0eSPaolo Bonzini {
60e40cdb0eSPaolo Bonzini     __coverity_negative_sink__(len);
61e40cdb0eSPaolo Bonzini     if (len == 0) return;
62e40cdb0eSPaolo Bonzini     int first = buf[0];
63e40cdb0eSPaolo Bonzini     int last = buf[len-1];
64e40cdb0eSPaolo Bonzini }
65e40cdb0eSPaolo Bonzini 
66e40cdb0eSPaolo Bonzini bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
67e40cdb0eSPaolo Bonzini                       int len, bool is_write)
68e40cdb0eSPaolo Bonzini {
69e40cdb0eSPaolo Bonzini     bool result;
70e40cdb0eSPaolo Bonzini 
71e40cdb0eSPaolo Bonzini     // TODO: investigate impact of treating reads as producing
72e40cdb0eSPaolo Bonzini     // tainted data, with __coverity_tainted_data_argument__(buf).
73e40cdb0eSPaolo Bonzini     if (is_write) __write(buf, len); else __read(buf, len);
74e40cdb0eSPaolo Bonzini 
75e40cdb0eSPaolo Bonzini     return result;
76e40cdb0eSPaolo Bonzini }
77e40cdb0eSPaolo Bonzini 
78e40cdb0eSPaolo Bonzini /* Tainting */
79e40cdb0eSPaolo Bonzini 
80e40cdb0eSPaolo Bonzini typedef struct {} name2keysym_t;
81e40cdb0eSPaolo Bonzini static int get_keysym(const name2keysym_t *table,
82e40cdb0eSPaolo Bonzini                       const char *name)
83e40cdb0eSPaolo Bonzini {
84e40cdb0eSPaolo Bonzini     int result;
85e40cdb0eSPaolo Bonzini     if (result > 0) {
86e40cdb0eSPaolo Bonzini         __coverity_tainted_string_sanitize_content__(name);
87e40cdb0eSPaolo Bonzini         return result;
88e40cdb0eSPaolo Bonzini     } else {
89e40cdb0eSPaolo Bonzini         return 0;
90e40cdb0eSPaolo Bonzini     }
91e40cdb0eSPaolo Bonzini }
92e40cdb0eSPaolo Bonzini 
93*9d7a4c66SMarkus Armbruster /*
94*9d7a4c66SMarkus Armbruster  * GLib memory allocation functions.
95e40cdb0eSPaolo Bonzini  *
96e40cdb0eSPaolo Bonzini  * Note that we ignore the fact that g_malloc of 0 bytes returns NULL,
97e40cdb0eSPaolo Bonzini  * and g_realloc of 0 bytes frees the pointer.
98e40cdb0eSPaolo Bonzini  *
99e40cdb0eSPaolo Bonzini  * Modeling this would result in Coverity flagging a lot of memory
100e40cdb0eSPaolo Bonzini  * allocations as potentially returning NULL, and asking us to check
101e40cdb0eSPaolo Bonzini  * whether the result of the allocation is NULL or not.  However, the
102e40cdb0eSPaolo Bonzini  * resulting pointer should never be dereferenced anyway, and in fact
103e40cdb0eSPaolo Bonzini  * it is not in the vast majority of cases.
104e40cdb0eSPaolo Bonzini  *
105e40cdb0eSPaolo Bonzini  * If a dereference did happen, this would suppress a defect report
106e40cdb0eSPaolo Bonzini  * for an actual null pointer dereference.  But it's too unlikely to
107e40cdb0eSPaolo Bonzini  * be worth wading through the false positives, and with some luck
108e40cdb0eSPaolo Bonzini  * we'll get a buffer overflow reported anyway.
109e40cdb0eSPaolo Bonzini  */
110e40cdb0eSPaolo Bonzini 
111*9d7a4c66SMarkus Armbruster /*
112*9d7a4c66SMarkus Armbruster  * Allocation primitives, cannot return NULL
113*9d7a4c66SMarkus Armbruster  * See also Coverity's library/generic/libc/all/all.c
114*9d7a4c66SMarkus Armbruster  */
115e40cdb0eSPaolo Bonzini 
116*9d7a4c66SMarkus Armbruster void *g_malloc_n(size_t nmemb, size_t size)
117e40cdb0eSPaolo Bonzini {
118*9d7a4c66SMarkus Armbruster     size_t sz;
119*9d7a4c66SMarkus Armbruster     void *ptr;
120*9d7a4c66SMarkus Armbruster 
121*9d7a4c66SMarkus Armbruster     __coverity_negative_sink__(nmemb);
122*9d7a4c66SMarkus Armbruster     __coverity_negative_sink__(size);
123*9d7a4c66SMarkus Armbruster     sz = nmemb * size;
124*9d7a4c66SMarkus Armbruster     ptr = __coverity_alloc__(size);
125*9d7a4c66SMarkus Armbruster     __coverity_mark_as_uninitialized_buffer__(ptr);
126*9d7a4c66SMarkus Armbruster     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
127*9d7a4c66SMarkus Armbruster     return ptr;
128e40cdb0eSPaolo Bonzini }
129e40cdb0eSPaolo Bonzini 
130*9d7a4c66SMarkus Armbruster void *g_malloc0_n(size_t nmemb, size_t size)
131e40cdb0eSPaolo Bonzini {
132*9d7a4c66SMarkus Armbruster     size_t sz;
133*9d7a4c66SMarkus Armbruster     void *ptr;
134*9d7a4c66SMarkus Armbruster 
135*9d7a4c66SMarkus Armbruster     __coverity_negative_sink__(nmemb);
136*9d7a4c66SMarkus Armbruster     __coverity_negative_sink__(size);
137*9d7a4c66SMarkus Armbruster     sz = nmemb * size;
138*9d7a4c66SMarkus Armbruster     ptr = __coverity_alloc__(size);
139*9d7a4c66SMarkus Armbruster     __coverity_writeall0__(ptr);
140*9d7a4c66SMarkus Armbruster     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
141*9d7a4c66SMarkus Armbruster     return ptr;
142e40cdb0eSPaolo Bonzini }
143e40cdb0eSPaolo Bonzini 
144*9d7a4c66SMarkus Armbruster void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
145e40cdb0eSPaolo Bonzini {
146*9d7a4c66SMarkus Armbruster     size_t sz;
147*9d7a4c66SMarkus Armbruster 
148*9d7a4c66SMarkus Armbruster     __coverity_negative_sink__(nmemb);
149*9d7a4c66SMarkus Armbruster     __coverity_negative_sink__(size);
150*9d7a4c66SMarkus Armbruster     sz = nmemb * size;
151*9d7a4c66SMarkus Armbruster     __coverity_escape__(ptr);
152*9d7a4c66SMarkus Armbruster     ptr = __coverity_alloc__(size);
153*9d7a4c66SMarkus Armbruster     /*
154*9d7a4c66SMarkus Armbruster      * Memory beyond the old size isn't actually initialized.  Can't
155*9d7a4c66SMarkus Armbruster      * model that.  See Coverity's realloc() model
156*9d7a4c66SMarkus Armbruster      */
157*9d7a4c66SMarkus Armbruster     __coverity_writeall__(ptr);
158*9d7a4c66SMarkus Armbruster     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
159*9d7a4c66SMarkus Armbruster     return ptr;
160e40cdb0eSPaolo Bonzini }
161e40cdb0eSPaolo Bonzini 
162*9d7a4c66SMarkus Armbruster void g_free(void *ptr)
163e40cdb0eSPaolo Bonzini {
164*9d7a4c66SMarkus Armbruster     __coverity_free__(ptr);
165*9d7a4c66SMarkus Armbruster     __coverity_mark_as_afm_freed__(ptr, AFM_free);
166e40cdb0eSPaolo Bonzini }
167e40cdb0eSPaolo Bonzini 
168*9d7a4c66SMarkus Armbruster /*
169*9d7a4c66SMarkus Armbruster  * Derive the g_try_FOO_n() from the g_FOO_n() by adding indeterminate
170*9d7a4c66SMarkus Armbruster  * out of memory conditions
171*9d7a4c66SMarkus Armbruster  */
172*9d7a4c66SMarkus Armbruster 
173*9d7a4c66SMarkus Armbruster void *g_try_malloc_n(size_t nmemb, size_t size)
174e40cdb0eSPaolo Bonzini {
175*9d7a4c66SMarkus Armbruster     int nomem;
176*9d7a4c66SMarkus Armbruster 
177*9d7a4c66SMarkus Armbruster     if (nomem) {
178*9d7a4c66SMarkus Armbruster         return NULL;
179*9d7a4c66SMarkus Armbruster     }
180*9d7a4c66SMarkus Armbruster     return g_malloc_n(nmemb, size);
181e40cdb0eSPaolo Bonzini }
182e40cdb0eSPaolo Bonzini 
183*9d7a4c66SMarkus Armbruster void *g_try_malloc0_n(size_t nmemb, size_t size)
184e40cdb0eSPaolo Bonzini {
185*9d7a4c66SMarkus Armbruster     int nomem;
186*9d7a4c66SMarkus Armbruster 
187*9d7a4c66SMarkus Armbruster     if (nomem) {
188*9d7a4c66SMarkus Armbruster         return NULL;
189*9d7a4c66SMarkus Armbruster     }
190*9d7a4c66SMarkus Armbruster     return g_malloc0_n(nmemb, size);
191e40cdb0eSPaolo Bonzini }
192e40cdb0eSPaolo Bonzini 
193*9d7a4c66SMarkus Armbruster void *g_try_realloc_n(void *ptr, size_t nmemb, size_t size)
194e40cdb0eSPaolo Bonzini {
195*9d7a4c66SMarkus Armbruster     int nomem;
196*9d7a4c66SMarkus Armbruster 
197*9d7a4c66SMarkus Armbruster     if (nomem) {
198*9d7a4c66SMarkus Armbruster         return NULL;
199*9d7a4c66SMarkus Armbruster     }
200*9d7a4c66SMarkus Armbruster     return g_realloc_n(ptr, nmemb, size);
201*9d7a4c66SMarkus Armbruster }
202*9d7a4c66SMarkus Armbruster 
203*9d7a4c66SMarkus Armbruster /* Trivially derive the g_FOO() from the g_FOO_n() */
204*9d7a4c66SMarkus Armbruster 
205*9d7a4c66SMarkus Armbruster void *g_malloc(size_t size)
206*9d7a4c66SMarkus Armbruster {
207*9d7a4c66SMarkus Armbruster     return g_malloc_n(1, size);
208*9d7a4c66SMarkus Armbruster }
209*9d7a4c66SMarkus Armbruster 
210*9d7a4c66SMarkus Armbruster void *g_malloc0(size_t size)
211*9d7a4c66SMarkus Armbruster {
212*9d7a4c66SMarkus Armbruster     return g_malloc0_n(1, size);
213*9d7a4c66SMarkus Armbruster }
214*9d7a4c66SMarkus Armbruster 
215*9d7a4c66SMarkus Armbruster void *g_realloc(void *ptr, size_t size)
216*9d7a4c66SMarkus Armbruster {
217*9d7a4c66SMarkus Armbruster     return g_realloc_n(ptr, 1, size);
218*9d7a4c66SMarkus Armbruster }
219*9d7a4c66SMarkus Armbruster 
220*9d7a4c66SMarkus Armbruster void *g_try_malloc(size_t size)
221*9d7a4c66SMarkus Armbruster {
222*9d7a4c66SMarkus Armbruster     return g_try_malloc_n(1, size);
223*9d7a4c66SMarkus Armbruster }
224*9d7a4c66SMarkus Armbruster 
225*9d7a4c66SMarkus Armbruster void *g_try_malloc0(size_t size)
226*9d7a4c66SMarkus Armbruster {
227*9d7a4c66SMarkus Armbruster     return g_try_malloc0_n(1, size);
228*9d7a4c66SMarkus Armbruster }
229*9d7a4c66SMarkus Armbruster 
230*9d7a4c66SMarkus Armbruster void *g_try_realloc(void *ptr, size_t size)
231*9d7a4c66SMarkus Armbruster {
232*9d7a4c66SMarkus Armbruster     return g_try_realloc_n(ptr, 1, size);
233e40cdb0eSPaolo Bonzini }
234e40cdb0eSPaolo Bonzini 
235e40cdb0eSPaolo Bonzini /* Other glib functions */
236e40cdb0eSPaolo Bonzini 
237e40cdb0eSPaolo Bonzini typedef struct _GIOChannel GIOChannel;
238e40cdb0eSPaolo Bonzini GIOChannel *g_io_channel_unix_new(int fd)
239e40cdb0eSPaolo Bonzini {
240e40cdb0eSPaolo Bonzini     GIOChannel *c = g_malloc0(sizeof(GIOChannel));
241e40cdb0eSPaolo Bonzini     __coverity_escape__(fd);
242e40cdb0eSPaolo Bonzini     return c;
243e40cdb0eSPaolo Bonzini }
244e40cdb0eSPaolo Bonzini 
245e40cdb0eSPaolo Bonzini void g_assertion_message_expr(const char     *domain,
246e40cdb0eSPaolo Bonzini                               const char     *file,
247e40cdb0eSPaolo Bonzini                               int             line,
248e40cdb0eSPaolo Bonzini                               const char     *func,
249e40cdb0eSPaolo Bonzini                               const char     *expr)
250e40cdb0eSPaolo Bonzini {
251e40cdb0eSPaolo Bonzini     __coverity_panic__();
252e40cdb0eSPaolo Bonzini }
253