unpack: prevent ability to bypass the byte limit

By passing an empty file with a declared negative size,
a hostile VM can decrease the total bytes counter, while
not have do supply a huge amount of data, thus disabing
the byte size check, and potentially filling the target
filesystem.
release2 mm_9f3a74fd
Vincent Penquerc'h 10 years ago committed by Marek Marczykowski-Górecki
parent b95e80779e
commit 9f3a74fd77

@ -8,6 +8,7 @@
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <limits.h>
#include "libqubes-rpc-filecopy.h"
#include "crc32.h"
@ -18,8 +19,18 @@ long long total_bytes = 0;
long long total_files = 0;
int verbose = 0;
void do_exit(int code, const char *last_filename)
{
close(0);
send_status_and_crc(code, last_filename);
exit(code);
}
void set_size_limit(long long new_bytes_limit, long long new_files_limit)
{
if (new_bytes_limit < 0 || new_files_limit < 0) {
do_exit(EINVAL, "");
}
bytes_limit = new_bytes_limit;
files_limit = new_files_limit;
}
@ -58,13 +69,6 @@ void send_status_and_crc(int code, const char *last_filename) {
errno = saved_errno;
}
void do_exit(int code, const char *last_filename)
{
close(0);
send_status_and_crc(code, last_filename);
exit(code);
}
void fix_times_and_perms(struct file_header *untrusted_hdr,
const char *untrusted_name)
{
@ -88,9 +92,12 @@ void process_one_file_reg(struct file_header *untrusted_hdr,
int fdout = open(untrusted_name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0700); /* safe because of chroot */
if (fdout < 0)
do_exit(errno, untrusted_name);
total_bytes += untrusted_hdr->filelen;
if (bytes_limit && total_bytes > bytes_limit)
/* sizes are signed elsewhere */
if (untrusted_hdr->filelen > LLONG_MAX || (bytes_limit && untrusted_hdr->filelen > bytes_limit))
do_exit(EDQUOT, untrusted_name);
if (bytes_limit && total_bytes > bytes_limit - untrusted_hdr->filelen)
do_exit(EDQUOT, untrusted_name);
total_bytes += untrusted_hdr->filelen;
ret = copy_file(fdout, 0, untrusted_hdr->filelen, &crc32_sum);
if (ret != COPY_FILE_OK) {
if (ret == COPY_FILE_READ_EOF

Loading…
Cancel
Save