dom0: implement size/file-count limit of downloaded updates (#198)
Currently limit is 2GB and 2048 files, but can be adjusted by env variables (UPDATES_MAX_BYTES, UPDATES_MAX_FILES).
This commit is contained in:
parent
60d14758d6
commit
977b058395
@ -29,3 +29,4 @@ enum {
|
|||||||
|
|
||||||
int copy_file(int outfd, int infd, long long size, unsigned long *crc32);
|
int copy_file(int outfd, int infd, long long size, unsigned long *crc32);
|
||||||
char *copy_file_status_to_str(int status);
|
char *copy_file_status_to_str(int status);
|
||||||
|
void set_size_limit(long long new_bytes_limit, long long new_files_limit);
|
||||||
|
@ -11,10 +11,21 @@
|
|||||||
#include "crc32.h"
|
#include "crc32.h"
|
||||||
|
|
||||||
char untrusted_namebuf[MAX_PATH_LENGTH];
|
char untrusted_namebuf[MAX_PATH_LENGTH];
|
||||||
|
long long bytes_limit = 0;
|
||||||
|
long long files_limit = 0;
|
||||||
|
long long total_bytes = 0;
|
||||||
|
long long total_files = 0;
|
||||||
|
|
||||||
void notify_progress(int p1, int p2)
|
void notify_progress(int p1, int p2)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_size_limit(long long new_bytes_limit, long long new_files_limit)
|
||||||
|
{
|
||||||
|
bytes_limit = new_bytes_limit;
|
||||||
|
files_limit = new_files_limit;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long crc32_sum = 0;
|
unsigned long crc32_sum = 0;
|
||||||
int read_all_with_crc(int fd, void *buf, int size) {
|
int read_all_with_crc(int fd, void *buf, int size) {
|
||||||
int ret;
|
int ret;
|
||||||
@ -56,6 +67,9 @@ 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 */
|
int fdout = open(untrusted_name, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0700); /* safe because of chroot */
|
||||||
if (fdout < 0)
|
if (fdout < 0)
|
||||||
do_exit(errno);
|
do_exit(errno);
|
||||||
|
total_bytes += untrusted_hdr->filelen;
|
||||||
|
if (bytes_limit && total_bytes > bytes_limit)
|
||||||
|
do_exit(EDQUOT);
|
||||||
ret = copy_file(fdout, 0, untrusted_hdr->filelen, &crc32_sum);
|
ret = copy_file(fdout, 0, untrusted_hdr->filelen, &crc32_sum);
|
||||||
if (ret != COPY_FILE_OK) {
|
if (ret != COPY_FILE_OK) {
|
||||||
if (ret == COPY_FILE_READ_EOF
|
if (ret == COPY_FILE_READ_EOF
|
||||||
@ -140,6 +154,9 @@ void do_unpack(int fd)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
process_one_file(&untrusted_hdr);
|
process_one_file(&untrusted_hdr);
|
||||||
|
total_files++;
|
||||||
|
if (files_limit && total_files > files_limit)
|
||||||
|
do_exit(EDQUOT);
|
||||||
}
|
}
|
||||||
send_status_and_crc();
|
send_status_and_crc();
|
||||||
if (errno)
|
if (errno)
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
#include <gui-fatal.h>
|
#include <gui-fatal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "filecopy.h"
|
#include "filecopy.h"
|
||||||
|
|
||||||
|
#define DEFAULT_MAX_UPDATES_BYTES (2L<<30)
|
||||||
|
#define DEFAULT_MAX_UPDATES_FILES 2048
|
||||||
|
|
||||||
int prepare_creds_return_uid(char *username)
|
int prepare_creds_return_uid(char *username)
|
||||||
{
|
{
|
||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
@ -50,12 +54,20 @@ int main(int argc, char ** argv)
|
|||||||
char *incoming_dir;
|
char *incoming_dir;
|
||||||
int pipefds[2];
|
int pipefds[2];
|
||||||
int uid;
|
int uid;
|
||||||
|
char *var;
|
||||||
|
long long files_limit = DEFAULT_MAX_UPDATES_FILES;
|
||||||
|
long long bytes_limit = DEFAULT_MAX_UPDATES_BYTES;
|
||||||
|
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Invalid parameters, usage: %s user dir\n", argv[0]);
|
fprintf(stderr, "Invalid parameters, usage: %s user dir\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((var=getenv("UPDATES_MAX_BYTES")))
|
||||||
|
bytes_limit = atoll(var);
|
||||||
|
if ((var=getenv("UPDATES_MAX_FILES")))
|
||||||
|
files_limit = atoll(var);
|
||||||
|
|
||||||
pipe(pipefds);
|
pipe(pipefds);
|
||||||
|
|
||||||
uid = prepare_creds_return_uid(argv[1]);
|
uid = prepare_creds_return_uid(argv[1]);
|
||||||
@ -73,6 +85,7 @@ int main(int argc, char ** argv)
|
|||||||
gui_fatal("Error chroot to %s", incoming_dir);
|
gui_fatal("Error chroot to %s", incoming_dir);
|
||||||
setuid(uid);
|
setuid(uid);
|
||||||
close(pipefds[0]);
|
close(pipefds[0]);
|
||||||
|
set_size_limit(bytes_limit, files_limit);
|
||||||
do_unpack(pipefds[1]);
|
do_unpack(pipefds[1]);
|
||||||
exit(0);
|
exit(0);
|
||||||
default:;
|
default:;
|
||||||
|
Loading…
Reference in New Issue
Block a user