xref: /openbmc/qemu/scripts/coverity-scan/model.c (revision 96915d63)
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     size_t sz;
182e804f892SPaolo Bonzini     void *ptr;
183e804f892SPaolo Bonzini 
184e804f892SPaolo Bonzini     __coverity_negative_sink__(nmemb);
185e804f892SPaolo Bonzini     __coverity_negative_sink__(size);
186e804f892SPaolo Bonzini     sz = nmemb * size;
187e804f892SPaolo Bonzini     ptr = __coverity_alloc__(sz);
188e804f892SPaolo Bonzini     __coverity_mark_as_uninitialized_buffer__(ptr);
189243a545bSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
190e804f892SPaolo Bonzini     return ptr;
191e804f892SPaolo Bonzini }
192e804f892SPaolo Bonzini 
193e804f892SPaolo Bonzini void *g_malloc0_n(size_t nmemb, size_t size)
194e804f892SPaolo Bonzini {
195e804f892SPaolo Bonzini     size_t sz;
196e804f892SPaolo Bonzini     void *ptr;
197e804f892SPaolo Bonzini 
198e804f892SPaolo Bonzini     __coverity_negative_sink__(nmemb);
199e804f892SPaolo Bonzini     __coverity_negative_sink__(size);
200e804f892SPaolo Bonzini     sz = nmemb * size;
201e804f892SPaolo Bonzini     ptr = __coverity_alloc__(sz);
202e804f892SPaolo Bonzini     __coverity_writeall0__(ptr);
203243a545bSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
204e804f892SPaolo Bonzini     return ptr;
205e804f892SPaolo Bonzini }
206e804f892SPaolo Bonzini 
207e804f892SPaolo Bonzini void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
208e804f892SPaolo Bonzini {
209e804f892SPaolo Bonzini     size_t sz;
210e804f892SPaolo Bonzini 
211e804f892SPaolo Bonzini     __coverity_negative_sink__(nmemb);
212e804f892SPaolo Bonzini     __coverity_negative_sink__(size);
213e804f892SPaolo Bonzini     sz = nmemb * size;
214e804f892SPaolo Bonzini     __coverity_escape__(ptr);
215e804f892SPaolo Bonzini     ptr = __coverity_alloc__(sz);
216e804f892SPaolo Bonzini     /*
217e804f892SPaolo Bonzini      * Memory beyond the old size isn't actually initialized.  Can't
218e804f892SPaolo Bonzini      * model that.  See Coverity's realloc() model
219e804f892SPaolo Bonzini      */
220e804f892SPaolo Bonzini     __coverity_writeall__(ptr);
221243a545bSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
222e804f892SPaolo Bonzini     return ptr;
223e804f892SPaolo Bonzini }
224e804f892SPaolo Bonzini 
225e804f892SPaolo Bonzini void g_free(void *ptr)
226e804f892SPaolo Bonzini {
227e804f892SPaolo Bonzini     __coverity_free__(ptr);
228243a545bSPaolo Bonzini     __coverity_mark_as_afm_freed__(ptr, AFM_free);
229e804f892SPaolo Bonzini }
230e804f892SPaolo Bonzini 
231e804f892SPaolo Bonzini /*
232e804f892SPaolo Bonzini  * Derive the g_try_FOO_n() from the g_FOO_n() by adding indeterminate
233e804f892SPaolo Bonzini  * out of memory conditions
234e804f892SPaolo Bonzini  */
235e804f892SPaolo Bonzini 
236e804f892SPaolo Bonzini void *g_try_malloc_n(size_t nmemb, size_t size)
237e804f892SPaolo Bonzini {
238e804f892SPaolo Bonzini     int nomem;
239e804f892SPaolo Bonzini 
240e804f892SPaolo Bonzini     if (nomem) {
241e804f892SPaolo Bonzini         return NULL;
242e804f892SPaolo Bonzini     }
243e804f892SPaolo Bonzini     return g_malloc_n(nmemb, size);
244e804f892SPaolo Bonzini }
245e804f892SPaolo Bonzini 
246e804f892SPaolo Bonzini void *g_try_malloc0_n(size_t nmemb, size_t size)
247e804f892SPaolo Bonzini {
248e804f892SPaolo Bonzini     int nomem;
249e804f892SPaolo Bonzini 
250e804f892SPaolo Bonzini     if (nomem) {
251e804f892SPaolo Bonzini         return NULL;
252e804f892SPaolo Bonzini     }
253e804f892SPaolo Bonzini     return g_malloc0_n(nmemb, size);
254e804f892SPaolo Bonzini }
255e804f892SPaolo Bonzini 
256e804f892SPaolo Bonzini void *g_try_realloc_n(void *ptr, size_t nmemb, size_t size)
257e804f892SPaolo Bonzini {
258e804f892SPaolo Bonzini     int nomem;
259e804f892SPaolo Bonzini 
260e804f892SPaolo Bonzini     if (nomem) {
261e804f892SPaolo Bonzini         return NULL;
262e804f892SPaolo Bonzini     }
263e804f892SPaolo Bonzini     return g_realloc_n(ptr, nmemb, size);
264e804f892SPaolo Bonzini }
265e804f892SPaolo Bonzini 
266*96915d63SPaolo Bonzini /* Derive the g_FOO() from the g_FOO_n() */
267e804f892SPaolo Bonzini 
268e804f892SPaolo Bonzini void *g_malloc(size_t size)
269e804f892SPaolo Bonzini {
270e804f892SPaolo Bonzini     return g_malloc_n(1, size);
271e804f892SPaolo Bonzini }
272e804f892SPaolo Bonzini 
273e804f892SPaolo Bonzini void *g_malloc0(size_t size)
274e804f892SPaolo Bonzini {
275e804f892SPaolo Bonzini     return g_malloc0_n(1, size);
276e804f892SPaolo Bonzini }
277e804f892SPaolo Bonzini 
278e804f892SPaolo Bonzini void *g_realloc(void *ptr, size_t size)
279e804f892SPaolo Bonzini {
280e804f892SPaolo Bonzini     return g_realloc_n(ptr, 1, size);
281e804f892SPaolo Bonzini }
282e804f892SPaolo Bonzini 
283e804f892SPaolo Bonzini void *g_try_malloc(size_t size)
284e804f892SPaolo Bonzini {
285e804f892SPaolo Bonzini     return g_try_malloc_n(1, size);
286e804f892SPaolo Bonzini }
287e804f892SPaolo Bonzini 
288e804f892SPaolo Bonzini void *g_try_malloc0(size_t size)
289e804f892SPaolo Bonzini {
290e804f892SPaolo Bonzini     return g_try_malloc0_n(1, size);
291e804f892SPaolo Bonzini }
292e804f892SPaolo Bonzini 
293e804f892SPaolo Bonzini void *g_try_realloc(void *ptr, size_t size)
294e804f892SPaolo Bonzini {
295e804f892SPaolo Bonzini     return g_try_realloc_n(ptr, 1, size);
296e804f892SPaolo Bonzini }
297e804f892SPaolo Bonzini 
298e804f892SPaolo Bonzini /* Other glib functions */
299e804f892SPaolo Bonzini 
300e804f892SPaolo Bonzini typedef struct pollfd GPollFD;
301e804f892SPaolo Bonzini 
302e804f892SPaolo Bonzini int poll();
303e804f892SPaolo Bonzini 
304e804f892SPaolo Bonzini int g_poll (GPollFD *fds, unsigned nfds, int timeout)
305e804f892SPaolo Bonzini {
306e804f892SPaolo Bonzini     return poll(fds, nfds, timeout);
307e804f892SPaolo Bonzini }
308e804f892SPaolo Bonzini 
309e804f892SPaolo Bonzini typedef struct _GIOChannel GIOChannel;
310e804f892SPaolo Bonzini GIOChannel *g_io_channel_unix_new(int fd)
311e804f892SPaolo Bonzini {
312e804f892SPaolo Bonzini     GIOChannel *c = g_malloc0(sizeof(GIOChannel));
313e804f892SPaolo Bonzini     __coverity_escape__(fd);
314e804f892SPaolo Bonzini     return c;
315e804f892SPaolo Bonzini }
316e804f892SPaolo Bonzini 
317e804f892SPaolo Bonzini void g_assertion_message_expr(const char     *domain,
318e804f892SPaolo Bonzini                               const char     *file,
319e804f892SPaolo Bonzini                               int             line,
320e804f892SPaolo Bonzini                               const char     *func,
321e804f892SPaolo Bonzini                               const char     *expr)
322e804f892SPaolo Bonzini {
323e804f892SPaolo Bonzini     __coverity_panic__();
324e804f892SPaolo Bonzini }
325