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