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