void-packages/srcpkgs/proot/patches/linux4.8.patch

194 lines
6.0 KiB
Diff

From 25e8461cbe56a3f035df145d9d762b65aa3eedb7 Mon Sep 17 00:00:00 2001
From: Jorge Gomes <jorge@lip.pt>
Date: Mon, 13 Feb 2017 20:37:17 +0000
Subject: [PATCH] fix event.c for seccomp and ptrace
---
src/tracee/event.c | 129 ++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 88 insertions(+), 41 deletions(-)
diff --git src/tracee/event.c src/tracee/event.c
index bafc3c5..64166f6 100644
--- a/src/tracee/event.c
+++ b/src/tracee/event.c
@@ -20,6 +20,7 @@
* 02110-1301 USA.
*/
+#include <stdio.h>
#include <sched.h> /* CLONE_*, */
#include <sys/types.h> /* pid_t, */
#include <sys/ptrace.h> /* ptrace(1), PTRACE_*, */
@@ -47,6 +48,7 @@
#include "attribute.h"
#include "compat.h"
+
/**
* Start @tracee->exe with the given @argv[]. This function
* returns -errno if an error occurred, otherwise 0.
@@ -205,6 +207,27 @@ static void print_talloc_hierarchy(int signum, siginfo_t *siginfo UNUSED, void *
static int last_exit_status = -1;
/**
+ * Check if kernel >= 4.8
+ */
+bool is_kernel_4_8(void) {
+ struct utsname utsname;
+ int status;
+ static bool version_48 = false;
+ static int major = 0;
+ static int minor = 0;
+ if (! major) {
+ status = uname(&utsname);
+ if (status < 0)
+ return false;
+ sscanf(utsname.release, "%d.%d", &major, &minor);
+ if (major >= 4)
+ if (minor >= 8)
+ version_48 = true;
+ }
+ return version_48;
+}
+
+/**
* Check if this instance of PRoot can *technically* handle @tracee.
*/
static void check_architecture(Tracee *tracee)
@@ -362,6 +385,7 @@ int event_loop()
int handle_tracee_event(Tracee *tracee, int tracee_status)
{
static bool seccomp_detected = false;
+ static bool seccomp_enabled = false;
pid_t pid = tracee->pid;
long status;
int signal;
@@ -432,6 +456,7 @@ int handle_tracee_event(Tracee *tracee, int tracee_status)
status = ptrace(PTRACE_SETOPTIONS, tracee->pid, NULL,
default_ptrace_options | PTRACE_O_TRACESECCOMP);
if (status < 0) {
+ seccomp_enabled = false;
/* ... otherwise use default options only. */
status = ptrace(PTRACE_SETOPTIONS, tracee->pid, NULL,
default_ptrace_options);
@@ -440,8 +465,71 @@ int handle_tracee_event(Tracee *tracee, int tracee_status)
exit(EXIT_FAILURE);
}
}
+ else {
+ if (getenv("PROOT_NO_SECCOMP") == NULL)
+ seccomp_enabled = true;
+ }
}
/* Fall through. */
+ case SIGTRAP | PTRACE_EVENT_SECCOMP2 << 8:
+ case SIGTRAP | PTRACE_EVENT_SECCOMP << 8:
+
+ if (is_kernel_4_8()) {
+ if (seccomp_enabled) {
+ if (!seccomp_detected) {
+ VERBOSE(tracee, 1, "ptrace acceleration (seccomp mode 2) enabled");
+ tracee->seccomp = ENABLED;
+ seccomp_detected = true;
+ }
+
+ unsigned long flags = 0;
+ status = ptrace(PTRACE_GETEVENTMSG, tracee->pid, NULL, &flags);
+ if (status < 0)
+ break;
+ }
+ }
+ else if (signal == (SIGTRAP | PTRACE_EVENT_SECCOMP2 << 8) ||
+ signal == (SIGTRAP | PTRACE_EVENT_SECCOMP << 8)) {
+ unsigned long flags = 0;
+
+ signal = 0;
+
+ if (!seccomp_detected) {
+ VERBOSE(tracee, 1, "ptrace acceleration (seccomp mode 2) enabled");
+ tracee->seccomp = ENABLED;
+ seccomp_detected = true;
+ }
+
+ /* Use the common ptrace flow if seccomp was
+ * explicitely disabled for this tracee. */
+ if (tracee->seccomp != ENABLED)
+ break;
+
+ status = ptrace(PTRACE_GETEVENTMSG, tracee->pid, NULL, &flags);
+ if (status < 0)
+ break;
+
+ /* Use the common ptrace flow when
+ * sysexit has to be handled. */
+ if ((flags & FILTER_SYSEXIT) != 0) {
+ tracee->restart_how = PTRACE_SYSCALL;
+ break;
+ }
+
+ /* Otherwise, handle the sysenter
+ * stage right now. */
+ tracee->restart_how = PTRACE_CONT;
+ translate_syscall(tracee);
+
+ /* This syscall has disabled seccomp, so move
+ * the ptrace flow back to the common path to
+ * ensure its sysexit will be handled. */
+ if (tracee->seccomp == DISABLING)
+ tracee->restart_how = PTRACE_SYSCALL;
+ break;
+ }
+
+ /* Fall through. */
case SIGTRAP | 0x80:
signal = 0;
@@ -490,47 +578,6 @@ int handle_tracee_event(Tracee *tracee, int tracee_status)
}
break;
- case SIGTRAP | PTRACE_EVENT_SECCOMP2 << 8:
- case SIGTRAP | PTRACE_EVENT_SECCOMP << 8: {
- unsigned long flags = 0;
-
- signal = 0;
-
- if (!seccomp_detected) {
- VERBOSE(tracee, 1, "ptrace acceleration (seccomp mode 2) enabled");
- tracee->seccomp = ENABLED;
- seccomp_detected = true;
- }
-
- /* Use the common ptrace flow if seccomp was
- * explicitely disabled for this tracee. */
- if (tracee->seccomp != ENABLED)
- break;
-
- status = ptrace(PTRACE_GETEVENTMSG, tracee->pid, NULL, &flags);
- if (status < 0)
- break;
-
- /* Use the common ptrace flow when
- * sysexit has to be handled. */
- if ((flags & FILTER_SYSEXIT) != 0) {
- tracee->restart_how = PTRACE_SYSCALL;
- break;
- }
-
- /* Otherwise, handle the sysenter
- * stage right now. */
- tracee->restart_how = PTRACE_CONT;
- translate_syscall(tracee);
-
- /* This syscall has disabled seccomp, so move
- * the ptrace flow back to the common path to
- * ensure its sysexit will be handled. */
- if (tracee->seccomp == DISABLING)
- tracee->restart_how = PTRACE_SYSCALL;
- break;
- }
-
case SIGTRAP | PTRACE_EVENT_VFORK << 8:
signal = 0;
(void) new_child(tracee, CLONE_VFORK);