diff --git a/daemon/upload.c b/daemon/upload.c index 6db332871..1d60b5548 100644 --- a/daemon/upload.c +++ b/daemon/upload.c @@ -1,5 +1,5 @@ /* libguestfs - the guestfsd daemon - * Copyright (C) 2009 Red Hat Inc. + * Copyright (C) 2009-2013 Red Hat Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -129,6 +129,24 @@ do_upload_offset (const char *filename, int64_t offset) return upload (filename, O_WRONLY|O_CREAT|O_NOCTTY|O_CLOEXEC, offset); } +/* Extra check to prevent RHBZ#908321. */ +static int +check_not_directory (const char *filename, int fd) +{ + struct stat statbuf; + + if (fstat (fd, &statbuf) == -1) { + reply_with_perror ("fstat: %s", filename); + return -1; + } + if (S_ISDIR (statbuf.st_mode)) { + reply_with_error ("%s: is a directory", filename); + return -1; + } + + return 0; +} + /* Has one FileOut parameter. */ int do_download (const char *filename) @@ -146,6 +164,11 @@ do_download (const char *filename) return -1; } + if (check_not_directory (filename, fd) == -1) { + close (fd); + return -1; + } + /* Calculate the size of the file or device for notification messages. */ uint64_t total, sent = 0; if (!is_dev) { @@ -229,6 +252,11 @@ do_download_offset (const char *filename, int64_t offset, int64_t size) return -1; } + if (check_not_directory (filename, fd) == -1) { + close (fd); + return -1; + } + if (offset) { if (lseek (fd, offset, SEEK_SET) == -1) { reply_with_perror ("lseek: %s", filename);