[libvirt] [PATCH] virBufferVSprintf: do not skip va_end

This fixes the last of the varargs problems reported by coverity: va_end(argptr) was never called, and va_end(locarg) would have been skipped upon OOM.
From 7a75b9da0d08a54e9f256dd26cca061b59c32c6d Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering@redhat.com> Date: Thu, 18 Feb 2010 21:25:01 +0100 Subject: [PATCH] virBufferVSprintf: do not skip va_end
* src/util/buf.c (virBufferVSprintf): Do not omit or skip va_end calls. --- src/util/buf.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/util/buf.c b/src/util/buf.c index cc0a087..caf8ee0 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -246,14 +246,17 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...) grow_size = (count > 1000) ? count : 1000; if (virBufferGrow(buf, grow_size) < 0) - return; + goto cleanup; size = buf->size - buf->use - 1; va_copy(locarg, argptr); } - va_end(locarg); buf->use += count; buf->content[buf->use] = '\0'; + + cleanup: + va_end(argptr); + va_end(locarg); } /** -- 1.7.0.233.g05e1a

On Thu, Feb 18, 2010 at 09:27:25PM +0100, Jim Meyering wrote:
This fixes the last of the varargs problems reported by coverity:
va_end(argptr) was never called, and va_end(locarg) would have been skipped upon OOM.
From 7a75b9da0d08a54e9f256dd26cca061b59c32c6d Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering@redhat.com> Date: Thu, 18 Feb 2010 21:25:01 +0100 Subject: [PATCH] virBufferVSprintf: do not skip va_end
* src/util/buf.c (virBufferVSprintf): Do not omit or skip va_end calls. --- src/util/buf.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/util/buf.c b/src/util/buf.c index cc0a087..caf8ee0 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -246,14 +246,17 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
grow_size = (count > 1000) ? count : 1000; if (virBufferGrow(buf, grow_size) < 0) - return; + goto cleanup;
size = buf->size - buf->use - 1; va_copy(locarg, argptr); } - va_end(locarg); buf->use += count; buf->content[buf->use] = '\0'; + + cleanup: + va_end(argptr); + va_end(locarg); }
/**
Hum, that one I'm not sure. In the case of virBufferGrow failure, we just did va_end(locarg); in the loop before, so going to cleanup there does it twice, and I'm not sure it's legal. Probably simpler to add just va_end(argptr); before return in that case and drop the cleanup: target. Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@veillard.com | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/

Daniel Veillard wrote:
Subject: [PATCH] virBufferVSprintf: do not skip va_end
* src/util/buf.c (virBufferVSprintf): Do not omit or skip va_end calls. ... Hum, that one I'm not sure. In the case of virBufferGrow failure, we just did va_end(locarg); in the loop before, so going to cleanup there does it twice, and I'm not sure it's legal. Probably simpler to add just va_end(argptr); before return in that case and drop the cleanup: target.
Good catch. Corrected, as you suggest:
From 313af81e8ff93ceb06b6086ea917db6a7eb160cc Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering@redhat.com> Date: Thu, 18 Feb 2010 21:25:01 +0100 Subject: [PATCH] virBufferVSprintf: do not omit va_end call
* src/util/buf.c (virBufferVSprintf): Do not omit va_end call. Improved-by: Daniel Veillard. --- .gnulib | 2 +- src/util/buf.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.gnulib b/.gnulib index 11fbc57..a1d565a 160000 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 11fbc57405a118e6ec9a3ebc19bbf5ececdae4d6 +Subproject commit a1d565aa5b47ec56243e74d4ac8b4988a751fef2 diff --git a/src/util/buf.c b/src/util/buf.c index cc0a087..ef72294 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -245,8 +245,10 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...) va_end(locarg); grow_size = (count > 1000) ? count : 1000; - if (virBufferGrow(buf, grow_size) < 0) + if (virBufferGrow(buf, grow_size) < 0) { + va_end(argptr); return; + } size = buf->size - buf->use - 1; va_copy(locarg, argptr); -- 1.7.0.233.g05e1a

Jim Meyering wrote:
Daniel Veillard wrote:
Subject: [PATCH] virBufferVSprintf: do not skip va_end
* src/util/buf.c (virBufferVSprintf): Do not omit or skip va_end calls. ... Hum, that one I'm not sure. In the case of virBufferGrow failure, we just did va_end(locarg); in the loop before, so going to cleanup there does it twice, and I'm not sure it's legal. Probably simpler to add just va_end(argptr); before return in that case and drop the cleanup: target.
Good catch. Corrected, as you suggest:
From 313af81e8ff93ceb06b6086ea917db6a7eb160cc Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering@redhat.com> Date: Thu, 18 Feb 2010 21:25:01 +0100 Subject: [PATCH] virBufferVSprintf: do not omit va_end call
* src/util/buf.c (virBufferVSprintf): Do not omit va_end call. Improved-by: Daniel Veillard. --- .gnulib | 2 +- src/util/buf.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/.gnulib b/.gnulib index 11fbc57..a1d565a 160000 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 11fbc57405a118e6ec9a3ebc19bbf5ececdae4d6 +Subproject commit a1d565aa5b47ec56243e74d4ac8b4988a751fef2 diff --git a/src/util/buf.c b/src/util/buf.c index cc0a087..ef72294 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -245,8 +245,10 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...) va_end(locarg);
grow_size = (count > 1000) ? count : 1000; - if (virBufferGrow(buf, grow_size) < 0) + if (virBufferGrow(buf, grow_size) < 0) { + va_end(argptr); return; + }
size = buf->size - buf->use - 1; va_copy(locarg, argptr);
I looked at this again and realized that the above is insufficient. We do have to call va_end(argptr) at the end, as well, so I'm merging this additional change locally. Otherwise, we'd leak in the common case. diff --git a/.gnulib b/.gnulib index 11fbc57..a1d565a 160000 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 11fbc57405a118e6ec9a3ebc19bbf5ececdae4d6 +Subproject commit a1d565aa5b47ec56243e74d4ac8b4988a751fef2 diff --git a/src/util/buf.c b/src/util/buf.c index ef72294..fc1217b 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -252,8 +252,9 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...) size = buf->size - buf->use - 1; va_copy(locarg, argptr); } + va_end(argptr); va_end(locarg); buf->use += count; buf->content[buf->use] = '\0'; } Amended patch:
From 2a5ca2656325546231a546cf580f08bb0462d37a Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering@redhat.com> Date: Thu, 18 Feb 2010 21:25:01 +0100 Subject: [PATCH] virBufferVSprintf: do not omit va_end(argptr) call
* src/util/buf.c (virBufferVSprintf): Do not omit va_end(argptr). Improved-by: Daniel Veillard. --- .gnulib | 2 +- src/util/buf.c | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.gnulib b/.gnulib index 11fbc57..a1d565a 160000 --- a/.gnulib +++ b/.gnulib @@ -1 +1 @@ -Subproject commit 11fbc57405a118e6ec9a3ebc19bbf5ececdae4d6 +Subproject commit a1d565aa5b47ec56243e74d4ac8b4988a751fef2 diff --git a/src/util/buf.c b/src/util/buf.c index cc0a087..fc1217b 100644 --- a/src/util/buf.c +++ b/src/util/buf.c @@ -245,12 +245,15 @@ virBufferVSprintf(const virBufferPtr buf, const char *format, ...) va_end(locarg); grow_size = (count > 1000) ? count : 1000; - if (virBufferGrow(buf, grow_size) < 0) + if (virBufferGrow(buf, grow_size) < 0) { + va_end(argptr); return; + } size = buf->size - buf->use - 1; va_copy(locarg, argptr); } + va_end(argptr); va_end(locarg); buf->use += count; buf->content[buf->use] = '\0'; -- 1.7.0.233.g05e1a

According to Jim Meyering on 2/19/2010 3:45 AM:
Hum, that one I'm not sure. In the case of virBufferGrow failure, we just did va_end(locarg); in the loop before, so going to cleanup there does it twice, and I'm not sure it's legal. Probably simpler to add just va_end(argptr); before return in that case and drop the cleanup: target.
Good catch. Corrected, as you suggest:
+++ b/.gnulib @@ -1 +1 @@ -Subproject commit 11fbc57405a118e6ec9a3ebc19bbf5ececdae4d6 +Subproject commit a1d565aa5b47ec56243e74d4ac8b4988a751fef2
Why the change in .gnulib? Shouldn't that be an independent patch? -- Don't work too hard, make some time for fun as well! Eric Blake ebb9@byu.net

Eric Blake wrote:
According to Jim Meyering on 2/19/2010 3:45 AM:
Hum, that one I'm not sure. In the case of virBufferGrow failure, we just did va_end(locarg); in the loop before, so going to cleanup there does it twice, and I'm not sure it's legal. Probably simpler to add just va_end(argptr); before return in that case and drop the cleanup: target.
Good catch. Corrected, as you suggest:
+++ b/.gnulib @@ -1 +1 @@ -Subproject commit 11fbc57405a118e6ec9a3ebc19bbf5ececdae4d6 +Subproject commit a1d565aa5b47ec56243e74d4ac8b4988a751fef2
Why the change in .gnulib? Shouldn't that be an independent patch?
Well spotted. I saw it too, and (as you probably noticed) removed it from the updated patch.

According to Jim Meyering on 2/19/2010 6:50 AM:
Why the change in .gnulib? Shouldn't that be an independent patch?
Well spotted. I saw it too, and (as you probably noticed) removed it from the updated patch.
I still see it in your most recent post: https://www.redhat.com/archives/libvir-list/2010-February/msg00698.html -- Don't work too hard, make some time for fun as well! Eric Blake ebb9@byu.net

Eric Blake wrote:
According to Jim Meyering on 2/19/2010 6:50 AM:
Why the change in .gnulib? Shouldn't that be an independent patch?
Well spotted. I saw it too, and (as you probably noticed) removed it from the updated patch.
I still see it in your most recent post: https://www.redhat.com/archives/libvir-list/2010-February/msg00698.html
Humph ;-) Well I did remove it, but then pulled it back in with an --amend. Thanks!

Eric Blake wrote:
According to Jim Meyering on 2/19/2010 3:45 AM:
Hum, that one I'm not sure. In the case of virBufferGrow failure, we just did va_end(locarg); in the loop before, so going to cleanup there does it twice, and I'm not sure it's legal. Probably simpler to add just va_end(argptr); before return in that case and drop the cleanup: target.
Good catch. Corrected, as you suggest:
+++ b/.gnulib @@ -1 +1 @@ -Subproject commit 11fbc57405a118e6ec9a3ebc19bbf5ececdae4d6 +Subproject commit a1d565aa5b47ec56243e74d4ac8b4988a751fef2
Shouldn't that be an independent patch?
Yes. BTW, if I were to update to the latest from gnulib, it would break "syntax-check", due to a weakness in maint.mk's new hash.h check. It gets a false-positive on any inclusion of libvirt's own "hash.h": $ git ls-files|grep hash.h src/util/hash.h I haven't yet decided what to do about that.
participants (3)
-
Daniel Veillard
-
Eric Blake
-
Jim Meyering