vm+dom0/filecopy-unpacker: send errors to qfile-agent istead of local message (#239)

Because unpacker no longer require GUI access, there is no need for separate
process for error reporting. Which greatly simplify the code.
This commit is contained in:
Marek Marczykowski 2012-08-25 02:09:45 +02:00
parent cec58c048a
commit fefb6d9cff
3 changed files with 26 additions and 86 deletions

View File

@ -52,12 +52,11 @@ void wait_for_child(int statusfd)
} }
} }
extern void do_unpack(int); extern int do_unpack(void);
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
char *incoming_dir; char *incoming_dir;
int pipefds[2];
int uid; int uid;
char *var; char *var;
long long files_limit = DEFAULT_MAX_UPDATES_FILES; long long files_limit = DEFAULT_MAX_UPDATES_FILES;
@ -73,32 +72,15 @@ int main(int argc, char ** argv)
if ((var=getenv("UPDATES_MAX_FILES"))) if ((var=getenv("UPDATES_MAX_FILES")))
files_limit = atoll(var); files_limit = atoll(var);
pipe(pipefds);
uid = prepare_creds_return_uid(argv[1]); uid = prepare_creds_return_uid(argv[1]);
incoming_dir = argv[2]; incoming_dir = argv[2];
mkdir(incoming_dir, 0700); mkdir(incoming_dir, 0700);
if (chdir(incoming_dir)) if (chdir(incoming_dir))
gui_fatal("Error chdir to %s", incoming_dir); gui_fatal("Error chdir to %s", incoming_dir);
switch (fork()) { if (chroot(incoming_dir)) //impossible
case -1: gui_fatal("Error chroot to %s", incoming_dir);
perror("fork");
exit(1);
case 0:
if (chroot(incoming_dir)) //impossible
gui_fatal("Error chroot to %s", incoming_dir);
setuid(uid);
close(pipefds[0]);
set_size_limit(bytes_limit, files_limit);
do_unpack(pipefds[1]);
exit(0);
default:;
}
setuid(uid); setuid(uid);
close(pipefds[1]); set_size_limit(bytes_limit, files_limit);
wait_for_child(pipefds[0]); return do_unpack();
return 0;
} }

View File

@ -29,32 +29,14 @@ int prepare_creds_return_uid(char *username)
return pwd->pw_uid; return pwd->pw_uid;
} }
void wait_for_child(int statusfd) extern int do_unpack(void);
{
int status;
if (read(statusfd, &status, sizeof status)!=sizeof status)
gui_fatal("File copy error: Internal error reading status from unpacker");
errno = status;
switch (status) {
case LEGAL_EOF: break;
case 0: gui_fatal("File copy: Connection terminated unexpectedly"); break;
case EINVAL: gui_fatal("File copy: Corrupted data from packer"); break;
case EEXIST: gui_fatal("File copy: not overwriting existing file. Clean ~/incoming, and retry copy"); break;
default: gui_fatal("File copy");
}
}
extern void do_unpack(int);
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
char *incoming_dir; char *incoming_dir;
int pipefds[2];
int uid; int uid;
char *remote_domain; char *remote_domain;
pipe(pipefds);
uid = prepare_creds_return_uid("user"); uid = prepare_creds_return_uid("user");
remote_domain = getenv("QREXEC_REMOTE_DOMAIN"); remote_domain = getenv("QREXEC_REMOTE_DOMAIN");
@ -67,25 +49,8 @@ int main(int argc, char ** argv)
mkdir(incoming_dir, 0700); mkdir(incoming_dir, 0700);
if (chdir(incoming_dir)) if (chdir(incoming_dir))
gui_fatal("Error chdir to %s", incoming_dir); gui_fatal("Error chdir to %s", incoming_dir);
switch (fork()) { if (chroot(incoming_dir)) //impossible
case -1: gui_fatal("Error chroot to %s", incoming_dir);
perror("fork");
exit(1);
case 0:
if (chroot(incoming_dir)) //impossible
gui_fatal("Error chroot to %s", incoming_dir);
setuid(uid);
close(pipefds[0]);
do_unpack(pipefds[1]);
exit(0);
default:;
}
close(0);
close(1);
setuid(uid); setuid(uid);
close(pipefds[1]); return do_unpack();
wait_for_child(pipefds[0]);
return 0;
} }

View File

@ -35,14 +35,22 @@ int read_all_with_crc(int fd, void *buf, int size) {
return ret; return ret;
} }
int global_status_fd; void send_status_and_crc(int code) {
void do_exit(int code) struct result_header hdr;
{ int saved_errno;
int codebuf = code;
write(global_status_fd, &codebuf, sizeof codebuf); saved_errno = errno;
exit(0); hdr.error_code = code;
hdr.crc32 = crc32_sum;
write_all(1, &hdr, sizeof(hdr));
errno = saved_errno;
} }
void do_exit(int code)
{
send_status_and_crc(code);
exit(code);
}
void fix_times_and_perms(struct file_header *untrusted_hdr, void fix_times_and_perms(struct file_header *untrusted_hdr,
char *untrusted_name) char *untrusted_name)
@ -130,20 +138,8 @@ void process_one_file(struct file_header *untrusted_hdr)
do_exit(EINVAL); do_exit(EINVAL);
} }
void send_status_and_crc() { int do_unpack()
struct result_header hdr;
int saved_errno;
saved_errno = errno;
hdr.error_code = errno;
hdr.crc32 = crc32_sum;
write_all(1, &hdr, sizeof(hdr));
errno = saved_errno;
}
void do_unpack(int fd)
{ {
global_status_fd = fd;
struct file_header untrusted_hdr; struct file_header untrusted_hdr;
/* initialize checksum */ /* initialize checksum */
crc32_sum = 0; crc32_sum = 0;
@ -158,9 +154,6 @@ void do_unpack(int fd)
if (files_limit && total_files > files_limit) if (files_limit && total_files > files_limit)
do_exit(EDQUOT); do_exit(EDQUOT);
} }
send_status_and_crc(); send_status_and_crc(errno);
if (errno) return errno;
do_exit(errno);
else
do_exit(LEGAL_EOF);
} }