Skip to content

Commit

Permalink
daemon: Check parameter of base64-out and tar-out before running exte…
Browse files Browse the repository at this point in the history
…rnal command (RHBZ#908322).

For base64-out, check the filename parameter exists and is not a
directory.

For tar-out, check the dir parameter exists and is a directory.
(cherry picked from commit c78ec7e)
  • Loading branch information
rwmjones committed Feb 14, 2013
1 parent 477426a commit 1bd8138
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 9 deletions.
31 changes: 27 additions & 4 deletions daemon/base64.c
Expand Up @@ -22,6 +22,9 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "guestfs_protocol.h"
#include "daemon.h"
Expand Down Expand Up @@ -97,12 +100,32 @@ do_base64_in (const char *file)
int
do_base64_out (const char *file)
{
CLEANUP_FREE char *buf = NULL;
struct stat statbuf;
int r;
FILE *fp;
CLEANUP_FREE char *cmd = NULL;
char buf[GUESTFS_MAX_CHUNK_SIZE];
char buffer[GUESTFS_MAX_CHUNK_SIZE];

if (asprintf_nowarn (&cmd, "%s %R", str_base64, file) == -1) {
/* Check the filename exists and is not a directory (RHBZ#908322). */
buf = sysroot_path (file);
if (buf == NULL) {
reply_with_perror ("malloc");
return -1;
}

if (stat (buf, &statbuf) == -1) {
reply_with_perror ("stat: %s", file);
return -1;
}

if (S_ISDIR (statbuf.st_mode)) {
reply_with_error ("%s: is a directory", file);
return -1;
}

/* Construct the command. */
if (asprintf_nowarn (&cmd, "%s %s", str_base64, buf) == -1) {
reply_with_perror ("asprintf");
return -1;
}
Expand All @@ -122,8 +145,8 @@ do_base64_out (const char *file)
*/
reply (NULL, NULL);

while ((r = fread (buf, 1, sizeof buf, fp)) > 0) {
if (send_file_write (buf, r) < 0) {
while ((r = fread (buffer, 1, sizeof buffer, fp)) > 0) {
if (send_file_write (buffer, r) < 0) {
pclose (fp);
return -1;
}
Expand Down
32 changes: 27 additions & 5 deletions daemon/tar.c
Expand Up @@ -22,6 +22,9 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "read-file.h"

Expand Down Expand Up @@ -279,12 +282,14 @@ int
do_tar_out (const char *dir, const char *compress, int numericowner,
char *const *excludes)
{
CLEANUP_FREE char *buf = NULL;
struct stat statbuf;
const char *filter;
int r;
FILE *fp;
CLEANUP_FREE char *excludes_args = NULL;
CLEANUP_FREE char *cmd = NULL;
char buf[GUESTFS_MAX_CHUNK_SIZE];
char buffer[GUESTFS_MAX_CHUNK_SIZE];

if ((optargs_bitmask & GUESTFS_TAR_OUT_COMPRESS_BITMASK)) {
if (STREQ (compress, "compress"))
Expand Down Expand Up @@ -319,10 +324,27 @@ do_tar_out (const char *dir, const char *compress, int numericowner,
}
}

/* Check the filename exists and is a directory (RHBZ#908322). */
buf = sysroot_path (dir);
if (buf == NULL) {
reply_with_perror ("malloc");
return -1;
}

if (stat (buf, &statbuf) == -1) {
reply_with_perror ("stat: %s", dir);
return -1;
}

if (! S_ISDIR (statbuf.st_mode)) {
reply_with_error ("%s: not a directory", dir);
return -1;
}

/* "tar -C /sysroot%s -cf - ." but we have to quote the dir. */
if (asprintf_nowarn (&cmd, "%s -C %R%s%s%s -cf - .",
if (asprintf_nowarn (&cmd, "%s -C %s%s%s%s -cf - .",
str_tar,
dir, filter,
buf, filter,
numericowner ? " --numeric-owner" : "",
excludes_args) == -1) {
reply_with_perror ("asprintf");
Expand All @@ -344,8 +366,8 @@ do_tar_out (const char *dir, const char *compress, int numericowner,
*/
reply (NULL, NULL);

while ((r = fread (buf, 1, sizeof buf, fp)) > 0) {
if (send_file_write (buf, r) < 0) {
while ((r = fread (buffer, 1, sizeof buffer, fp)) > 0) {
if (send_file_write (buffer, r) < 0) {
pclose (fp);
return -1;
}
Expand Down

0 comments on commit 1bd8138

Please sign in to comment.