From af78e8d9e8937478b54fe39f4932e5bf7fca4501 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Sat, 28 Dec 2013 06:28:20 -0500 Subject: [PATCH] unpack: count directory and symlink sizes Also do not rely on unpack being called just once if we don't have to and initialize counts. Since we don't know directory size before populating with files, we just accumulate the size on the second pass, but do not actually check for the limit being reached. If there's any file after that, that'll trip the check. --- qrexec-lib/unpack.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/qrexec-lib/unpack.c b/qrexec-lib/unpack.c index 0de026f..38bf270 100644 --- a/qrexec-lib/unpack.c +++ b/qrexec-lib/unpack.c @@ -109,10 +109,15 @@ void process_one_file_dir(struct file_header *untrusted_hdr, { // fix perms only when the directory is sent for the second time // it allows to transfer r.x directory contents, as we create it rwx initially + struct stat buf; if (!mkdir(untrusted_name, 0700)) /* safe because of chroot */ return; if (errno != EEXIST) do_exit(errno, untrusted_name); + if (stat(untrusted_name,&buf) < 0) + do_exit(errno, untrusted_name); + total_bytes += buf.st_size; + /* size accumulated after the fact, so don't check limit here */ fix_times_and_perms(untrusted_hdr, untrusted_name); } @@ -124,6 +129,9 @@ void process_one_file_link(struct file_header *untrusted_hdr, if (untrusted_hdr->filelen > MAX_PATH_LENGTH - 1) do_exit(ENAMETOOLONG, untrusted_name); filelen = untrusted_hdr->filelen; /* sanitized above */ + total_bytes += filelen; + if (bytes_limit && total_bytes > bytes_limit) + do_exit(EDQUOT, untrusted_name); if (!read_all_with_crc(0, untrusted_content, filelen)) do_exit(LEGAL_EOF, untrusted_name); // hopefully remote has produced error message untrusted_content[filelen] = 0; @@ -156,6 +164,7 @@ void process_one_file(struct file_header *untrusted_hdr) int do_unpack() { struct file_header untrusted_hdr; + total_bytes = total_files = 0; /* initialize checksum */ crc32_sum = 0; while (read_all_with_crc(0, &untrusted_hdr, sizeof untrusted_hdr)) {