From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39013) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YGPOW-00068l-NK for qemu-devel@nongnu.org; Wed, 28 Jan 2015 04:58:52 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YGPOO-0000Pe-MC for qemu-devel@nongnu.org; Wed, 28 Jan 2015 04:58:44 -0500 Received: from mx1.redhat.com ([209.132.183.28]:36045) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YGPOO-0000PM-FM for qemu-devel@nongnu.org; Wed, 28 Jan 2015 04:58:36 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t0S9wZft002099 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Wed, 28 Jan 2015 04:58:35 -0500 From: Markus Armbruster Date: Wed, 28 Jan 2015 10:58:31 +0100 Message-Id: <1422439112-12336-3-git-send-email-armbru@redhat.com> In-Reply-To: <1422439112-12336-1-git-send-email-armbru@redhat.com> References: <1422439112-12336-1-git-send-email-armbru@redhat.com> Subject: [Qemu-devel] [PATCH 2/3] coverity: Model GLib string allocation partially List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com 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 --- scripts/coverity-model.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/scripts/coverity-model.c b/scripts/coverity-model.c index 8d0839e..230bc30 100644 --- a/scripts/coverity-model.c +++ b/scripts/coverity-model.c @@ -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; -- 1.9.3