xref: /openbmc/qemu/scripts/coverity-scan/model.c (revision 05ad6857)
1e804f892SPaolo Bonzini /* Coverity Scan model
2e804f892SPaolo Bonzini  *
3e804f892SPaolo Bonzini  * Copyright (C) 2014 Red Hat, Inc.
4e804f892SPaolo Bonzini  *
5e804f892SPaolo Bonzini  * Authors:
6e804f892SPaolo Bonzini  *  Markus Armbruster <armbru@redhat.com>
7e804f892SPaolo Bonzini  *  Paolo Bonzini <pbonzini@redhat.com>
8e804f892SPaolo Bonzini  *
9e804f892SPaolo Bonzini  * This work is licensed under the terms of the GNU GPL, version 2 or, at your
10e804f892SPaolo Bonzini  * option, any later version.  See the COPYING file in the top-level directory.
11e804f892SPaolo Bonzini  */
12e804f892SPaolo Bonzini 
13e804f892SPaolo Bonzini 
14e804f892SPaolo Bonzini /*
15e804f892SPaolo Bonzini  * This is the source code for our Coverity user model file.  The
16e804f892SPaolo Bonzini  * purpose of user models is to increase scanning accuracy by explaining
17e804f892SPaolo Bonzini  * code Coverity can't see (out of tree libraries) or doesn't
18e804f892SPaolo Bonzini  * sufficiently understand.  Better accuracy means both fewer false
19e804f892SPaolo Bonzini  * positives and more true defects.  Memory leaks in particular.
20e804f892SPaolo Bonzini  *
21e804f892SPaolo Bonzini  * - A model file can't import any header files.  Some built-in primitives are
22e804f892SPaolo Bonzini  *   available but not wchar_t, NULL etc.
23e804f892SPaolo Bonzini  * - Modeling doesn't need full structs and typedefs. Rudimentary structs
24e804f892SPaolo Bonzini  *   and similar types are sufficient.
25e804f892SPaolo Bonzini  * - An uninitialized local variable signifies that the variable could be
26e804f892SPaolo Bonzini  *   any value.
27e804f892SPaolo Bonzini  *
28e804f892SPaolo Bonzini  * The model file must be uploaded by an admin in the analysis settings of
29e804f892SPaolo Bonzini  * http://scan.coverity.com/projects/378
30e804f892SPaolo Bonzini  */
31e804f892SPaolo Bonzini 
32e804f892SPaolo Bonzini #define NULL ((void *)0)
33e804f892SPaolo Bonzini 
34e804f892SPaolo Bonzini typedef unsigned char uint8_t;
35e804f892SPaolo Bonzini typedef char int8_t;
36e804f892SPaolo Bonzini typedef unsigned int uint32_t;
37e804f892SPaolo Bonzini typedef int int32_t;
38e804f892SPaolo Bonzini typedef long ssize_t;
39e804f892SPaolo Bonzini typedef unsigned long long uint64_t;
40e804f892SPaolo Bonzini typedef long long int64_t;
41e804f892SPaolo Bonzini typedef _Bool bool;
42e804f892SPaolo Bonzini 
43e804f892SPaolo Bonzini typedef struct va_list_str *va_list;
44e804f892SPaolo Bonzini 
45e804f892SPaolo Bonzini /* exec.c */
46e804f892SPaolo Bonzini 
47e804f892SPaolo Bonzini typedef struct AddressSpace AddressSpace;
48d4b3d152SPaolo Bonzini typedef struct MemoryRegionCache MemoryRegionCache;
49e804f892SPaolo Bonzini typedef uint64_t hwaddr;
50e804f892SPaolo Bonzini typedef uint32_t MemTxResult;
51d4b3d152SPaolo Bonzini typedef struct MemTxAttrs {} MemTxAttrs;
52e804f892SPaolo Bonzini 
53e804f892SPaolo Bonzini static void __bufwrite(uint8_t *buf, ssize_t len)
54e804f892SPaolo Bonzini {
55e804f892SPaolo Bonzini     int first, last;
56e804f892SPaolo Bonzini     __coverity_negative_sink__(len);
57e804f892SPaolo Bonzini     if (len == 0) return;
58e804f892SPaolo Bonzini     buf[0] = first;
59e804f892SPaolo Bonzini     buf[len-1] = last;
60e804f892SPaolo Bonzini     __coverity_writeall__(buf);
61e804f892SPaolo Bonzini }
62e804f892SPaolo Bonzini 
63e804f892SPaolo Bonzini static void __bufread(uint8_t *buf, ssize_t len)
64e804f892SPaolo Bonzini {
65e804f892SPaolo Bonzini     __coverity_negative_sink__(len);
66e804f892SPaolo Bonzini     if (len == 0) return;
67e804f892SPaolo Bonzini     int first = buf[0];
68e804f892SPaolo Bonzini     int last = buf[len-1];
69e804f892SPaolo Bonzini }
70e804f892SPaolo 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 
102e804f892SPaolo Bonzini MemTxResult address_space_read(AddressSpace *as, hwaddr addr,
103e804f892SPaolo Bonzini                                MemTxAttrs attrs,
104d4b3d152SPaolo Bonzini                                void *buf, int len)
105e804f892SPaolo Bonzini {
106e804f892SPaolo Bonzini     MemTxResult result;
107e804f892SPaolo Bonzini     // TODO: investigate impact of treating reads as producing
108e804f892SPaolo Bonzini     // tainted data, with __coverity_tainted_data_argument__(buf).
109e804f892SPaolo Bonzini     __bufwrite(buf, len);
110e804f892SPaolo Bonzini     return result;
111e804f892SPaolo Bonzini }
112e804f892SPaolo Bonzini 
113e804f892SPaolo Bonzini MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
114e804f892SPaolo Bonzini                                 MemTxAttrs attrs,
115d4b3d152SPaolo Bonzini                                 const void *buf, int len)
116e804f892SPaolo Bonzini {
117e804f892SPaolo Bonzini     MemTxResult result;
118e804f892SPaolo Bonzini     __bufread(buf, len);
119e804f892SPaolo Bonzini     return result;
120e804f892SPaolo Bonzini }
121e804f892SPaolo 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 }
132e804f892SPaolo Bonzini 
133e804f892SPaolo Bonzini /* Tainting */
134e804f892SPaolo Bonzini 
135e804f892SPaolo Bonzini typedef struct {} name2keysym_t;
136e804f892SPaolo Bonzini static int get_keysym(const name2keysym_t *table,
137e804f892SPaolo Bonzini                       const char *name)
138e804f892SPaolo Bonzini {
139e804f892SPaolo Bonzini     int result;
140e804f892SPaolo Bonzini     if (result > 0) {
141e804f892SPaolo Bonzini         __coverity_tainted_string_sanitize_content__(name);
142e804f892SPaolo Bonzini         return result;
143e804f892SPaolo Bonzini     } else {
144e804f892SPaolo Bonzini         return 0;
145e804f892SPaolo Bonzini     }
146e804f892SPaolo Bonzini }
147e804f892SPaolo Bonzini 
148e804f892SPaolo Bonzini /* Replay data is considered trusted.  */
149e804f892SPaolo Bonzini uint8_t replay_get_byte(void)
150e804f892SPaolo Bonzini {
151e804f892SPaolo Bonzini     uint8_t byte;
152e804f892SPaolo Bonzini     return byte;
153e804f892SPaolo Bonzini }
154e804f892SPaolo Bonzini 
155e804f892SPaolo Bonzini 
156e804f892SPaolo Bonzini /*
157e804f892SPaolo Bonzini  * GLib memory allocation functions.
158e804f892SPaolo Bonzini  *
159e804f892SPaolo Bonzini  * Note that we ignore the fact that g_malloc of 0 bytes returns NULL,
160e804f892SPaolo Bonzini  * and g_realloc of 0 bytes frees the pointer.
161e804f892SPaolo Bonzini  *
162e804f892SPaolo Bonzini  * Modeling this would result in Coverity flagging a lot of memory
163e804f892SPaolo Bonzini  * allocations as potentially returning NULL, and asking us to check
164e804f892SPaolo Bonzini  * whether the result of the allocation is NULL or not.  However, the
165e804f892SPaolo Bonzini  * resulting pointer should never be dereferenced anyway, and in fact
166e804f892SPaolo Bonzini  * it is not in the vast majority of cases.
167e804f892SPaolo Bonzini  *
168e804f892SPaolo Bonzini  * If a dereference did happen, this would suppress a defect report
169e804f892SPaolo Bonzini  * for an actual null pointer dereference.  But it's too unlikely to
170e804f892SPaolo Bonzini  * be worth wading through the false positives, and with some luck
171e804f892SPaolo Bonzini  * we'll get a buffer overflow reported anyway.
172e804f892SPaolo Bonzini  */
173e804f892SPaolo Bonzini 
174e804f892SPaolo Bonzini /*
175e804f892SPaolo Bonzini  * Allocation primitives, cannot return NULL
176e804f892SPaolo Bonzini  * See also Coverity's library/generic/libc/all/all.c
177e804f892SPaolo Bonzini  */
178e804f892SPaolo Bonzini 
179e804f892SPaolo Bonzini void *g_malloc_n(size_t nmemb, size_t size)
180e804f892SPaolo Bonzini {
181e804f892SPaolo Bonzini     void *ptr;
182e804f892SPaolo Bonzini 
183e804f892SPaolo Bonzini     __coverity_negative_sink__(nmemb);
184e804f892SPaolo Bonzini     __coverity_negative_sink__(size);
185*05ad6857SPaolo Bonzini     ptr = __coverity_alloc__(nmemb * size);
186e804f892SPaolo Bonzini     __coverity_mark_as_uninitialized_buffer__(ptr);
187243a545bSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
188e804f892SPaolo Bonzini     return ptr;
189e804f892SPaolo Bonzini }
190e804f892SPaolo Bonzini 
191e804f892SPaolo Bonzini void *g_malloc0_n(size_t nmemb, size_t size)
192e804f892SPaolo Bonzini {
193e804f892SPaolo Bonzini     void *ptr;
194e804f892SPaolo Bonzini 
195e804f892SPaolo Bonzini     __coverity_negative_sink__(nmemb);
196e804f892SPaolo Bonzini     __coverity_negative_sink__(size);
197*05ad6857SPaolo Bonzini     ptr = __coverity_alloc__(nmemb * size);
198e804f892SPaolo Bonzini     __coverity_writeall0__(ptr);
199243a545bSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
200e804f892SPaolo Bonzini     return ptr;
201e804f892SPaolo Bonzini }
202e804f892SPaolo Bonzini 
203e804f892SPaolo Bonzini void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
204e804f892SPaolo Bonzini {
205e804f892SPaolo Bonzini     __coverity_negative_sink__(nmemb);
206e804f892SPaolo Bonzini     __coverity_negative_sink__(size);
207e804f892SPaolo Bonzini     __coverity_escape__(ptr);
208*05ad6857SPaolo Bonzini     ptr = __coverity_alloc__(nmemb * size);
209e804f892SPaolo Bonzini     /*
210e804f892SPaolo Bonzini      * Memory beyond the old size isn't actually initialized.  Can't
211e804f892SPaolo Bonzini      * model that.  See Coverity's realloc() model
212e804f892SPaolo Bonzini      */
213e804f892SPaolo Bonzini     __coverity_writeall__(ptr);
214243a545bSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
215e804f892SPaolo Bonzini     return ptr;
216e804f892SPaolo Bonzini }
217e804f892SPaolo Bonzini 
218e804f892SPaolo Bonzini void g_free(void *ptr)
219e804f892SPaolo Bonzini {
220e804f892SPaolo Bonzini     __coverity_free__(ptr);
221243a545bSPaolo Bonzini     __coverity_mark_as_afm_freed__(ptr, AFM_free);
222e804f892SPaolo Bonzini }
223e804f892SPaolo Bonzini 
224e804f892SPaolo Bonzini /*
225e804f892SPaolo Bonzini  * Derive the g_try_FOO_n() from the g_FOO_n() by adding indeterminate
226e804f892SPaolo Bonzini  * out of memory conditions
227e804f892SPaolo Bonzini  */
228e804f892SPaolo Bonzini 
229e804f892SPaolo Bonzini void *g_try_malloc_n(size_t nmemb, size_t size)
230e804f892SPaolo Bonzini {
231e804f892SPaolo Bonzini     int nomem;
232e804f892SPaolo Bonzini 
233e804f892SPaolo Bonzini     if (nomem) {
234e804f892SPaolo Bonzini         return NULL;
235e804f892SPaolo Bonzini     }
236e804f892SPaolo Bonzini     return g_malloc_n(nmemb, size);
237e804f892SPaolo Bonzini }
238e804f892SPaolo Bonzini 
239e804f892SPaolo Bonzini void *g_try_malloc0_n(size_t nmemb, size_t size)
240e804f892SPaolo Bonzini {
241e804f892SPaolo Bonzini     int nomem;
242e804f892SPaolo Bonzini 
243e804f892SPaolo Bonzini     if (nomem) {
244e804f892SPaolo Bonzini         return NULL;
245e804f892SPaolo Bonzini     }
246e804f892SPaolo Bonzini     return g_malloc0_n(nmemb, size);
247e804f892SPaolo Bonzini }
248e804f892SPaolo Bonzini 
249e804f892SPaolo Bonzini void *g_try_realloc_n(void *ptr, size_t nmemb, size_t size)
250e804f892SPaolo Bonzini {
251e804f892SPaolo Bonzini     int nomem;
252e804f892SPaolo Bonzini 
253e804f892SPaolo Bonzini     if (nomem) {
254e804f892SPaolo Bonzini         return NULL;
255e804f892SPaolo Bonzini     }
256e804f892SPaolo Bonzini     return g_realloc_n(ptr, nmemb, size);
257e804f892SPaolo Bonzini }
258e804f892SPaolo Bonzini 
25996915d63SPaolo Bonzini /* Derive the g_FOO() from the g_FOO_n() */
260e804f892SPaolo Bonzini 
261e804f892SPaolo Bonzini void *g_malloc(size_t size)
262e804f892SPaolo Bonzini {
263e804f892SPaolo Bonzini     return g_malloc_n(1, size);
264e804f892SPaolo Bonzini }
265e804f892SPaolo Bonzini 
266e804f892SPaolo Bonzini void *g_malloc0(size_t size)
267e804f892SPaolo Bonzini {
268e804f892SPaolo Bonzini     return g_malloc0_n(1, size);
269e804f892SPaolo Bonzini }
270e804f892SPaolo Bonzini 
271e804f892SPaolo Bonzini void *g_realloc(void *ptr, size_t size)
272e804f892SPaolo Bonzini {
273e804f892SPaolo Bonzini     return g_realloc_n(ptr, 1, size);
274e804f892SPaolo Bonzini }
275e804f892SPaolo Bonzini 
276e804f892SPaolo Bonzini void *g_try_malloc(size_t size)
277e804f892SPaolo Bonzini {
278e804f892SPaolo Bonzini     return g_try_malloc_n(1, size);
279e804f892SPaolo Bonzini }
280e804f892SPaolo Bonzini 
281e804f892SPaolo Bonzini void *g_try_malloc0(size_t size)
282e804f892SPaolo Bonzini {
283e804f892SPaolo Bonzini     return g_try_malloc0_n(1, size);
284e804f892SPaolo Bonzini }
285e804f892SPaolo Bonzini 
286e804f892SPaolo Bonzini void *g_try_realloc(void *ptr, size_t size)
287e804f892SPaolo Bonzini {
288e804f892SPaolo Bonzini     return g_try_realloc_n(ptr, 1, size);
289e804f892SPaolo Bonzini }
290e804f892SPaolo Bonzini 
291e804f892SPaolo Bonzini /* Other glib functions */
292e804f892SPaolo Bonzini 
293e804f892SPaolo Bonzini typedef struct pollfd GPollFD;
294e804f892SPaolo Bonzini 
295e804f892SPaolo Bonzini int poll();
296e804f892SPaolo Bonzini 
297e804f892SPaolo Bonzini int g_poll (GPollFD *fds, unsigned nfds, int timeout)
298e804f892SPaolo Bonzini {
299e804f892SPaolo Bonzini     return poll(fds, nfds, timeout);
300e804f892SPaolo Bonzini }
301e804f892SPaolo Bonzini 
302e804f892SPaolo Bonzini typedef struct _GIOChannel GIOChannel;
303e804f892SPaolo Bonzini GIOChannel *g_io_channel_unix_new(int fd)
304e804f892SPaolo Bonzini {
305e804f892SPaolo Bonzini     GIOChannel *c = g_malloc0(sizeof(GIOChannel));
306e804f892SPaolo Bonzini     __coverity_escape__(fd);
307e804f892SPaolo Bonzini     return c;
308e804f892SPaolo Bonzini }
309e804f892SPaolo Bonzini 
310e804f892SPaolo Bonzini void g_assertion_message_expr(const char     *domain,
311e804f892SPaolo Bonzini                               const char     *file,
312e804f892SPaolo Bonzini                               int             line,
313e804f892SPaolo Bonzini                               const char     *func,
314e804f892SPaolo Bonzini                               const char     *expr)
315e804f892SPaolo Bonzini {
316e804f892SPaolo Bonzini     __coverity_panic__();
317e804f892SPaolo Bonzini }
318