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