diff options
author | Julian Andres Klode <jak@debian.org> | 2017-11-12 17:45:13 +0100 |
---|---|---|
committer | Julian Andres Klode <jak@debian.org> | 2017-11-12 17:45:13 +0100 |
commit | 243acdee176dd90cb2838690cb5abbd64d4da905 (patch) | |
tree | 7c310f7c21cbc5df3728a73cec5859b46fc4a57b /methods/aptmethod.h | |
parent | 32b39bf5c9210ad49ad66d620f78f83240b0bb4c (diff) |
Do not attempt seccomp under qemu-user and drop EFAULT workaround
qemu-user passes prctl()-based seccomp through to the kernel,
umodified. That's bad, as it blocks the wrong syscalls.
We ignored EFAULT which fixed the problem for targets with different
pointer sizes from the host, but was a bad hack. In order to identify
qemu we can rely on the fact that qemu-user prints its version and
exits with 0 if QEMU_VERSION is set to an unsupported value. If we
run a command that should fail in such an environment, and it exits
with 0, then we are running in qemu-user.
apt-helper is an obvious command to run. The tests ensure it exits
with 1, and it only prints usage information. We also could not use
/bin/false because apt might just as well be from a foreign arch
while /bin/false is not.
Closes: #881519
Diffstat (limited to 'methods/aptmethod.h')
-rw-r--r-- | methods/aptmethod.h | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/methods/aptmethod.h b/methods/aptmethod.h index 5cae7295b..8d37cbe80 100644 --- a/methods/aptmethod.h +++ b/methods/aptmethod.h @@ -14,9 +14,11 @@ #include <string> #include <vector> +#include <stdlib.h> #include <sys/stat.h> #include <sys/time.h> #include <sys/types.h> +#include <sys/wait.h> #include <unistd.h> #include <apti18n.h> @@ -60,6 +62,34 @@ protected: return true; } + bool RunningInQemu(void) + { + int status; + pid_t pid; + + pid = fork(); + if (pid == 0) + { + close(0); + close(1); + close(2); + setenv("QEMU_VERSION", "meow", 1); + char path[] = LIBEXEC_DIR "/apt-helper"; + char *const argv[] = {path, NULL}; + execv(argv[0], argv); + _exit(255); + } + + // apt-helper is supposed to exit with an error. If it exited with 0, + // qemu-user had problems with QEMU_VERSION and returned 0 => running in + // qemu-user. + + if (waitpid(pid, &status, 0) == pid && WIFEXITED(status) && WEXITSTATUS(status) == 0) + return true; + + return false; + } + bool LoadSeccomp() { #ifdef HAVE_SECCOMP @@ -72,6 +102,12 @@ protected: if (_config->FindB("APT::Sandbox::Seccomp", true) == false) return true; + if (RunningInQemu() == true) + { + Warning("Running in qemu-user, not using seccomp"); + return true; + } + ctx = seccomp_init(SCMP_ACT_TRAP); if (ctx == NULL) return _error->FatalE("HttpMethod::Configuration", "Cannot init seccomp"); @@ -270,7 +306,7 @@ protected: #undef ALLOW rc = seccomp_load(ctx); - if (rc == -EINVAL || rc == -EFAULT) // Qemu faults... + if (rc == -EINVAL) Warning("aptMethod::Configuration: could not load seccomp policy: %s", strerror(-rc)); else if (rc != 0) return _error->FatalE("aptMethod::Configuration", "could not load seccomp policy: %s", strerror(-rc)); |