diff options
Diffstat (limited to 'executor/common_linux.h')
| -rw-r--r-- | executor/common_linux.h | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h index 3c6aadd31..610586021 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -1424,8 +1424,14 @@ static void setup_binfmt_misc() #endif #if SYZ_EXECUTOR || SYZ_SANDBOX_NONE || SYZ_SANDBOX_SETUID || SYZ_SANDBOX_NAMESPACE +#include <errno.h> +#include <sys/mount.h> + static void setup_common() { + if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) { + debug("mount(fusectl) failed: %d\n", errno); + } #if SYZ_EXECUTOR || SYZ_ENABLE_CGROUPS setup_cgroups(); setup_binfmt_misc(); @@ -1853,6 +1859,60 @@ static int fault_injected(int fail_fd) } #endif +#if SYZ_EXECUTOR || SYZ_REPEAT +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> + +static void kill_and_wait(int pid, int* status) +{ + kill(-pid, SIGKILL); + kill(pid, SIGKILL); + int i; + // First, give it up to 100 ms to surrender. + for (i = 0; i < 100; i++) { + if (waitpid(-1, status, WNOHANG | __WALL) == pid) + return; + usleep(1000); + } + // Now, try to abort fuse connections as they cause deadlocks, + // see Documentation/filesystems/fuse.txt for details. + // There is no good way to figure out the right connections + // provided that the process could use unshare(CLONE_NEWNS), + // so we abort all. + debug("kill is not working\n"); + DIR* dir = opendir("/sys/fs/fuse/connections"); + if (dir) { + for (;;) { + struct dirent* ent = readdir(dir); + if (!ent) + break; + if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) + continue; + char abort[300]; + snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort", ent->d_name); + int fd = open(abort, O_WRONLY); + if (fd == -1) { + debug("failed to open %s: %d\n", abort, errno); + continue; + } + debug("aborting fuse conn %s\n", ent->d_name); + write(fd, abort, 1); + close(fd); + } + closedir(dir); + } else { + debug("failed to open /sys/fs/fuse/connections: %d\n", errno); + } + // Now, just wait, no other options. + while (waitpid(-1, status, __WALL) != pid) { + } +} +#endif + #if SYZ_EXECUTOR || SYZ_REPEAT && SYZ_ENABLE_CGROUPS #include <fcntl.h> #include <sys/ioctl.h> |
