xref: /openbmc/qemu/scripts/coverity-scan/model.c (revision e804f892)
1*e804f892SPaolo Bonzini /* Coverity Scan model
2*e804f892SPaolo Bonzini  *
3*e804f892SPaolo Bonzini  * Copyright (C) 2014 Red Hat, Inc.
4*e804f892SPaolo Bonzini  *
5*e804f892SPaolo Bonzini  * Authors:
6*e804f892SPaolo Bonzini  *  Markus Armbruster <armbru@redhat.com>
7*e804f892SPaolo Bonzini  *  Paolo Bonzini <pbonzini@redhat.com>
8*e804f892SPaolo Bonzini  *
9*e804f892SPaolo Bonzini  * This work is licensed under the terms of the GNU GPL, version 2 or, at your
10*e804f892SPaolo Bonzini  * option, any later version.  See the COPYING file in the top-level directory.
11*e804f892SPaolo Bonzini  */
12*e804f892SPaolo Bonzini 
13*e804f892SPaolo Bonzini 
14*e804f892SPaolo Bonzini /*
15*e804f892SPaolo Bonzini  * This is the source code for our Coverity user model file.  The
16*e804f892SPaolo Bonzini  * purpose of user models is to increase scanning accuracy by explaining
17*e804f892SPaolo Bonzini  * code Coverity can't see (out of tree libraries) or doesn't
18*e804f892SPaolo Bonzini  * sufficiently understand.  Better accuracy means both fewer false
19*e804f892SPaolo Bonzini  * positives and more true defects.  Memory leaks in particular.
20*e804f892SPaolo Bonzini  *
21*e804f892SPaolo Bonzini  * - A model file can't import any header files.  Some built-in primitives are
22*e804f892SPaolo Bonzini  *   available but not wchar_t, NULL etc.
23*e804f892SPaolo Bonzini  * - Modeling doesn't need full structs and typedefs. Rudimentary structs
24*e804f892SPaolo Bonzini  *   and similar types are sufficient.
25*e804f892SPaolo Bonzini  * - An uninitialized local variable signifies that the variable could be
26*e804f892SPaolo Bonzini  *   any value.
27*e804f892SPaolo Bonzini  *
28*e804f892SPaolo Bonzini  * The model file must be uploaded by an admin in the analysis settings of
29*e804f892SPaolo Bonzini  * http://scan.coverity.com/projects/378
30*e804f892SPaolo Bonzini  */
31*e804f892SPaolo Bonzini 
32*e804f892SPaolo Bonzini #define NULL ((void *)0)
33*e804f892SPaolo Bonzini 
34*e804f892SPaolo Bonzini typedef unsigned char uint8_t;
35*e804f892SPaolo Bonzini typedef char int8_t;
36*e804f892SPaolo Bonzini typedef unsigned int uint32_t;
37*e804f892SPaolo Bonzini typedef int int32_t;
38*e804f892SPaolo Bonzini typedef long ssize_t;
39*e804f892SPaolo Bonzini typedef unsigned long long uint64_t;
40*e804f892SPaolo Bonzini typedef long long int64_t;
41*e804f892SPaolo Bonzini typedef _Bool bool;
42*e804f892SPaolo Bonzini 
43*e804f892SPaolo Bonzini typedef struct va_list_str *va_list;
44*e804f892SPaolo Bonzini 
45*e804f892SPaolo Bonzini /* exec.c */
46*e804f892SPaolo Bonzini 
47*e804f892SPaolo Bonzini typedef struct AddressSpace AddressSpace;
48*e804f892SPaolo Bonzini typedef uint64_t hwaddr;
49*e804f892SPaolo Bonzini typedef uint32_t MemTxResult;
50*e804f892SPaolo Bonzini typedef uint64_t MemTxAttrs;
51*e804f892SPaolo Bonzini 
52*e804f892SPaolo Bonzini static void __bufwrite(uint8_t *buf, ssize_t len)
53*e804f892SPaolo Bonzini {
54*e804f892SPaolo Bonzini     int first, last;
55*e804f892SPaolo Bonzini     __coverity_negative_sink__(len);
56*e804f892SPaolo Bonzini     if (len == 0) return;
57*e804f892SPaolo Bonzini     buf[0] = first;
58*e804f892SPaolo Bonzini     buf[len-1] = last;
59*e804f892SPaolo Bonzini     __coverity_writeall__(buf);
60*e804f892SPaolo Bonzini }
61*e804f892SPaolo Bonzini 
62*e804f892SPaolo Bonzini static void __bufread(uint8_t *buf, ssize_t len)
63*e804f892SPaolo Bonzini {
64*e804f892SPaolo Bonzini     __coverity_negative_sink__(len);
65*e804f892SPaolo Bonzini     if (len == 0) return;
66*e804f892SPaolo Bonzini     int first = buf[0];
67*e804f892SPaolo Bonzini     int last = buf[len-1];
68*e804f892SPaolo Bonzini }
69*e804f892SPaolo Bonzini 
70*e804f892SPaolo Bonzini MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
71*e804f892SPaolo Bonzini                                MemTxAttrs attrs,
72*e804f892SPaolo Bonzini                                uint8_t *buf, int len)
73*e804f892SPaolo Bonzini {
74*e804f892SPaolo Bonzini     MemTxResult result;
75*e804f892SPaolo Bonzini     // TODO: investigate impact of treating reads as producing
76*e804f892SPaolo Bonzini     // tainted data, with __coverity_tainted_data_argument__(buf).
77*e804f892SPaolo Bonzini     __bufwrite(buf, len);
78*e804f892SPaolo Bonzini     return result;
79*e804f892SPaolo Bonzini }
80*e804f892SPaolo Bonzini 
81*e804f892SPaolo Bonzini MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
82*e804f892SPaolo Bonzini                                 MemTxAttrs attrs,
83*e804f892SPaolo Bonzini                                 const uint8_t *buf, int len)
84*e804f892SPaolo Bonzini {
85*e804f892SPaolo Bonzini     MemTxResult result;
86*e804f892SPaolo Bonzini     __bufread(buf, len);
87*e804f892SPaolo Bonzini     return result;
88*e804f892SPaolo Bonzini }
89*e804f892SPaolo Bonzini 
90*e804f892SPaolo Bonzini 
91*e804f892SPaolo Bonzini /* Tainting */
92*e804f892SPaolo Bonzini 
93*e804f892SPaolo Bonzini typedef struct {} name2keysym_t;
94*e804f892SPaolo Bonzini static int get_keysym(const name2keysym_t *table,
95*e804f892SPaolo Bonzini                       const char *name)
96*e804f892SPaolo Bonzini {
97*e804f892SPaolo Bonzini     int result;
98*e804f892SPaolo Bonzini     if (result > 0) {
99*e804f892SPaolo Bonzini         __coverity_tainted_string_sanitize_content__(name);
100*e804f892SPaolo Bonzini         return result;
101*e804f892SPaolo Bonzini     } else {
102*e804f892SPaolo Bonzini         return 0;
103*e804f892SPaolo Bonzini     }
104*e804f892SPaolo Bonzini }
105*e804f892SPaolo Bonzini 
106*e804f892SPaolo Bonzini /* Replay data is considered trusted.  */
107*e804f892SPaolo Bonzini uint8_t replay_get_byte(void)
108*e804f892SPaolo Bonzini {
109*e804f892SPaolo Bonzini     uint8_t byte;
110*e804f892SPaolo Bonzini     return byte;
111*e804f892SPaolo Bonzini }
112*e804f892SPaolo Bonzini 
113*e804f892SPaolo Bonzini 
114*e804f892SPaolo Bonzini /*
115*e804f892SPaolo Bonzini  * GLib memory allocation functions.
116*e804f892SPaolo Bonzini  *
117*e804f892SPaolo Bonzini  * Note that we ignore the fact that g_malloc of 0 bytes returns NULL,
118*e804f892SPaolo Bonzini  * and g_realloc of 0 bytes frees the pointer.
119*e804f892SPaolo Bonzini  *
120*e804f892SPaolo Bonzini  * Modeling this would result in Coverity flagging a lot of memory
121*e804f892SPaolo Bonzini  * allocations as potentially returning NULL, and asking us to check
122*e804f892SPaolo Bonzini  * whether the result of the allocation is NULL or not.  However, the
123*e804f892SPaolo Bonzini  * resulting pointer should never be dereferenced anyway, and in fact
124*e804f892SPaolo Bonzini  * it is not in the vast majority of cases.
125*e804f892SPaolo Bonzini  *
126*e804f892SPaolo Bonzini  * If a dereference did happen, this would suppress a defect report
127*e804f892SPaolo Bonzini  * for an actual null pointer dereference.  But it's too unlikely to
128*e804f892SPaolo Bonzini  * be worth wading through the false positives, and with some luck
129*e804f892SPaolo Bonzini  * we'll get a buffer overflow reported anyway.
130*e804f892SPaolo Bonzini  */
131*e804f892SPaolo Bonzini 
132*e804f892SPaolo Bonzini /*
133*e804f892SPaolo Bonzini  * Allocation primitives, cannot return NULL
134*e804f892SPaolo Bonzini  * See also Coverity's library/generic/libc/all/all.c
135*e804f892SPaolo Bonzini  */
136*e804f892SPaolo Bonzini 
137*e804f892SPaolo Bonzini void *g_malloc_n(size_t nmemb, size_t size)
138*e804f892SPaolo Bonzini {
139*e804f892SPaolo Bonzini     size_t sz;
140*e804f892SPaolo Bonzini     void *ptr;
141*e804f892SPaolo Bonzini 
142*e804f892SPaolo Bonzini     __coverity_negative_sink__(nmemb);
143*e804f892SPaolo Bonzini     __coverity_negative_sink__(size);
144*e804f892SPaolo Bonzini     sz = nmemb * size;
145*e804f892SPaolo Bonzini     ptr = __coverity_alloc__(sz);
146*e804f892SPaolo Bonzini     __coverity_mark_as_uninitialized_buffer__(ptr);
147*e804f892SPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, "g_free");
148*e804f892SPaolo Bonzini     return ptr;
149*e804f892SPaolo Bonzini }
150*e804f892SPaolo Bonzini 
151*e804f892SPaolo Bonzini void *g_malloc0_n(size_t nmemb, size_t size)
152*e804f892SPaolo Bonzini {
153*e804f892SPaolo Bonzini     size_t sz;
154*e804f892SPaolo Bonzini     void *ptr;
155*e804f892SPaolo Bonzini 
156*e804f892SPaolo Bonzini     __coverity_negative_sink__(nmemb);
157*e804f892SPaolo Bonzini     __coverity_negative_sink__(size);
158*e804f892SPaolo Bonzini     sz = nmemb * size;
159*e804f892SPaolo Bonzini     ptr = __coverity_alloc__(sz);
160*e804f892SPaolo Bonzini     __coverity_writeall0__(ptr);
161*e804f892SPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, "g_free");
162*e804f892SPaolo Bonzini     return ptr;
163*e804f892SPaolo Bonzini }
164*e804f892SPaolo Bonzini 
165*e804f892SPaolo Bonzini void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
166*e804f892SPaolo Bonzini {
167*e804f892SPaolo Bonzini     size_t sz;
168*e804f892SPaolo Bonzini 
169*e804f892SPaolo Bonzini     __coverity_negative_sink__(nmemb);
170*e804f892SPaolo Bonzini     __coverity_negative_sink__(size);
171*e804f892SPaolo Bonzini     sz = nmemb * size;
172*e804f892SPaolo Bonzini     __coverity_escape__(ptr);
173*e804f892SPaolo Bonzini     ptr = __coverity_alloc__(sz);
174*e804f892SPaolo Bonzini     /*
175*e804f892SPaolo Bonzini      * Memory beyond the old size isn't actually initialized.  Can't
176*e804f892SPaolo Bonzini      * model that.  See Coverity's realloc() model
177*e804f892SPaolo Bonzini      */
178*e804f892SPaolo Bonzini     __coverity_writeall__(ptr);
179*e804f892SPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, "g_free");
180*e804f892SPaolo Bonzini     return ptr;
181*e804f892SPaolo Bonzini }
182*e804f892SPaolo Bonzini 
183*e804f892SPaolo Bonzini void g_free(void *ptr)
184*e804f892SPaolo Bonzini {
185*e804f892SPaolo Bonzini     __coverity_free__(ptr);
186*e804f892SPaolo Bonzini     __coverity_mark_as_afm_freed__(ptr, "g_free");
187*e804f892SPaolo Bonzini }
188*e804f892SPaolo Bonzini 
189*e804f892SPaolo Bonzini /*
190*e804f892SPaolo Bonzini  * Derive the g_try_FOO_n() from the g_FOO_n() by adding indeterminate
191*e804f892SPaolo Bonzini  * out of memory conditions
192*e804f892SPaolo Bonzini  */
193*e804f892SPaolo Bonzini 
194*e804f892SPaolo Bonzini void *g_try_malloc_n(size_t nmemb, size_t size)
195*e804f892SPaolo Bonzini {
196*e804f892SPaolo Bonzini     int nomem;
197*e804f892SPaolo Bonzini 
198*e804f892SPaolo Bonzini     if (nomem) {
199*e804f892SPaolo Bonzini         return NULL;
200*e804f892SPaolo Bonzini     }
201*e804f892SPaolo Bonzini     return g_malloc_n(nmemb, size);
202*e804f892SPaolo Bonzini }
203*e804f892SPaolo Bonzini 
204*e804f892SPaolo Bonzini void *g_try_malloc0_n(size_t nmemb, size_t size)
205*e804f892SPaolo Bonzini {
206*e804f892SPaolo Bonzini     int nomem;
207*e804f892SPaolo Bonzini 
208*e804f892SPaolo Bonzini     if (nomem) {
209*e804f892SPaolo Bonzini         return NULL;
210*e804f892SPaolo Bonzini     }
211*e804f892SPaolo Bonzini     return g_malloc0_n(nmemb, size);
212*e804f892SPaolo Bonzini }
213*e804f892SPaolo Bonzini 
214*e804f892SPaolo Bonzini void *g_try_realloc_n(void *ptr, size_t nmemb, size_t size)
215*e804f892SPaolo Bonzini {
216*e804f892SPaolo Bonzini     int nomem;
217*e804f892SPaolo Bonzini 
218*e804f892SPaolo Bonzini     if (nomem) {
219*e804f892SPaolo Bonzini         return NULL;
220*e804f892SPaolo Bonzini     }
221*e804f892SPaolo Bonzini     return g_realloc_n(ptr, nmemb, size);
222*e804f892SPaolo Bonzini }
223*e804f892SPaolo Bonzini 
224*e804f892SPaolo Bonzini /* Trivially derive the g_FOO() from the g_FOO_n() */
225*e804f892SPaolo Bonzini 
226*e804f892SPaolo Bonzini void *g_malloc(size_t size)
227*e804f892SPaolo Bonzini {
228*e804f892SPaolo Bonzini     return g_malloc_n(1, size);
229*e804f892SPaolo Bonzini }
230*e804f892SPaolo Bonzini 
231*e804f892SPaolo Bonzini void *g_malloc0(size_t size)
232*e804f892SPaolo Bonzini {
233*e804f892SPaolo Bonzini     return g_malloc0_n(1, size);
234*e804f892SPaolo Bonzini }
235*e804f892SPaolo Bonzini 
236*e804f892SPaolo Bonzini void *g_realloc(void *ptr, size_t size)
237*e804f892SPaolo Bonzini {
238*e804f892SPaolo Bonzini     return g_realloc_n(ptr, 1, size);
239*e804f892SPaolo Bonzini }
240*e804f892SPaolo Bonzini 
241*e804f892SPaolo Bonzini void *g_try_malloc(size_t size)
242*e804f892SPaolo Bonzini {
243*e804f892SPaolo Bonzini     return g_try_malloc_n(1, size);
244*e804f892SPaolo Bonzini }
245*e804f892SPaolo Bonzini 
246*e804f892SPaolo Bonzini void *g_try_malloc0(size_t size)
247*e804f892SPaolo Bonzini {
248*e804f892SPaolo Bonzini     return g_try_malloc0_n(1, size);
249*e804f892SPaolo Bonzini }
250*e804f892SPaolo Bonzini 
251*e804f892SPaolo Bonzini void *g_try_realloc(void *ptr, size_t size)
252*e804f892SPaolo Bonzini {
253*e804f892SPaolo Bonzini     return g_try_realloc_n(ptr, 1, size);
254*e804f892SPaolo Bonzini }
255*e804f892SPaolo Bonzini 
256*e804f892SPaolo Bonzini /* Other memory allocation functions */
257*e804f892SPaolo Bonzini 
258*e804f892SPaolo Bonzini void *g_memdup(const void *ptr, unsigned size)
259*e804f892SPaolo Bonzini {
260*e804f892SPaolo Bonzini     unsigned char *dup;
261*e804f892SPaolo Bonzini     unsigned i;
262*e804f892SPaolo Bonzini 
263*e804f892SPaolo Bonzini     if (!ptr) {
264*e804f892SPaolo Bonzini         return NULL;
265*e804f892SPaolo Bonzini     }
266*e804f892SPaolo Bonzini 
267*e804f892SPaolo Bonzini     dup = g_malloc(size);
268*e804f892SPaolo Bonzini     for (i = 0; i < size; i++)
269*e804f892SPaolo Bonzini         dup[i] = ((unsigned char *)ptr)[i];
270*e804f892SPaolo Bonzini     return dup;
271*e804f892SPaolo Bonzini }
272*e804f892SPaolo Bonzini 
273*e804f892SPaolo Bonzini /*
274*e804f892SPaolo Bonzini  * GLib string allocation functions
275*e804f892SPaolo Bonzini  */
276*e804f892SPaolo Bonzini 
277*e804f892SPaolo Bonzini char *g_strdup(const char *s)
278*e804f892SPaolo Bonzini {
279*e804f892SPaolo Bonzini     char *dup;
280*e804f892SPaolo Bonzini     size_t i;
281*e804f892SPaolo Bonzini 
282*e804f892SPaolo Bonzini     if (!s) {
283*e804f892SPaolo Bonzini         return NULL;
284*e804f892SPaolo Bonzini     }
285*e804f892SPaolo Bonzini 
286*e804f892SPaolo Bonzini     __coverity_string_null_sink__(s);
287*e804f892SPaolo Bonzini     __coverity_string_size_sink__(s);
288*e804f892SPaolo Bonzini     dup = __coverity_alloc_nosize__();
289*e804f892SPaolo Bonzini     __coverity_mark_as_afm_allocated__(dup, "g_free");
290*e804f892SPaolo Bonzini     for (i = 0; (dup[i] = s[i]); i++) ;
291*e804f892SPaolo Bonzini     return dup;
292*e804f892SPaolo Bonzini }
293*e804f892SPaolo Bonzini 
294*e804f892SPaolo Bonzini char *g_strndup(const char *s, size_t n)
295*e804f892SPaolo Bonzini {
296*e804f892SPaolo Bonzini     char *dup;
297*e804f892SPaolo Bonzini     size_t i;
298*e804f892SPaolo Bonzini 
299*e804f892SPaolo Bonzini     __coverity_negative_sink__(n);
300*e804f892SPaolo Bonzini 
301*e804f892SPaolo Bonzini     if (!s) {
302*e804f892SPaolo Bonzini         return NULL;
303*e804f892SPaolo Bonzini     }
304*e804f892SPaolo Bonzini 
305*e804f892SPaolo Bonzini     dup = g_malloc(n + 1);
306*e804f892SPaolo Bonzini     for (i = 0; i < n && (dup[i] = s[i]); i++) ;
307*e804f892SPaolo Bonzini     dup[i] = 0;
308*e804f892SPaolo Bonzini     return dup;
309*e804f892SPaolo Bonzini }
310*e804f892SPaolo Bonzini 
311*e804f892SPaolo Bonzini char *g_strdup_printf(const char *format, ...)
312*e804f892SPaolo Bonzini {
313*e804f892SPaolo Bonzini     char ch, *s;
314*e804f892SPaolo Bonzini     size_t len;
315*e804f892SPaolo Bonzini 
316*e804f892SPaolo Bonzini     __coverity_string_null_sink__(format);
317*e804f892SPaolo Bonzini     __coverity_string_size_sink__(format);
318*e804f892SPaolo Bonzini 
319*e804f892SPaolo Bonzini     ch = *format;
320*e804f892SPaolo Bonzini 
321*e804f892SPaolo Bonzini     s = __coverity_alloc_nosize__();
322*e804f892SPaolo Bonzini     __coverity_writeall__(s);
323*e804f892SPaolo Bonzini     __coverity_mark_as_afm_allocated__(s, "g_free");
324*e804f892SPaolo Bonzini     return s;
325*e804f892SPaolo Bonzini }
326*e804f892SPaolo Bonzini 
327*e804f892SPaolo Bonzini char *g_strdup_vprintf(const char *format, va_list ap)
328*e804f892SPaolo Bonzini {
329*e804f892SPaolo Bonzini     char ch, *s;
330*e804f892SPaolo Bonzini     size_t len;
331*e804f892SPaolo Bonzini 
332*e804f892SPaolo Bonzini     __coverity_string_null_sink__(format);
333*e804f892SPaolo Bonzini     __coverity_string_size_sink__(format);
334*e804f892SPaolo Bonzini 
335*e804f892SPaolo Bonzini     ch = *format;
336*e804f892SPaolo Bonzini     ch = *(char *)ap;
337*e804f892SPaolo Bonzini 
338*e804f892SPaolo Bonzini     s = __coverity_alloc_nosize__();
339*e804f892SPaolo Bonzini     __coverity_writeall__(s);
340*e804f892SPaolo Bonzini     __coverity_mark_as_afm_allocated__(s, "g_free");
341*e804f892SPaolo Bonzini 
342*e804f892SPaolo Bonzini     return len;
343*e804f892SPaolo Bonzini }
344*e804f892SPaolo Bonzini 
345*e804f892SPaolo Bonzini char *g_strconcat(const char *s, ...)
346*e804f892SPaolo Bonzini {
347*e804f892SPaolo Bonzini     char *s;
348*e804f892SPaolo Bonzini 
349*e804f892SPaolo Bonzini     /*
350*e804f892SPaolo Bonzini      * Can't model: last argument must be null, the others
351*e804f892SPaolo Bonzini      * null-terminated strings
352*e804f892SPaolo Bonzini      */
353*e804f892SPaolo Bonzini 
354*e804f892SPaolo Bonzini     s = __coverity_alloc_nosize__();
355*e804f892SPaolo Bonzini     __coverity_writeall__(s);
356*e804f892SPaolo Bonzini     __coverity_mark_as_afm_allocated__(s, "g_free");
357*e804f892SPaolo Bonzini     return s;
358*e804f892SPaolo Bonzini }
359*e804f892SPaolo Bonzini 
360*e804f892SPaolo Bonzini /* Other glib functions */
361*e804f892SPaolo Bonzini 
362*e804f892SPaolo Bonzini typedef struct pollfd GPollFD;
363*e804f892SPaolo Bonzini 
364*e804f892SPaolo Bonzini int poll();
365*e804f892SPaolo Bonzini 
366*e804f892SPaolo Bonzini int g_poll (GPollFD *fds, unsigned nfds, int timeout)
367*e804f892SPaolo Bonzini {
368*e804f892SPaolo Bonzini     return poll(fds, nfds, timeout);
369*e804f892SPaolo Bonzini }
370*e804f892SPaolo Bonzini 
371*e804f892SPaolo Bonzini typedef struct _GIOChannel GIOChannel;
372*e804f892SPaolo Bonzini GIOChannel *g_io_channel_unix_new(int fd)
373*e804f892SPaolo Bonzini {
374*e804f892SPaolo Bonzini     GIOChannel *c = g_malloc0(sizeof(GIOChannel));
375*e804f892SPaolo Bonzini     __coverity_escape__(fd);
376*e804f892SPaolo Bonzini     return c;
377*e804f892SPaolo Bonzini }
378*e804f892SPaolo Bonzini 
379*e804f892SPaolo Bonzini void g_assertion_message_expr(const char     *domain,
380*e804f892SPaolo Bonzini                               const char     *file,
381*e804f892SPaolo Bonzini                               int             line,
382*e804f892SPaolo Bonzini                               const char     *func,
383*e804f892SPaolo Bonzini                               const char     *expr)
384*e804f892SPaolo Bonzini {
385*e804f892SPaolo Bonzini     __coverity_panic__();
386*e804f892SPaolo Bonzini }
387