redmine

Fixed "Bad system call" on --thread-splitting --forbid-devices --seccomp-filter

... ... @@ -83,14 +83,10 @@ int clsync_cgroup_attach(ctx_t *ctx_p) {
int clsync_cgroup_deinit(ctx_t *ctx_p) {
debug(2, "");
setuid(0);
error_on(cgroup_delete_cgroup_ext(cgroup, CGFLAG_DELETE_IGNORE_MIGRATION | CGFLAG_DELETE_RECURSIVE));
cgroup_free(&cgroup);
if (ctx_p->uid != 0)
setuid(ctx_p->uid);
debug(15, "end");
return 0;
}
... ...
... ... @@ -1292,7 +1292,9 @@ Forbid all syscalls for non-privileged thread, but
.RS
futex
inotify_init1
alarm
alert
stat
fstat
lstat
open
write
... ...
... ... @@ -812,7 +812,46 @@ void *privileged_handler(void *_ctx_p)
}
# ifdef CGROUP_SUPPORT
case PA_CLSYNC_CGROUP_DEINIT: {
cmd.ret = (void *)(long)clsync_cgroup_deinit(cmd.arg);
/*
* That is strange, but setuid() doesn't work
* without fork() in case of enabled seccomp
* filter. So sorry for this hacky thing.
*
* TODO: fix that.
*/
int status;
pid_t pid = fork();
switch (pid) {
case -1:
error("Cannot fork().");
break;
case 0:
debug(4, "setgid(0) == %i", setgid(0));
debug(4, "setuid(0) == %i", setuid(0));
exit(clsync_cgroup_deinit(cmd.arg));
}
if (waitpid(pid, &status, 0) != pid) {
switch (errno) {
case ECHILD:
debug(2, "Child %u has already died.", pid);
break;
default:
error("Cannot waitid().");
cmd._errno = errno;
cmd.ret = (void *)(long)errno;
}
}
#ifdef VERYPARANOID
pthread_sigmask(SIG_SETMASK, &sigset_old, NULL);
#endif
// Return
int exitcode = WEXITSTATUS(status);
debug(3, "execution completed with exitcode %i", exitcode);
cmd._errno = exitcode;
cmd.ret = (void *)(long)exitcode;
break;
}
# endif
... ...