xref: /qemu/scripts/coverity-scan/model.c (revision 96915d638cb83aa139e39096815b8dd9832f264b)
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;
48d4b3d152SPaolo Bonzini typedef struct MemoryRegionCache MemoryRegionCache;
49e40cdb0eSPaolo Bonzini typedef uint64_t hwaddr;
505c9eb028SPeter Maydell typedef uint32_t MemTxResult;
51d4b3d152SPaolo Bonzini typedef struct MemTxAttrs {} MemTxAttrs;
52e40cdb0eSPaolo Bonzini 
532e1c92daSPaolo Bonzini static void __bufwrite(uint8_t *buf, ssize_t len)
54e40cdb0eSPaolo Bonzini {
55e40cdb0eSPaolo Bonzini     int first, last;
56e40cdb0eSPaolo Bonzini     __coverity_negative_sink__(len);
57e40cdb0eSPaolo Bonzini     if (len == 0) return;
58e40cdb0eSPaolo Bonzini     buf[0] = first;
59e40cdb0eSPaolo Bonzini     buf[len-1] = last;
60e40cdb0eSPaolo Bonzini     __coverity_writeall__(buf);
61e40cdb0eSPaolo Bonzini }
62e40cdb0eSPaolo Bonzini 
632e1c92daSPaolo Bonzini static void __bufread(uint8_t *buf, ssize_t len)
64e40cdb0eSPaolo Bonzini {
65e40cdb0eSPaolo Bonzini     __coverity_negative_sink__(len);
66e40cdb0eSPaolo Bonzini     if (len == 0) return;
67e40cdb0eSPaolo Bonzini     int first = buf[0];
68e40cdb0eSPaolo Bonzini     int last = buf[len-1];
69e40cdb0eSPaolo Bonzini }
70e40cdb0eSPaolo Bonzini 
71d4b3d152SPaolo Bonzini MemTxResult address_space_read_cached(MemoryRegionCache *cache, hwaddr addr,
72d4b3d152SPaolo Bonzini                                       MemTxAttrs attrs,
73d4b3d152SPaolo Bonzini                                       void *buf, int len)
74d4b3d152SPaolo Bonzini {
75d4b3d152SPaolo Bonzini     MemTxResult result;
76d4b3d152SPaolo Bonzini     // TODO: investigate impact of treating reads as producing
77d4b3d152SPaolo Bonzini     // tainted data, with __coverity_tainted_data_argument__(buf).
78d4b3d152SPaolo Bonzini     __bufwrite(buf, len);
79d4b3d152SPaolo Bonzini     return result;
80d4b3d152SPaolo Bonzini }
81d4b3d152SPaolo Bonzini 
82d4b3d152SPaolo Bonzini MemTxResult address_space_write_cached(MemoryRegionCache *cache, hwaddr addr,
83d4b3d152SPaolo Bonzini                                 MemTxAttrs attrs,
84d4b3d152SPaolo Bonzini                                 const void *buf, int len)
85d4b3d152SPaolo Bonzini {
86d4b3d152SPaolo Bonzini     MemTxResult result;
87d4b3d152SPaolo Bonzini     __bufread(buf, len);
88d4b3d152SPaolo Bonzini     return result;
89d4b3d152SPaolo Bonzini }
90d4b3d152SPaolo Bonzini 
91d4b3d152SPaolo Bonzini MemTxResult address_space_rw_cached(MemoryRegionCache *cache, hwaddr addr,
92d4b3d152SPaolo Bonzini                                     MemTxAttrs attrs,
93d4b3d152SPaolo Bonzini                                     void *buf, int len, bool is_write)
94d4b3d152SPaolo Bonzini {
95d4b3d152SPaolo Bonzini     if (is_write) {
96d4b3d152SPaolo Bonzini         return address_space_write_cached(cache, addr, attrs, buf, len);
97d4b3d152SPaolo Bonzini     } else {
98d4b3d152SPaolo Bonzini         return address_space_read_cached(cache, addr, attrs, buf, len);
99d4b3d152SPaolo Bonzini     }
100d4b3d152SPaolo Bonzini }
101d4b3d152SPaolo Bonzini 
1024d0e7239SPaolo Bonzini MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
1034d0e7239SPaolo Bonzini                                MemTxAttrs attrs,
104d4b3d152SPaolo Bonzini                                void *buf, int len)
105e40cdb0eSPaolo Bonzini {
1065c9eb028SPeter Maydell     MemTxResult result;
107e40cdb0eSPaolo Bonzini     // TODO: investigate impact of treating reads as producing
108e40cdb0eSPaolo Bonzini     // tainted data, with __coverity_tainted_data_argument__(buf).
1094d0e7239SPaolo Bonzini     __bufwrite(buf, len);
110e40cdb0eSPaolo Bonzini     return result;
111e40cdb0eSPaolo Bonzini }
112e40cdb0eSPaolo Bonzini 
1134d0e7239SPaolo Bonzini MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
1144d0e7239SPaolo Bonzini                                 MemTxAttrs attrs,
115d4b3d152SPaolo Bonzini                                 const void *buf, int len)
1164d0e7239SPaolo Bonzini {
1174d0e7239SPaolo Bonzini     MemTxResult result;
1184d0e7239SPaolo Bonzini     __bufread(buf, len);
1194d0e7239SPaolo Bonzini     return result;
1204d0e7239SPaolo Bonzini }
1214d0e7239SPaolo Bonzini 
122d4b3d152SPaolo Bonzini MemTxResult address_space_rw(AddressSpace *as, hwaddr addr,
123d4b3d152SPaolo Bonzini                              MemTxAttrs attrs,
124d4b3d152SPaolo Bonzini                              void *buf, int len, bool is_write)
125d4b3d152SPaolo Bonzini {
126d4b3d152SPaolo Bonzini     if (is_write) {
127d4b3d152SPaolo Bonzini         return address_space_write(as, addr, attrs, buf, len);
128d4b3d152SPaolo Bonzini     } else {
129d4b3d152SPaolo Bonzini         return address_space_read(as, addr, attrs, buf, len);
130d4b3d152SPaolo Bonzini     }
131d4b3d152SPaolo Bonzini }
1324d0e7239SPaolo Bonzini 
133e40cdb0eSPaolo Bonzini /* Tainting */
134e40cdb0eSPaolo Bonzini 
135e40cdb0eSPaolo Bonzini typedef struct {} name2keysym_t;
136e40cdb0eSPaolo Bonzini static int get_keysym(const name2keysym_t *table,
137e40cdb0eSPaolo Bonzini                       const char *name)
138e40cdb0eSPaolo Bonzini {
139e40cdb0eSPaolo Bonzini     int result;
140e40cdb0eSPaolo Bonzini     if (result > 0) {
141e40cdb0eSPaolo Bonzini         __coverity_tainted_string_sanitize_content__(name);
142e40cdb0eSPaolo Bonzini         return result;
143e40cdb0eSPaolo Bonzini     } else {
144e40cdb0eSPaolo Bonzini         return 0;
145e40cdb0eSPaolo Bonzini     }
146e40cdb0eSPaolo Bonzini }
147e40cdb0eSPaolo Bonzini 
14804a0afe5SPaolo Bonzini /* Replay data is considered trusted.  */
14904a0afe5SPaolo Bonzini uint8_t replay_get_byte(void)
15004a0afe5SPaolo Bonzini {
15119020d41SMarkus Armbruster     uint8_t byte;
15204a0afe5SPaolo Bonzini     return byte;
15304a0afe5SPaolo Bonzini }
15404a0afe5SPaolo Bonzini 
15504a0afe5SPaolo Bonzini 
1569d7a4c66SMarkus Armbruster /*
1579d7a4c66SMarkus Armbruster  * GLib memory allocation functions.
158e40cdb0eSPaolo Bonzini  *
159e40cdb0eSPaolo Bonzini  * Note that we ignore the fact that g_malloc of 0 bytes returns NULL,
160e40cdb0eSPaolo Bonzini  * and g_realloc of 0 bytes frees the pointer.
161e40cdb0eSPaolo Bonzini  *
162e40cdb0eSPaolo Bonzini  * Modeling this would result in Coverity flagging a lot of memory
163e40cdb0eSPaolo Bonzini  * allocations as potentially returning NULL, and asking us to check
164e40cdb0eSPaolo Bonzini  * whether the result of the allocation is NULL or not.  However, the
165e40cdb0eSPaolo Bonzini  * resulting pointer should never be dereferenced anyway, and in fact
166e40cdb0eSPaolo Bonzini  * it is not in the vast majority of cases.
167e40cdb0eSPaolo Bonzini  *
168e40cdb0eSPaolo Bonzini  * If a dereference did happen, this would suppress a defect report
169e40cdb0eSPaolo Bonzini  * for an actual null pointer dereference.  But it's too unlikely to
170e40cdb0eSPaolo Bonzini  * be worth wading through the false positives, and with some luck
171e40cdb0eSPaolo Bonzini  * we'll get a buffer overflow reported anyway.
172e40cdb0eSPaolo Bonzini  */
173e40cdb0eSPaolo Bonzini 
1749d7a4c66SMarkus Armbruster /*
1759d7a4c66SMarkus Armbruster  * Allocation primitives, cannot return NULL
1769d7a4c66SMarkus Armbruster  * See also Coverity's library/generic/libc/all/all.c
1779d7a4c66SMarkus Armbruster  */
178e40cdb0eSPaolo Bonzini 
1799d7a4c66SMarkus Armbruster void *g_malloc_n(size_t nmemb, size_t size)
180e40cdb0eSPaolo Bonzini {
1819d7a4c66SMarkus Armbruster     size_t sz;
1829d7a4c66SMarkus Armbruster     void *ptr;
1839d7a4c66SMarkus Armbruster 
1849d7a4c66SMarkus Armbruster     __coverity_negative_sink__(nmemb);
1859d7a4c66SMarkus Armbruster     __coverity_negative_sink__(size);
1869d7a4c66SMarkus Armbruster     sz = nmemb * size;
187906b8babSJan Kiszka     ptr = __coverity_alloc__(sz);
1889d7a4c66SMarkus Armbruster     __coverity_mark_as_uninitialized_buffer__(ptr);
189243a545bSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
1909d7a4c66SMarkus Armbruster     return ptr;
191e40cdb0eSPaolo Bonzini }
192e40cdb0eSPaolo Bonzini 
1939d7a4c66SMarkus Armbruster void *g_malloc0_n(size_t nmemb, size_t size)
194e40cdb0eSPaolo Bonzini {
1959d7a4c66SMarkus Armbruster     size_t sz;
1969d7a4c66SMarkus Armbruster     void *ptr;
1979d7a4c66SMarkus Armbruster 
1989d7a4c66SMarkus Armbruster     __coverity_negative_sink__(nmemb);
1999d7a4c66SMarkus Armbruster     __coverity_negative_sink__(size);
2009d7a4c66SMarkus Armbruster     sz = nmemb * size;
201906b8babSJan Kiszka     ptr = __coverity_alloc__(sz);
2029d7a4c66SMarkus Armbruster     __coverity_writeall0__(ptr);
203243a545bSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
2049d7a4c66SMarkus Armbruster     return ptr;
205e40cdb0eSPaolo Bonzini }
206e40cdb0eSPaolo Bonzini 
2079d7a4c66SMarkus Armbruster void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
208e40cdb0eSPaolo Bonzini {
2099d7a4c66SMarkus Armbruster     size_t sz;
2109d7a4c66SMarkus Armbruster 
2119d7a4c66SMarkus Armbruster     __coverity_negative_sink__(nmemb);
2129d7a4c66SMarkus Armbruster     __coverity_negative_sink__(size);
2139d7a4c66SMarkus Armbruster     sz = nmemb * size;
2149d7a4c66SMarkus Armbruster     __coverity_escape__(ptr);
215906b8babSJan Kiszka     ptr = __coverity_alloc__(sz);
2169d7a4c66SMarkus Armbruster     /*
2179d7a4c66SMarkus Armbruster      * Memory beyond the old size isn't actually initialized.  Can't
2189d7a4c66SMarkus Armbruster      * model that.  See Coverity's realloc() model
2199d7a4c66SMarkus Armbruster      */
2209d7a4c66SMarkus Armbruster     __coverity_writeall__(ptr);
221243a545bSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
2229d7a4c66SMarkus Armbruster     return ptr;
223e40cdb0eSPaolo Bonzini }
224e40cdb0eSPaolo Bonzini 
2259d7a4c66SMarkus Armbruster void g_free(void *ptr)
226e40cdb0eSPaolo Bonzini {
2279d7a4c66SMarkus Armbruster     __coverity_free__(ptr);
228243a545bSPaolo Bonzini     __coverity_mark_as_afm_freed__(ptr, AFM_free);
229e40cdb0eSPaolo Bonzini }
230e40cdb0eSPaolo Bonzini 
2319d7a4c66SMarkus Armbruster /*
2329d7a4c66SMarkus Armbruster  * Derive the g_try_FOO_n() from the g_FOO_n() by adding indeterminate
2339d7a4c66SMarkus Armbruster  * out of memory conditions
2349d7a4c66SMarkus Armbruster  */
2359d7a4c66SMarkus Armbruster 
2369d7a4c66SMarkus Armbruster void *g_try_malloc_n(size_t nmemb, size_t size)
237e40cdb0eSPaolo Bonzini {
2389d7a4c66SMarkus Armbruster     int nomem;
2399d7a4c66SMarkus Armbruster 
2409d7a4c66SMarkus Armbruster     if (nomem) {
2419d7a4c66SMarkus Armbruster         return NULL;
2429d7a4c66SMarkus Armbruster     }
2439d7a4c66SMarkus Armbruster     return g_malloc_n(nmemb, size);
244e40cdb0eSPaolo Bonzini }
245e40cdb0eSPaolo Bonzini 
2469d7a4c66SMarkus Armbruster void *g_try_malloc0_n(size_t nmemb, size_t size)
247e40cdb0eSPaolo Bonzini {
2489d7a4c66SMarkus Armbruster     int nomem;
2499d7a4c66SMarkus Armbruster 
2509d7a4c66SMarkus Armbruster     if (nomem) {
2519d7a4c66SMarkus Armbruster         return NULL;
2529d7a4c66SMarkus Armbruster     }
2539d7a4c66SMarkus Armbruster     return g_malloc0_n(nmemb, size);
254e40cdb0eSPaolo Bonzini }
255e40cdb0eSPaolo Bonzini 
2569d7a4c66SMarkus Armbruster void *g_try_realloc_n(void *ptr, size_t nmemb, size_t size)
257e40cdb0eSPaolo Bonzini {
2589d7a4c66SMarkus Armbruster     int nomem;
2599d7a4c66SMarkus Armbruster 
2609d7a4c66SMarkus Armbruster     if (nomem) {
2619d7a4c66SMarkus Armbruster         return NULL;
2629d7a4c66SMarkus Armbruster     }
2639d7a4c66SMarkus Armbruster     return g_realloc_n(ptr, nmemb, size);
2649d7a4c66SMarkus Armbruster }
2659d7a4c66SMarkus Armbruster 
266*96915d63SPaolo Bonzini /* Derive the g_FOO() from the g_FOO_n() */
2679d7a4c66SMarkus Armbruster 
2689d7a4c66SMarkus Armbruster void *g_malloc(size_t size)
2699d7a4c66SMarkus Armbruster {
2709d7a4c66SMarkus Armbruster     return g_malloc_n(1, size);
2719d7a4c66SMarkus Armbruster }
2729d7a4c66SMarkus Armbruster 
2739d7a4c66SMarkus Armbruster void *g_malloc0(size_t size)
2749d7a4c66SMarkus Armbruster {
2759d7a4c66SMarkus Armbruster     return g_malloc0_n(1, size);
2769d7a4c66SMarkus Armbruster }
2779d7a4c66SMarkus Armbruster 
2789d7a4c66SMarkus Armbruster void *g_realloc(void *ptr, size_t size)
2799d7a4c66SMarkus Armbruster {
2809d7a4c66SMarkus Armbruster     return g_realloc_n(ptr, 1, size);
2819d7a4c66SMarkus Armbruster }
2829d7a4c66SMarkus Armbruster 
2839d7a4c66SMarkus Armbruster void *g_try_malloc(size_t size)
2849d7a4c66SMarkus Armbruster {
2859d7a4c66SMarkus Armbruster     return g_try_malloc_n(1, size);
2869d7a4c66SMarkus Armbruster }
2879d7a4c66SMarkus Armbruster 
2889d7a4c66SMarkus Armbruster void *g_try_malloc0(size_t size)
2899d7a4c66SMarkus Armbruster {
2909d7a4c66SMarkus Armbruster     return g_try_malloc0_n(1, size);
2919d7a4c66SMarkus Armbruster }
2929d7a4c66SMarkus Armbruster 
2939d7a4c66SMarkus Armbruster void *g_try_realloc(void *ptr, size_t size)
2949d7a4c66SMarkus Armbruster {
2959d7a4c66SMarkus Armbruster     return g_try_realloc_n(ptr, 1, size);
296e40cdb0eSPaolo Bonzini }
297e40cdb0eSPaolo Bonzini 
298e40cdb0eSPaolo Bonzini /* Other glib functions */
299e40cdb0eSPaolo Bonzini 
3001e819697SMarkus Armbruster typedef struct pollfd GPollFD;
3011e819697SMarkus Armbruster 
3021e819697SMarkus Armbruster int poll();
3031e819697SMarkus Armbruster 
3041e819697SMarkus Armbruster int g_poll (GPollFD *fds, unsigned nfds, int timeout)
3051e819697SMarkus Armbruster {
3061e819697SMarkus Armbruster     return poll(fds, nfds, timeout);
3071e819697SMarkus Armbruster }
3081e819697SMarkus Armbruster 
309e40cdb0eSPaolo Bonzini typedef struct _GIOChannel GIOChannel;
310e40cdb0eSPaolo Bonzini GIOChannel *g_io_channel_unix_new(int fd)
311e40cdb0eSPaolo Bonzini {
312e40cdb0eSPaolo Bonzini     GIOChannel *c = g_malloc0(sizeof(GIOChannel));
313e40cdb0eSPaolo Bonzini     __coverity_escape__(fd);
314e40cdb0eSPaolo Bonzini     return c;
315e40cdb0eSPaolo Bonzini }
316e40cdb0eSPaolo Bonzini 
317e40cdb0eSPaolo Bonzini void g_assertion_message_expr(const char     *domain,
318e40cdb0eSPaolo Bonzini                               const char     *file,
319e40cdb0eSPaolo Bonzini                               int             line,
320e40cdb0eSPaolo Bonzini                               const char     *func,
321e40cdb0eSPaolo Bonzini                               const char     *expr)
322e40cdb0eSPaolo Bonzini {
323e40cdb0eSPaolo Bonzini     __coverity_panic__();
324e40cdb0eSPaolo Bonzini }
325