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