summaryrefslogtreecommitdiff
path: root/methods
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2017-11-12 17:45:13 +0100
committerJulian Andres Klode <jak@debian.org>2017-11-12 17:45:13 +0100
commit243acdee176dd90cb2838690cb5abbd64d4da905 (patch)
tree7c310f7c21cbc5df3728a73cec5859b46fc4a57b /methods
parent32b39bf5c9210ad49ad66d620f78f83240b0bb4c (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')
-rw-r--r--methods/aptmethod.h38
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));