From f9bafde5e7f1302ce7c5ea304e51a8d90a323b58 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 6 Feb 2013 13:27:26 +0000 Subject: [PATCH] daemon: download: Add extra check that download file is not a directory (RHBZ#908321). --- daemon/upload.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) 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);