coverity: Model GLib string allocation partially
Without a model, Coverity can't know that the result of g_strdup() needs to be fed to g_free(). One way to get such a model is to scan GLib, build a derived model file with cov-collect-models, and use that when scanning QEMU. Unfortunately, the Coverity Scan service we use doesn't support that. Thus, we're stuck with the other way: write a user model. Doing that for all of GLib is hardly practical. I'm doing it for the "String Utility Functions" we actually use that return dynamically allocated strings. In a local scan, this flags 20 additional RESOURCE_LEAKs. The ones I checked look genuine. It also loses a NULL_RETURNS about ppce500_init() using qemu_find_file() without error checking. I don't understand why. Signed-off-by: Markus Armbruster <armbru@redhat.com> Acked-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9d7a4c6690
commit
e4b77daa57
@ -40,6 +40,8 @@ typedef unsigned long long uint64_t;
|
||||
typedef long long int64_t;
|
||||
typedef _Bool bool;
|
||||
|
||||
typedef struct va_list_str *va_list;
|
||||
|
||||
/* exec.c */
|
||||
|
||||
typedef struct AddressSpace AddressSpace;
|
||||
@ -232,6 +234,93 @@ void *g_try_realloc(void *ptr, size_t size)
|
||||
return g_try_realloc_n(ptr, 1, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* GLib string allocation functions
|
||||
*/
|
||||
|
||||
char *g_strdup(const char *s)
|
||||
{
|
||||
char *dup;
|
||||
size_t i;
|
||||
|
||||
if (!s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
__coverity_string_null_sink__(s);
|
||||
__coverity_string_size_sink__(s);
|
||||
dup = __coverity_alloc_nosize__();
|
||||
__coverity_mark_as_afm_allocated__(dup, AFM_free);
|
||||
for (i = 0; (dup[i] = s[i]); i++) ;
|
||||
return dup;
|
||||
}
|
||||
|
||||
char *g_strndup(const char *s, size_t n)
|
||||
{
|
||||
char *dup;
|
||||
size_t i;
|
||||
|
||||
__coverity_negative_sink__(n);
|
||||
|
||||
if (!s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dup = g_malloc(n + 1);
|
||||
for (i = 0; i < n && (dup[i] = s[i]); i++) ;
|
||||
dup[i] = 0;
|
||||
return dup;
|
||||
}
|
||||
|
||||
char *g_strdup_printf(const char *format, ...)
|
||||
{
|
||||
char ch, *s;
|
||||
size_t len;
|
||||
|
||||
__coverity_string_null_sink__(format);
|
||||
__coverity_string_size_sink__(format);
|
||||
|
||||
ch = *format;
|
||||
|
||||
s = __coverity_alloc_nosize__();
|
||||
__coverity_writeall__(s);
|
||||
__coverity_mark_as_afm_allocated__(s, AFM_free);
|
||||
return s;
|
||||
}
|
||||
|
||||
char *g_strdup_vprintf(const char *format, va_list ap)
|
||||
{
|
||||
char ch, *s;
|
||||
size_t len;
|
||||
|
||||
__coverity_string_null_sink__(format);
|
||||
__coverity_string_size_sink__(format);
|
||||
|
||||
ch = *format;
|
||||
ch = *(char *)ap;
|
||||
|
||||
s = __coverity_alloc_nosize__();
|
||||
__coverity_writeall__(s);
|
||||
__coverity_mark_as_afm_allocated__(s, AFM_free);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
char *g_strconcat(const char *s, ...)
|
||||
{
|
||||
char *s;
|
||||
|
||||
/*
|
||||
* Can't model: last argument must be null, the others
|
||||
* null-terminated strings
|
||||
*/
|
||||
|
||||
s = __coverity_alloc_nosize__();
|
||||
__coverity_writeall__(s);
|
||||
__coverity_mark_as_afm_allocated__(s, AFM_free);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Other glib functions */
|
||||
|
||||
typedef struct _GIOChannel GIOChannel;
|
||||
|
Loading…
Reference in New Issue
Block a user