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

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);
} }