diff options
author | Richard Jones <rjones@redhat.com> | 2010-05-07 13:30:42 +0100 |
---|---|---|
committer | Richard Jones <rjones@redhat.com> | 2010-05-07 15:27:29 +0100 |
commit | 42f59b28f123f53ae038df23a9abee08e959e46b (patch) | |
tree | 4ac2c3ac492680659fffde3b4316703c74953bcd /daemon/initrd.c | |
parent | a84f1360499309e2d2ecb661adc6917539b5eef4 (diff) | |
download | libguestfs-42f59b28f123f53ae038df23a9abee08e959e46b.tar.gz libguestfs-42f59b28f123f53ae038df23a9abee08e959e46b.tar.xz libguestfs-42f59b28f123f53ae038df23a9abee08e959e46b.zip |
daemon: Fix read-file so it fails gracefully for large files (RHBZ#589039).
Pengzhen Cao noticed that read-file would fail for files
larger than the protocol size; this is *not* the bug. However
it would also lose protocol synchronization after this.
The reason was that functions which return RBufferOut in the
generator must not 'touch' the *size_r parameter along error
return paths.
I fixed read-file and initrd-cat, and I checked that pread was
doing the right thing.
This also adds regression tests for read-file with various categories
of large file.
Diffstat (limited to 'daemon/initrd.c')
-rw-r--r-- | daemon/initrd.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/daemon/initrd.c b/daemon/initrd.c index addeb144..932564b8 100644 --- a/daemon/initrd.c +++ b/daemon/initrd.c @@ -142,25 +142,24 @@ do_initrd_cat (const char *path, const char *filename, size_t *size_r) goto cleanup; } - *size_r = statbuf.st_size; /* The actual limit on messages is smaller than this. This * check just limits the amount of memory we'll try and allocate * here. If the message is larger than the real limit, that will * be caught later when we try to serialize the message. */ - if (*size_r >= GUESTFS_MESSAGE_MAX) { + if (statbuf.st_size >= GUESTFS_MESSAGE_MAX) { reply_with_error ("%s:%s: file is too large for the protocol", path, filename); goto cleanup; } - ret = malloc (*size_r); + ret = malloc (statbuf.st_size); if (ret == NULL) { reply_with_perror ("malloc"); goto cleanup; } - if (xread (fd, ret, *size_r) == -1) { + if (xread (fd, ret, statbuf.st_size) == -1) { reply_with_perror ("read: %s:%s", path, filename); free (ret); ret = NULL; @@ -175,6 +174,11 @@ do_initrd_cat (const char *path, const char *filename, size_t *size_r) } fd = -1; + /* Mustn't touch *size_r until we are sure that we won't return any + * error (RHBZ#589039). + */ + *size_r = statbuf.st_size; + cleanup: if (fd >= 0) close (fd); |