[Libvir] [PATCH] Fix endless loop of VirBufferVSprintf()

Hi VirBufferVSprintf() loops endless when it receives over 2000 bytes, because the return value of vsnprintf() is more than "size - 1". It is because the maximum of "size" is 1999 bytes. --> the maximum of "buf->size - buf->use" = 2000 (1000(argument of virBufferGrow()) + 1000(set in virBufferGrow())) So, virBufferEscapeString() has the same problem. This patch sets to virBufferGrow() the size of the data which VirBufferVSprintf()(virBufferEscapeString()) received when it is over 1000 bytes. Signed-off-by: Masayuki Sunou <fj1826dm@aa.jp.fujitsu.com> Thanks, Masayuki Sunou. ---------------------------------------------------------------------- Index: src/buf.c =================================================================== RCS file: /data/cvs/libvirt/src/buf.c,v retrieving revision 1.3 diff -u -p -r1.3 buf.c --- src/buf.c 9 Jul 2007 11:24:52 -0000 1.3 +++ src/buf.c 24 Aug 2007 05:56:37 -0000 @@ -159,7 +159,7 @@ virBufferContentAndFree (virBufferPtr bu int virBufferVSprintf(virBufferPtr buf, const char *format, ...) { - int size, count; + int size, count, grow_size; va_list locarg, argptr; if ((format == NULL) || (buf == NULL)) { @@ -172,7 +172,8 @@ virBufferVSprintf(virBufferPtr buf, cons locarg)) < 0) || (count >= size - 1)) { buf->content[buf->use] = 0; va_end(locarg); - if (virBufferGrow(buf, 1000) < 0) { + grow_size = (count > 1000) ? count : 1000; + if (virBufferGrow(buf, grow_size) < 0) { return (-1); } size = buf->size - buf->use - 1; @@ -198,7 +199,7 @@ virBufferVSprintf(virBufferPtr buf, cons int virBufferEscapeString(virBufferPtr buf, const char *format, const char *str) { - int size, count, len; + int size, count, len, grow_size; char *escaped, *out; const char *cur; @@ -248,7 +249,8 @@ virBufferEscapeString(virBufferPtr buf, while (((count = snprintf(&buf->content[buf->use], size, format, (char *)escaped)) < 0) || (count >= size - 1)) { buf->content[buf->use] = 0; - if (virBufferGrow(buf, 1000) < 0) { + grow_size = (count > 1000) ? count : 1000; + if (virBufferGrow(buf, grow_size) < 0) { free(escaped); return (-1); } ----------------------------------------------------------------------

Hi Would you give me a comment on this? This occurs when virsh create is executed by using the attached file. Thanks, Masayuki Sunou In message <200708241730.AJI90166.3GE29KN7@aa.jp.fujitsu.com> "[Libvir] [PATCH] Fix endless loop of VirBufferVSprintf()" "Masayuki Sunou <fj1826dm@aa.jp.fujitsu.com>" wrote:
Hi
VirBufferVSprintf() loops endless when it receives over 2000 bytes, because the return value of vsnprintf() is more than "size - 1". It is because the maximum of "size" is 1999 bytes. --> the maximum of "buf->size - buf->use" = 2000 (1000(argument of virBufferGrow()) + 1000(set in virBufferGrow()))
So, virBufferEscapeString() has the same problem.
This patch sets to virBufferGrow() the size of the data which VirBufferVSprintf()(virBufferEscapeString()) received when it is over 1000 bytes.
Signed-off-by: Masayuki Sunou <fj1826dm@aa.jp.fujitsu.com>
Thanks, Masayuki Sunou.
---------------------------------------------------------------------- Index: src/buf.c =================================================================== RCS file: /data/cvs/libvirt/src/buf.c,v retrieving revision 1.3 diff -u -p -r1.3 buf.c --- src/buf.c 9 Jul 2007 11:24:52 -0000 1.3 +++ src/buf.c 24 Aug 2007 05:56:37 -0000 @@ -159,7 +159,7 @@ virBufferContentAndFree (virBufferPtr bu int virBufferVSprintf(virBufferPtr buf, const char *format, ...) { - int size, count; + int size, count, grow_size; va_list locarg, argptr;
if ((format == NULL) || (buf == NULL)) { @@ -172,7 +172,8 @@ virBufferVSprintf(virBufferPtr buf, cons locarg)) < 0) || (count >= size - 1)) { buf->content[buf->use] = 0; va_end(locarg); - if (virBufferGrow(buf, 1000) < 0) { + grow_size = (count > 1000) ? count : 1000; + if (virBufferGrow(buf, grow_size) < 0) { return (-1); } size = buf->size - buf->use - 1; @@ -198,7 +199,7 @@ virBufferVSprintf(virBufferPtr buf, cons int virBufferEscapeString(virBufferPtr buf, const char *format, const char *str) { - int size, count, len; + int size, count, len, grow_size; char *escaped, *out; const char *cur;
@@ -248,7 +249,8 @@ virBufferEscapeString(virBufferPtr buf, while (((count = snprintf(&buf->content[buf->use], size, format, (char *)escaped)) < 0) || (count >= size - 1)) { buf->content[buf->use] = 0; - if (virBufferGrow(buf, 1000) < 0) { + grow_size = (count > 1000) ? count : 1000; + if (virBufferGrow(buf, grow_size) < 0) { free(escaped); return (-1); } ----------------------------------------------------------------------
-- Libvir-list mailing list Libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On Thu, Aug 30, 2007 at 11:29:34AM +0900, Masayuki Sunou wrote:
Hi
Would you give me a comment on this? This occurs when virsh create is executed by using the attached file.
Yes, sorry when I first looked at the patch I though I needed to give it a deeper look because I misunderstood something, and I forgot about it ... Looking again, yes this is right, the code made an assumption which was that virBufGrow would automatically allocate at least the size given while it just ensure that there is at least that space available. You patch is right, applied and commited to CVS, thanks a lot ! Daniel -- Red Hat Virtualization group http://redhat.com/virtualization/ Daniel Veillard | virtualization library http://libvirt.org/ veillard@redhat.com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/ http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
participants (2)
-
Daniel Veillard
-
Masayuki Sunou