xref: /qemu/scripts/coverity-scan/model.c (revision 906b8bab8bbc588f19752ed19e0222330dce31f9)
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 
43e4b77daaSMarkus Armbruster typedef struct va_list_str *va_list;
44e4b77daaSMarkus Armbruster 
45e40cdb0eSPaolo Bonzini /* exec.c */
46e40cdb0eSPaolo Bonzini 
47e40cdb0eSPaolo Bonzini typedef struct AddressSpace AddressSpace;
48e40cdb0eSPaolo Bonzini typedef uint64_t hwaddr;
49e40cdb0eSPaolo Bonzini 
50e40cdb0eSPaolo Bonzini static void __write(uint8_t *buf, ssize_t len)
51e40cdb0eSPaolo Bonzini {
52e40cdb0eSPaolo Bonzini     int first, last;
53e40cdb0eSPaolo Bonzini     __coverity_negative_sink__(len);
54e40cdb0eSPaolo Bonzini     if (len == 0) return;
55e40cdb0eSPaolo Bonzini     buf[0] = first;
56e40cdb0eSPaolo Bonzini     buf[len-1] = last;
57e40cdb0eSPaolo Bonzini     __coverity_writeall__(buf);
58e40cdb0eSPaolo Bonzini }
59e40cdb0eSPaolo Bonzini 
60e40cdb0eSPaolo Bonzini static void __read(uint8_t *buf, ssize_t len)
61e40cdb0eSPaolo Bonzini {
62e40cdb0eSPaolo Bonzini     __coverity_negative_sink__(len);
63e40cdb0eSPaolo Bonzini     if (len == 0) return;
64e40cdb0eSPaolo Bonzini     int first = buf[0];
65e40cdb0eSPaolo Bonzini     int last = buf[len-1];
66e40cdb0eSPaolo Bonzini }
67e40cdb0eSPaolo Bonzini 
68e40cdb0eSPaolo Bonzini bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf,
69e40cdb0eSPaolo Bonzini                       int len, bool is_write)
70e40cdb0eSPaolo Bonzini {
71e40cdb0eSPaolo Bonzini     bool result;
72e40cdb0eSPaolo Bonzini 
73e40cdb0eSPaolo Bonzini     // TODO: investigate impact of treating reads as producing
74e40cdb0eSPaolo Bonzini     // tainted data, with __coverity_tainted_data_argument__(buf).
75e40cdb0eSPaolo Bonzini     if (is_write) __write(buf, len); else __read(buf, len);
76e40cdb0eSPaolo Bonzini 
77e40cdb0eSPaolo Bonzini     return result;
78e40cdb0eSPaolo Bonzini }
79e40cdb0eSPaolo Bonzini 
80e40cdb0eSPaolo Bonzini /* Tainting */
81e40cdb0eSPaolo Bonzini 
82e40cdb0eSPaolo Bonzini typedef struct {} name2keysym_t;
83e40cdb0eSPaolo Bonzini static int get_keysym(const name2keysym_t *table,
84e40cdb0eSPaolo Bonzini                       const char *name)
85e40cdb0eSPaolo Bonzini {
86e40cdb0eSPaolo Bonzini     int result;
87e40cdb0eSPaolo Bonzini     if (result > 0) {
88e40cdb0eSPaolo Bonzini         __coverity_tainted_string_sanitize_content__(name);
89e40cdb0eSPaolo Bonzini         return result;
90e40cdb0eSPaolo Bonzini     } else {
91e40cdb0eSPaolo Bonzini         return 0;
92e40cdb0eSPaolo Bonzini     }
93e40cdb0eSPaolo Bonzini }
94e40cdb0eSPaolo Bonzini 
959d7a4c66SMarkus Armbruster /*
969d7a4c66SMarkus Armbruster  * GLib memory allocation functions.
97e40cdb0eSPaolo Bonzini  *
98e40cdb0eSPaolo Bonzini  * Note that we ignore the fact that g_malloc of 0 bytes returns NULL,
99e40cdb0eSPaolo Bonzini  * and g_realloc of 0 bytes frees the pointer.
100e40cdb0eSPaolo Bonzini  *
101e40cdb0eSPaolo Bonzini  * Modeling this would result in Coverity flagging a lot of memory
102e40cdb0eSPaolo Bonzini  * allocations as potentially returning NULL, and asking us to check
103e40cdb0eSPaolo Bonzini  * whether the result of the allocation is NULL or not.  However, the
104e40cdb0eSPaolo Bonzini  * resulting pointer should never be dereferenced anyway, and in fact
105e40cdb0eSPaolo Bonzini  * it is not in the vast majority of cases.
106e40cdb0eSPaolo Bonzini  *
107e40cdb0eSPaolo Bonzini  * If a dereference did happen, this would suppress a defect report
108e40cdb0eSPaolo Bonzini  * for an actual null pointer dereference.  But it's too unlikely to
109e40cdb0eSPaolo Bonzini  * be worth wading through the false positives, and with some luck
110e40cdb0eSPaolo Bonzini  * we'll get a buffer overflow reported anyway.
111e40cdb0eSPaolo Bonzini  */
112e40cdb0eSPaolo Bonzini 
1139d7a4c66SMarkus Armbruster /*
1149d7a4c66SMarkus Armbruster  * Allocation primitives, cannot return NULL
1159d7a4c66SMarkus Armbruster  * See also Coverity's library/generic/libc/all/all.c
1169d7a4c66SMarkus Armbruster  */
117e40cdb0eSPaolo Bonzini 
1189d7a4c66SMarkus Armbruster void *g_malloc_n(size_t nmemb, size_t size)
119e40cdb0eSPaolo Bonzini {
1209d7a4c66SMarkus Armbruster     size_t sz;
1219d7a4c66SMarkus Armbruster     void *ptr;
1229d7a4c66SMarkus Armbruster 
1239d7a4c66SMarkus Armbruster     __coverity_negative_sink__(nmemb);
1249d7a4c66SMarkus Armbruster     __coverity_negative_sink__(size);
1259d7a4c66SMarkus Armbruster     sz = nmemb * size;
126*906b8babSJan Kiszka     ptr = __coverity_alloc__(sz);
1279d7a4c66SMarkus Armbruster     __coverity_mark_as_uninitialized_buffer__(ptr);
1287ad4c720SMarkus Armbruster     __coverity_mark_as_afm_allocated__(ptr, "g_free");
1299d7a4c66SMarkus Armbruster     return ptr;
130e40cdb0eSPaolo Bonzini }
131e40cdb0eSPaolo Bonzini 
1329d7a4c66SMarkus Armbruster void *g_malloc0_n(size_t nmemb, size_t size)
133e40cdb0eSPaolo Bonzini {
1349d7a4c66SMarkus Armbruster     size_t sz;
1359d7a4c66SMarkus Armbruster     void *ptr;
1369d7a4c66SMarkus Armbruster 
1379d7a4c66SMarkus Armbruster     __coverity_negative_sink__(nmemb);
1389d7a4c66SMarkus Armbruster     __coverity_negative_sink__(size);
1399d7a4c66SMarkus Armbruster     sz = nmemb * size;
140*906b8babSJan Kiszka     ptr = __coverity_alloc__(sz);
1419d7a4c66SMarkus Armbruster     __coverity_writeall0__(ptr);
1427ad4c720SMarkus Armbruster     __coverity_mark_as_afm_allocated__(ptr, "g_free");
1439d7a4c66SMarkus Armbruster     return ptr;
144e40cdb0eSPaolo Bonzini }
145e40cdb0eSPaolo Bonzini 
1469d7a4c66SMarkus Armbruster void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
147e40cdb0eSPaolo Bonzini {
1489d7a4c66SMarkus Armbruster     size_t sz;
1499d7a4c66SMarkus Armbruster 
1509d7a4c66SMarkus Armbruster     __coverity_negative_sink__(nmemb);
1519d7a4c66SMarkus Armbruster     __coverity_negative_sink__(size);
1529d7a4c66SMarkus Armbruster     sz = nmemb * size;
1539d7a4c66SMarkus Armbruster     __coverity_escape__(ptr);
154*906b8babSJan Kiszka     ptr = __coverity_alloc__(sz);
1559d7a4c66SMarkus Armbruster     /*
1569d7a4c66SMarkus Armbruster      * Memory beyond the old size isn't actually initialized.  Can't
1579d7a4c66SMarkus Armbruster      * model that.  See Coverity's realloc() model
1589d7a4c66SMarkus Armbruster      */
1599d7a4c66SMarkus Armbruster     __coverity_writeall__(ptr);
1607ad4c720SMarkus Armbruster     __coverity_mark_as_afm_allocated__(ptr, "g_free");
1619d7a4c66SMarkus Armbruster     return ptr;
162e40cdb0eSPaolo Bonzini }
163e40cdb0eSPaolo Bonzini 
1649d7a4c66SMarkus Armbruster void g_free(void *ptr)
165e40cdb0eSPaolo Bonzini {
1669d7a4c66SMarkus Armbruster     __coverity_free__(ptr);
1677ad4c720SMarkus Armbruster     __coverity_mark_as_afm_freed__(ptr, "g_free");
168e40cdb0eSPaolo Bonzini }
169e40cdb0eSPaolo Bonzini 
1709d7a4c66SMarkus Armbruster /*
1719d7a4c66SMarkus Armbruster  * Derive the g_try_FOO_n() from the g_FOO_n() by adding indeterminate
1729d7a4c66SMarkus Armbruster  * out of memory conditions
1739d7a4c66SMarkus Armbruster  */
1749d7a4c66SMarkus Armbruster 
1759d7a4c66SMarkus Armbruster void *g_try_malloc_n(size_t nmemb, size_t size)
176e40cdb0eSPaolo Bonzini {
1779d7a4c66SMarkus Armbruster     int nomem;
1789d7a4c66SMarkus Armbruster 
1799d7a4c66SMarkus Armbruster     if (nomem) {
1809d7a4c66SMarkus Armbruster         return NULL;
1819d7a4c66SMarkus Armbruster     }
1829d7a4c66SMarkus Armbruster     return g_malloc_n(nmemb, size);
183e40cdb0eSPaolo Bonzini }
184e40cdb0eSPaolo Bonzini 
1859d7a4c66SMarkus Armbruster void *g_try_malloc0_n(size_t nmemb, size_t size)
186e40cdb0eSPaolo Bonzini {
1879d7a4c66SMarkus Armbruster     int nomem;
1889d7a4c66SMarkus Armbruster 
1899d7a4c66SMarkus Armbruster     if (nomem) {
1909d7a4c66SMarkus Armbruster         return NULL;
1919d7a4c66SMarkus Armbruster     }
1929d7a4c66SMarkus Armbruster     return g_malloc0_n(nmemb, size);
193e40cdb0eSPaolo Bonzini }
194e40cdb0eSPaolo Bonzini 
1959d7a4c66SMarkus Armbruster void *g_try_realloc_n(void *ptr, size_t nmemb, size_t size)
196e40cdb0eSPaolo Bonzini {
1979d7a4c66SMarkus Armbruster     int nomem;
1989d7a4c66SMarkus Armbruster 
1999d7a4c66SMarkus Armbruster     if (nomem) {
2009d7a4c66SMarkus Armbruster         return NULL;
2019d7a4c66SMarkus Armbruster     }
2029d7a4c66SMarkus Armbruster     return g_realloc_n(ptr, nmemb, size);
2039d7a4c66SMarkus Armbruster }
2049d7a4c66SMarkus Armbruster 
2059d7a4c66SMarkus Armbruster /* Trivially derive the g_FOO() from the g_FOO_n() */
2069d7a4c66SMarkus Armbruster 
2079d7a4c66SMarkus Armbruster void *g_malloc(size_t size)
2089d7a4c66SMarkus Armbruster {
2099d7a4c66SMarkus Armbruster     return g_malloc_n(1, size);
2109d7a4c66SMarkus Armbruster }
2119d7a4c66SMarkus Armbruster 
2129d7a4c66SMarkus Armbruster void *g_malloc0(size_t size)
2139d7a4c66SMarkus Armbruster {
2149d7a4c66SMarkus Armbruster     return g_malloc0_n(1, size);
2159d7a4c66SMarkus Armbruster }
2169d7a4c66SMarkus Armbruster 
2179d7a4c66SMarkus Armbruster void *g_realloc(void *ptr, size_t size)
2189d7a4c66SMarkus Armbruster {
2199d7a4c66SMarkus Armbruster     return g_realloc_n(ptr, 1, size);
2209d7a4c66SMarkus Armbruster }
2219d7a4c66SMarkus Armbruster 
2229d7a4c66SMarkus Armbruster void *g_try_malloc(size_t size)
2239d7a4c66SMarkus Armbruster {
2249d7a4c66SMarkus Armbruster     return g_try_malloc_n(1, size);
2259d7a4c66SMarkus Armbruster }
2269d7a4c66SMarkus Armbruster 
2279d7a4c66SMarkus Armbruster void *g_try_malloc0(size_t size)
2289d7a4c66SMarkus Armbruster {
2299d7a4c66SMarkus Armbruster     return g_try_malloc0_n(1, size);
2309d7a4c66SMarkus Armbruster }
2319d7a4c66SMarkus Armbruster 
2329d7a4c66SMarkus Armbruster void *g_try_realloc(void *ptr, size_t size)
2339d7a4c66SMarkus Armbruster {
2349d7a4c66SMarkus Armbruster     return g_try_realloc_n(ptr, 1, size);
235e40cdb0eSPaolo Bonzini }
236e40cdb0eSPaolo Bonzini 
237e4b77daaSMarkus Armbruster /*
238e4b77daaSMarkus Armbruster  * GLib string allocation functions
239e4b77daaSMarkus Armbruster  */
240e4b77daaSMarkus Armbruster 
241e4b77daaSMarkus Armbruster char *g_strdup(const char *s)
242e4b77daaSMarkus Armbruster {
243e4b77daaSMarkus Armbruster     char *dup;
244e4b77daaSMarkus Armbruster     size_t i;
245e4b77daaSMarkus Armbruster 
246e4b77daaSMarkus Armbruster     if (!s) {
247e4b77daaSMarkus Armbruster         return NULL;
248e4b77daaSMarkus Armbruster     }
249e4b77daaSMarkus Armbruster 
250e4b77daaSMarkus Armbruster     __coverity_string_null_sink__(s);
251e4b77daaSMarkus Armbruster     __coverity_string_size_sink__(s);
252e4b77daaSMarkus Armbruster     dup = __coverity_alloc_nosize__();
2537ad4c720SMarkus Armbruster     __coverity_mark_as_afm_allocated__(dup, "g_free");
254e4b77daaSMarkus Armbruster     for (i = 0; (dup[i] = s[i]); i++) ;
255e4b77daaSMarkus Armbruster     return dup;
256e4b77daaSMarkus Armbruster }
257e4b77daaSMarkus Armbruster 
258e4b77daaSMarkus Armbruster char *g_strndup(const char *s, size_t n)
259e4b77daaSMarkus Armbruster {
260e4b77daaSMarkus Armbruster     char *dup;
261e4b77daaSMarkus Armbruster     size_t i;
262e4b77daaSMarkus Armbruster 
263e4b77daaSMarkus Armbruster     __coverity_negative_sink__(n);
264e4b77daaSMarkus Armbruster 
265e4b77daaSMarkus Armbruster     if (!s) {
266e4b77daaSMarkus Armbruster         return NULL;
267e4b77daaSMarkus Armbruster     }
268e4b77daaSMarkus Armbruster 
269e4b77daaSMarkus Armbruster     dup = g_malloc(n + 1);
270e4b77daaSMarkus Armbruster     for (i = 0; i < n && (dup[i] = s[i]); i++) ;
271e4b77daaSMarkus Armbruster     dup[i] = 0;
272e4b77daaSMarkus Armbruster     return dup;
273e4b77daaSMarkus Armbruster }
274e4b77daaSMarkus Armbruster 
275e4b77daaSMarkus Armbruster char *g_strdup_printf(const char *format, ...)
276e4b77daaSMarkus Armbruster {
277e4b77daaSMarkus Armbruster     char ch, *s;
278e4b77daaSMarkus Armbruster     size_t len;
279e4b77daaSMarkus Armbruster 
280e4b77daaSMarkus Armbruster     __coverity_string_null_sink__(format);
281e4b77daaSMarkus Armbruster     __coverity_string_size_sink__(format);
282e4b77daaSMarkus Armbruster 
283e4b77daaSMarkus Armbruster     ch = *format;
284e4b77daaSMarkus Armbruster 
285e4b77daaSMarkus Armbruster     s = __coverity_alloc_nosize__();
286e4b77daaSMarkus Armbruster     __coverity_writeall__(s);
2877ad4c720SMarkus Armbruster     __coverity_mark_as_afm_allocated__(s, "g_free");
288e4b77daaSMarkus Armbruster     return s;
289e4b77daaSMarkus Armbruster }
290e4b77daaSMarkus Armbruster 
291e4b77daaSMarkus Armbruster char *g_strdup_vprintf(const char *format, va_list ap)
292e4b77daaSMarkus Armbruster {
293e4b77daaSMarkus Armbruster     char ch, *s;
294e4b77daaSMarkus Armbruster     size_t len;
295e4b77daaSMarkus Armbruster 
296e4b77daaSMarkus Armbruster     __coverity_string_null_sink__(format);
297e4b77daaSMarkus Armbruster     __coverity_string_size_sink__(format);
298e4b77daaSMarkus Armbruster 
299e4b77daaSMarkus Armbruster     ch = *format;
300e4b77daaSMarkus Armbruster     ch = *(char *)ap;
301e4b77daaSMarkus Armbruster 
302e4b77daaSMarkus Armbruster     s = __coverity_alloc_nosize__();
303e4b77daaSMarkus Armbruster     __coverity_writeall__(s);
3047ad4c720SMarkus Armbruster     __coverity_mark_as_afm_allocated__(s, "g_free");
305e4b77daaSMarkus Armbruster 
306e4b77daaSMarkus Armbruster     return len;
307e4b77daaSMarkus Armbruster }
308e4b77daaSMarkus Armbruster 
309e4b77daaSMarkus Armbruster char *g_strconcat(const char *s, ...)
310e4b77daaSMarkus Armbruster {
311e4b77daaSMarkus Armbruster     char *s;
312e4b77daaSMarkus Armbruster 
313e4b77daaSMarkus Armbruster     /*
314e4b77daaSMarkus Armbruster      * Can't model: last argument must be null, the others
315e4b77daaSMarkus Armbruster      * null-terminated strings
316e4b77daaSMarkus Armbruster      */
317e4b77daaSMarkus Armbruster 
318e4b77daaSMarkus Armbruster     s = __coverity_alloc_nosize__();
319e4b77daaSMarkus Armbruster     __coverity_writeall__(s);
3207ad4c720SMarkus Armbruster     __coverity_mark_as_afm_allocated__(s, "g_free");
321e4b77daaSMarkus Armbruster     return s;
322e4b77daaSMarkus Armbruster }
323e4b77daaSMarkus Armbruster 
324e40cdb0eSPaolo Bonzini /* Other glib functions */
325e40cdb0eSPaolo Bonzini 
326e40cdb0eSPaolo Bonzini typedef struct _GIOChannel GIOChannel;
327e40cdb0eSPaolo Bonzini GIOChannel *g_io_channel_unix_new(int fd)
328e40cdb0eSPaolo Bonzini {
329e40cdb0eSPaolo Bonzini     GIOChannel *c = g_malloc0(sizeof(GIOChannel));
330e40cdb0eSPaolo Bonzini     __coverity_escape__(fd);
331e40cdb0eSPaolo Bonzini     return c;
332e40cdb0eSPaolo Bonzini }
333e40cdb0eSPaolo Bonzini 
334e40cdb0eSPaolo Bonzini void g_assertion_message_expr(const char     *domain,
335e40cdb0eSPaolo Bonzini                               const char     *file,
336e40cdb0eSPaolo Bonzini                               int             line,
337e40cdb0eSPaolo Bonzini                               const char     *func,
338e40cdb0eSPaolo Bonzini                               const char     *expr)
339e40cdb0eSPaolo Bonzini {
340e40cdb0eSPaolo Bonzini     __coverity_panic__();
341e40cdb0eSPaolo Bonzini }
342