diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2009-04-24 13:00:49 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2009-04-24 13:00:49 +0100 |
commit | 4507dd497f9a5eb8584e6d0937a87dc659cfa144 (patch) | |
tree | 6fe2046d694e0be7d5b1007ee062d3076f1cda2b | |
parent | 5b0fcfffc1872f335a2a6da9505f2e8926b1a740 (diff) | |
download | libguestfs-4507dd497f9a5eb8584e6d0937a87dc659cfa144.tar.gz libguestfs-4507dd497f9a5eb8584e6d0937a87dc659cfa144.tar.xz libguestfs-4507dd497f9a5eb8584e6d0937a87dc659cfa144.zip |
Don't use large message buffer on the stack (fixes Java/i386 segfault).
-rw-r--r-- | src/guestfs.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/src/guestfs.c b/src/guestfs.c index 77b16147..fdf5fede 100644 --- a/src/guestfs.c +++ b/src/guestfs.c @@ -1492,7 +1492,6 @@ int guestfs__send_sync (guestfs_h *g, int proc_nr, xdrproc_t xdrp, char *args) { - char buffer[GUESTFS_MESSAGE_MAX]; struct guestfs_message_header hdr; XDR xdr; unsigned len; @@ -1505,6 +1504,23 @@ guestfs__send_sync (guestfs_h *g, int proc_nr, return -1; } + /* This is probably an internal error. Or perhaps we should just + * free the buffer anyway? + */ + if (g->msg_out != NULL) { + error (g, "guestfs__send_sync: msg_out should be NULL"); + return -1; + } + + /* We have to allocate this message buffer on the heap because + * it is quite large (although will be mostly unused). We + * can't allocate it on the stack because in some environments + * we have quite limited stack space available, notably when + * running in the JVM. + */ + g->msg_out = safe_malloc (g, GUESTFS_MESSAGE_MAX + 4); + xdrmem_create (&xdr, g->msg_out + 4, GUESTFS_MESSAGE_MAX, XDR_ENCODE); + /* Serialize the header. */ hdr.prog = GUESTFS_PROGRAM; hdr.vers = GUESTFS_PROTOCOL_VERSION; @@ -1513,10 +1529,9 @@ guestfs__send_sync (guestfs_h *g, int proc_nr, hdr.serial = serial; hdr.status = GUESTFS_STATUS_OK; - xdrmem_create (&xdr, buffer, sizeof buffer, XDR_ENCODE); if (!xdr_guestfs_message_header (&xdr, &hdr)) { error (g, "xdr_guestfs_message_header failed"); - return -1; + goto cleanup1; } /* Serialize the args. If any, because some message types @@ -1525,24 +1540,23 @@ guestfs__send_sync (guestfs_h *g, int proc_nr, if (xdrp) { if (!(*xdrp) (&xdr, args)) { error (g, "dispatch failed to marshal args"); - return -1; + goto cleanup1; } } + /* Get the actual length of the message, resize the buffer to match + * the actual length, and write the length word at the beginning. + */ len = xdr_getpos (&xdr); xdr_destroy (&xdr); - /* Allocate the outgoing message buffer. */ - g->msg_out = safe_malloc (g, len + 4); - + g->msg_out = safe_realloc (g, g->msg_out, len + 4); g->msg_out_size = len + 4; g->msg_out_pos = 0; xdrmem_create (&xdr, g->msg_out, 4, XDR_ENCODE); xdr_uint32_t (&xdr, &len); - memcpy (g->msg_out + 4, buffer, len); - if (guestfs__switch_to_sending (g) == -1) goto cleanup1; |