xref: /openbmc/qemu/scripts/coverity-scan/model.c (revision fae4fad5)
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);
1860da41187SPaolo Bonzini     if (!ptr) {
1870da41187SPaolo Bonzini         __coverity_panic__();
1880da41187SPaolo 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);
2010da41187SPaolo Bonzini     if (!ptr) {
2020da41187SPaolo Bonzini         __coverity_panic__();
2030da41187SPaolo 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);
2150da41187SPaolo Bonzini     if (!ptr) {
2160da41187SPaolo Bonzini         __coverity_panic__();
2170da41187SPaolo 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 {
272e17bdaabSPaolo Bonzini     void *ptr;
273e17bdaabSPaolo Bonzini 
274e17bdaabSPaolo Bonzini     __coverity_negative_sink__(size);
275e17bdaabSPaolo Bonzini     ptr = __coverity_alloc__(size);
276e17bdaabSPaolo Bonzini     if (!ptr) {
277e17bdaabSPaolo Bonzini         __coverity_panic__();
278e17bdaabSPaolo Bonzini     }
279e17bdaabSPaolo Bonzini     __coverity_mark_as_uninitialized_buffer__(ptr);
280e17bdaabSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
281e17bdaabSPaolo Bonzini     return ptr;
282e804f892SPaolo Bonzini }
283e804f892SPaolo Bonzini 
284e804f892SPaolo Bonzini void *g_malloc0(size_t size)
285e804f892SPaolo Bonzini {
286e17bdaabSPaolo Bonzini     void *ptr;
287e17bdaabSPaolo Bonzini 
288e17bdaabSPaolo Bonzini     __coverity_negative_sink__(size);
289e17bdaabSPaolo Bonzini     ptr = __coverity_alloc__(size);
290e17bdaabSPaolo Bonzini     if (!ptr) {
291e17bdaabSPaolo Bonzini         __coverity_panic__();
292e17bdaabSPaolo Bonzini     }
293e17bdaabSPaolo Bonzini     __coverity_writeall0__(ptr);
294e17bdaabSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
295e17bdaabSPaolo Bonzini     return ptr;
296e804f892SPaolo Bonzini }
297e804f892SPaolo Bonzini 
298e804f892SPaolo Bonzini void *g_realloc(void *ptr, size_t size)
299e804f892SPaolo Bonzini {
300e17bdaabSPaolo Bonzini     __coverity_negative_sink__(size);
301e17bdaabSPaolo Bonzini     __coverity_escape__(ptr);
302e17bdaabSPaolo Bonzini     ptr = __coverity_alloc__(size);
303e17bdaabSPaolo Bonzini     if (!ptr) {
304e17bdaabSPaolo Bonzini         __coverity_panic__();
305e17bdaabSPaolo Bonzini     }
306e17bdaabSPaolo Bonzini     /*
307e17bdaabSPaolo Bonzini      * Memory beyond the old size isn't actually initialized.  Can't
308e17bdaabSPaolo Bonzini      * model that.  See Coverity's realloc() model
309e17bdaabSPaolo Bonzini      */
310e17bdaabSPaolo Bonzini     __coverity_writeall__(ptr);
311e17bdaabSPaolo Bonzini     __coverity_mark_as_afm_allocated__(ptr, AFM_free);
312e17bdaabSPaolo Bonzini     return ptr;
313e804f892SPaolo Bonzini }
314e804f892SPaolo Bonzini 
315e804f892SPaolo Bonzini void *g_try_malloc(size_t size)
316e804f892SPaolo Bonzini {
317e17bdaabSPaolo Bonzini     int nomem;
318e17bdaabSPaolo Bonzini 
319e17bdaabSPaolo Bonzini     if (nomem) {
320e17bdaabSPaolo Bonzini         return NULL;
321e17bdaabSPaolo Bonzini     }
322e17bdaabSPaolo Bonzini     return g_malloc(size);
323e804f892SPaolo Bonzini }
324e804f892SPaolo Bonzini 
325e804f892SPaolo Bonzini void *g_try_malloc0(size_t size)
326e804f892SPaolo Bonzini {
327e17bdaabSPaolo Bonzini     int nomem;
328e17bdaabSPaolo Bonzini 
329e17bdaabSPaolo Bonzini     if (nomem) {
330e17bdaabSPaolo Bonzini         return NULL;
331e17bdaabSPaolo Bonzini     }
332e17bdaabSPaolo Bonzini     return g_malloc0(size);
333e804f892SPaolo Bonzini }
334e804f892SPaolo Bonzini 
335e804f892SPaolo Bonzini void *g_try_realloc(void *ptr, size_t size)
336e804f892SPaolo Bonzini {
337e17bdaabSPaolo Bonzini     int nomem;
338e17bdaabSPaolo Bonzini 
339e17bdaabSPaolo Bonzini     if (nomem) {
340e17bdaabSPaolo Bonzini         return NULL;
341e17bdaabSPaolo Bonzini     }
342e17bdaabSPaolo Bonzini     return g_realloc(ptr, size);
343e804f892SPaolo Bonzini }
344e804f892SPaolo Bonzini 
345e804f892SPaolo Bonzini /* Other glib functions */
346e804f892SPaolo Bonzini 
347e804f892SPaolo Bonzini typedef struct pollfd GPollFD;
348e804f892SPaolo Bonzini 
349e804f892SPaolo Bonzini int poll();
350e804f892SPaolo Bonzini 
351e804f892SPaolo Bonzini int g_poll (GPollFD *fds, unsigned nfds, int timeout)
352e804f892SPaolo Bonzini {
353e804f892SPaolo Bonzini     return poll(fds, nfds, timeout);
354e804f892SPaolo Bonzini }
355e804f892SPaolo Bonzini 
356e804f892SPaolo Bonzini typedef struct _GIOChannel GIOChannel;
357e804f892SPaolo Bonzini GIOChannel *g_io_channel_unix_new(int fd)
358e804f892SPaolo Bonzini {
359*fae4fad5SPaolo Bonzini     /* cannot use incomplete type, the actual struct is roughly this size.  */
360*fae4fad5SPaolo Bonzini     GIOChannel *c = g_malloc0(20 * sizeof(void *));
361e804f892SPaolo Bonzini     __coverity_escape__(fd);
362e804f892SPaolo Bonzini     return c;
363e804f892SPaolo Bonzini }
364e804f892SPaolo Bonzini 
365e804f892SPaolo Bonzini void g_assertion_message_expr(const char     *domain,
366e804f892SPaolo Bonzini                               const char     *file,
367e804f892SPaolo Bonzini                               int             line,
368e804f892SPaolo Bonzini                               const char     *func,
369e804f892SPaolo Bonzini                               const char     *expr)
370e804f892SPaolo Bonzini {
371e804f892SPaolo Bonzini     __coverity_panic__();
372e804f892SPaolo Bonzini }
373