mirror of https://github.com/proot-me/proot.git
Set the restart_how field in a newly created child tracee. (#308)
This eliminates unexpected SIGTRAPs in newly forked processes, allowing removal of ugly (and broken) workarounds in the handle_tracee_event_kernel_4_8 event handler. "Useless" seccomp traps still may happen if a tracee has explicity disabled seccomp (like during ptrace emulation), but handling these is much easier. This fixes following tests: test-d92b57ca, test-2db65cd2. Additionaly test-230f47ch is not skipped now, but it fails under seccomp due to missing seccomp handling in handle_ptracee_event.
This commit is contained in:
parent
d92431accd
commit
9e9cd23baa
|
@ -398,7 +398,6 @@ static int handle_tracee_event_kernel_4_8(Tracee *tracee, int tracee_status)
|
|||
static bool seccomp_enabled = false; /* added for 4.8.0 */
|
||||
long status;
|
||||
int signal;
|
||||
bool need_exit = true;
|
||||
|
||||
/* Don't overwrite restart_how if it is explicitly set
|
||||
* elsewhere, i.e in the ptrace emulation when single
|
||||
|
@ -499,35 +498,16 @@ static int handle_tracee_event_kernel_4_8(Tracee *tracee, int tracee_status)
|
|||
unsigned long flags = 0;
|
||||
signal = 0;
|
||||
|
||||
/* Use the common ptrace flow if seccomp was
|
||||
* explicitly disabled for this tracee. */
|
||||
if (tracee->seccomp != ENABLED)
|
||||
break;
|
||||
|
||||
status = ptrace(PTRACE_GETEVENTMSG, tracee->pid, NULL, &flags);
|
||||
if (status < 0)
|
||||
break;
|
||||
need_exit = flags & FILTER_SYSEXIT;
|
||||
|
||||
/* SECCOMP TRAP can only be received for
|
||||
* sysenter events. It is sometimes possible for sysenter
|
||||
* to be handled at the normal PTRACE_SYSCALL SIGTRAP handler,
|
||||
* before seccomp trap arrives.
|
||||
* This may happen for example during handling of the first
|
||||
* syscall the traced process makes, before seccomp is enabled,
|
||||
* however there is some other random and unknown factor that affects that.
|
||||
* If this happened, then continue until the next syscall
|
||||
* or sysexit if necessary. */
|
||||
if (!IS_IN_SYSENTER(tracee)) {
|
||||
if (need_exit || tracee->restart_how == PTRACE_SYSCALL) {
|
||||
tracee->restart_how = PTRACE_SYSCALL;
|
||||
}
|
||||
else {
|
||||
// We are not interested in the sysexit
|
||||
// continue to the next sysenter
|
||||
// and clear the status to expect a sysenter next.
|
||||
tracee->restart_how = PTRACE_CONT;
|
||||
tracee->status = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (tracee->seccomp == ENABLED && (flags & FILTER_SYSEXIT) == 0) {
|
||||
if ((flags & FILTER_SYSEXIT) == 0) {
|
||||
tracee->restart_how = PTRACE_CONT;
|
||||
translate_syscall(tracee);
|
||||
|
||||
|
@ -553,7 +533,7 @@ static int handle_tracee_event_kernel_4_8(Tracee *tracee, int tracee_status)
|
|||
|
||||
switch (tracee->seccomp) {
|
||||
case ENABLED:
|
||||
if (IS_IN_SYSENTER(tracee) && need_exit) {
|
||||
if (IS_IN_SYSENTER(tracee)) {
|
||||
/* sysenter: ensure the sysexit
|
||||
* stage will be hit under seccomp. */
|
||||
tracee->restart_how = PTRACE_SYSCALL;
|
||||
|
|
|
@ -432,6 +432,7 @@ int new_child(Tracee *parent, word_t clone_flags)
|
|||
child->verbose = parent->verbose;
|
||||
child->seccomp = parent->seccomp;
|
||||
child->sysexit_pending = parent->sysexit_pending;
|
||||
child->restart_how = parent->restart_how;
|
||||
|
||||
/* If CLONE_VM is set, the calling process and the child
|
||||
* process run in the same memory space [...] any memory
|
||||
|
|
Loading…
Reference in New Issue