]> Git Repo - qemu.git/blob - scripts/coverity-model.c
target/i386: [tcg] Port to breakpoint_check
[qemu.git] / scripts / coverity-model.c
1 /* Coverity Scan model
2  *
3  * Copyright (C) 2014 Red Hat, Inc.
4  *
5  * Authors:
6  *  Markus Armbruster <[email protected]>
7  *  Paolo Bonzini <[email protected]>
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_read(AddressSpace *as, hwaddr addr,
71                                MemTxAttrs attrs,
72                                uint8_t *buf, int len)
73 {
74     MemTxResult result;
75     // TODO: investigate impact of treating reads as producing
76     // tainted data, with __coverity_tainted_data_argument__(buf).
77     __bufwrite(buf, len);
78     return result;
79 }
80
81 MemTxResult address_space_write(AddressSpace *as, hwaddr addr,
82                                 MemTxAttrs attrs,
83                                 const uint8_t *buf, int len)
84 {
85     MemTxResult result;
86     __bufread(buf, len);
87     return result;
88 }
89
90
91 /* Tainting */
92
93 typedef struct {} name2keysym_t;
94 static int get_keysym(const name2keysym_t *table,
95                       const char *name)
96 {
97     int result;
98     if (result > 0) {
99         __coverity_tainted_string_sanitize_content__(name);
100         return result;
101     } else {
102         return 0;
103     }
104 }
105
106 /*
107  * GLib memory allocation functions.
108  *
109  * Note that we ignore the fact that g_malloc of 0 bytes returns NULL,
110  * and g_realloc of 0 bytes frees the pointer.
111  *
112  * Modeling this would result in Coverity flagging a lot of memory
113  * allocations as potentially returning NULL, and asking us to check
114  * whether the result of the allocation is NULL or not.  However, the
115  * resulting pointer should never be dereferenced anyway, and in fact
116  * it is not in the vast majority of cases.
117  *
118  * If a dereference did happen, this would suppress a defect report
119  * for an actual null pointer dereference.  But it's too unlikely to
120  * be worth wading through the false positives, and with some luck
121  * we'll get a buffer overflow reported anyway.
122  */
123
124 /*
125  * Allocation primitives, cannot return NULL
126  * See also Coverity's library/generic/libc/all/all.c
127  */
128
129 void *g_malloc_n(size_t nmemb, size_t size)
130 {
131     size_t sz;
132     void *ptr;
133
134     __coverity_negative_sink__(nmemb);
135     __coverity_negative_sink__(size);
136     sz = nmemb * size;
137     ptr = __coverity_alloc__(sz);
138     __coverity_mark_as_uninitialized_buffer__(ptr);
139     __coverity_mark_as_afm_allocated__(ptr, "g_free");
140     return ptr;
141 }
142
143 void *g_malloc0_n(size_t nmemb, size_t size)
144 {
145     size_t sz;
146     void *ptr;
147
148     __coverity_negative_sink__(nmemb);
149     __coverity_negative_sink__(size);
150     sz = nmemb * size;
151     ptr = __coverity_alloc__(sz);
152     __coverity_writeall0__(ptr);
153     __coverity_mark_as_afm_allocated__(ptr, "g_free");
154     return ptr;
155 }
156
157 void *g_realloc_n(void *ptr, size_t nmemb, size_t size)
158 {
159     size_t sz;
160
161     __coverity_negative_sink__(nmemb);
162     __coverity_negative_sink__(size);
163     sz = nmemb * size;
164     __coverity_escape__(ptr);
165     ptr = __coverity_alloc__(sz);
166     /*
167      * Memory beyond the old size isn't actually initialized.  Can't
168      * model that.  See Coverity's realloc() model
169      */
170     __coverity_writeall__(ptr);
171     __coverity_mark_as_afm_allocated__(ptr, "g_free");
172     return ptr;
173 }
174
175 void g_free(void *ptr)
176 {
177     __coverity_free__(ptr);
178     __coverity_mark_as_afm_freed__(ptr, "g_free");
179 }
180
181 /*
182  * Derive the g_try_FOO_n() from the g_FOO_n() by adding indeterminate
183  * out of memory conditions
184  */
185
186 void *g_try_malloc_n(size_t nmemb, size_t size)
187 {
188     int nomem;
189
190     if (nomem) {
191         return NULL;
192     }
193     return g_malloc_n(nmemb, size);
194 }
195
196 void *g_try_malloc0_n(size_t nmemb, size_t size)
197 {
198     int nomem;
199
200     if (nomem) {
201         return NULL;
202     }
203     return g_malloc0_n(nmemb, size);
204 }
205
206 void *g_try_realloc_n(void *ptr, size_t nmemb, size_t size)
207 {
208     int nomem;
209
210     if (nomem) {
211         return NULL;
212     }
213     return g_realloc_n(ptr, nmemb, size);
214 }
215
216 /* Trivially derive the g_FOO() from the g_FOO_n() */
217
218 void *g_malloc(size_t size)
219 {
220     return g_malloc_n(1, size);
221 }
222
223 void *g_malloc0(size_t size)
224 {
225     return g_malloc0_n(1, size);
226 }
227
228 void *g_realloc(void *ptr, size_t size)
229 {
230     return g_realloc_n(ptr, 1, size);
231 }
232
233 void *g_try_malloc(size_t size)
234 {
235     return g_try_malloc_n(1, size);
236 }
237
238 void *g_try_malloc0(size_t size)
239 {
240     return g_try_malloc0_n(1, size);
241 }
242
243 void *g_try_realloc(void *ptr, size_t size)
244 {
245     return g_try_realloc_n(ptr, 1, size);
246 }
247
248 /* Other memory allocation functions */
249
250 void *g_memdup(const void *ptr, unsigned size)
251 {
252     unsigned char *dup;
253     unsigned i;
254
255     if (!ptr) {
256         return NULL;
257     }
258
259     dup = g_malloc(size);
260     for (i = 0; i < size; i++)
261         dup[i] = ((unsigned char *)ptr)[i];
262     return dup;
263 }
264
265 /*
266  * GLib string allocation functions
267  */
268
269 char *g_strdup(const char *s)
270 {
271     char *dup;
272     size_t i;
273
274     if (!s) {
275         return NULL;
276     }
277
278     __coverity_string_null_sink__(s);
279     __coverity_string_size_sink__(s);
280     dup = __coverity_alloc_nosize__();
281     __coverity_mark_as_afm_allocated__(dup, "g_free");
282     for (i = 0; (dup[i] = s[i]); i++) ;
283     return dup;
284 }
285
286 char *g_strndup(const char *s, size_t n)
287 {
288     char *dup;
289     size_t i;
290
291     __coverity_negative_sink__(n);
292
293     if (!s) {
294         return NULL;
295     }
296
297     dup = g_malloc(n + 1);
298     for (i = 0; i < n && (dup[i] = s[i]); i++) ;
299     dup[i] = 0;
300     return dup;
301 }
302
303 char *g_strdup_printf(const char *format, ...)
304 {
305     char ch, *s;
306     size_t len;
307
308     __coverity_string_null_sink__(format);
309     __coverity_string_size_sink__(format);
310
311     ch = *format;
312
313     s = __coverity_alloc_nosize__();
314     __coverity_writeall__(s);
315     __coverity_mark_as_afm_allocated__(s, "g_free");
316     return s;
317 }
318
319 char *g_strdup_vprintf(const char *format, va_list ap)
320 {
321     char ch, *s;
322     size_t len;
323
324     __coverity_string_null_sink__(format);
325     __coverity_string_size_sink__(format);
326
327     ch = *format;
328     ch = *(char *)ap;
329
330     s = __coverity_alloc_nosize__();
331     __coverity_writeall__(s);
332     __coverity_mark_as_afm_allocated__(s, "g_free");
333
334     return len;
335 }
336
337 char *g_strconcat(const char *s, ...)
338 {
339     char *s;
340
341     /*
342      * Can't model: last argument must be null, the others
343      * null-terminated strings
344      */
345
346     s = __coverity_alloc_nosize__();
347     __coverity_writeall__(s);
348     __coverity_mark_as_afm_allocated__(s, "g_free");
349     return s;
350 }
351
352 /* Other glib functions */
353
354 typedef struct pollfd GPollFD;
355
356 int poll();
357
358 int g_poll (GPollFD *fds, unsigned nfds, int timeout)
359 {
360     return poll(fds, nfds, timeout);
361 }
362
363 typedef struct _GIOChannel GIOChannel;
364 GIOChannel *g_io_channel_unix_new(int fd)
365 {
366     GIOChannel *c = g_malloc0(sizeof(GIOChannel));
367     __coverity_escape__(fd);
368     return c;
369 }
370
371 void g_assertion_message_expr(const char     *domain,
372                               const char     *file,
373                               int             line,
374                               const char     *func,
375                               const char     *expr)
376 {
377     __coverity_panic__();
378 }
This page took 0.043421 seconds and 4 git commands to generate.