blob: 7861fe1f510f0be018cf767a27a799537702096d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
digraph {
subgraph {
App;
}
subgraph {
Interrupt;
InterruptAfterSignalDeliveryStop;
}
subgraph {
Syscall;
SyscallAfterPtraceEventSeccomp;
SyscallEnter;
SyscallAfterSyscallEnterStop;
SyscallAfterSysemuStop;
SyscallInvoke;
SyscallAfterPtraceEventClone;
SyscallAfterExecStop;
SyscallAfterVforkStop;
SyscallReinvoke;
SyscallExit;
}
subgraph {
Vsyscall;
VsyscallAfterPtraceEventSeccomp;
VsyscallInvoke;
}
subgraph {
Exit;
ExitMain; // leave thread group, release resources, reparent children, kill PID namespace and wait if TGID 1
ExitNotify; // signal parent/tracer, become waitable
ExitDone; // represented by t.runState == nil
}
// Task exit
Exit -> ExitMain;
ExitMain -> ExitNotify;
ExitNotify -> ExitDone;
// Execution of untrusted application code
App -> App;
// Interrupts (usually signal delivery)
App -> Interrupt;
Interrupt -> Interrupt; // if other interrupt conditions may still apply
Interrupt -> Exit; // if killed
// Syscalls
App -> Syscall;
Syscall -> SyscallEnter;
SyscallEnter -> SyscallInvoke;
SyscallInvoke -> SyscallExit;
SyscallExit -> App;
// exit, exit_group
SyscallInvoke -> Exit;
// execve
SyscallInvoke -> SyscallAfterExecStop;
SyscallAfterExecStop -> SyscallExit;
SyscallAfterExecStop -> App; // fatal signal pending
// vfork
SyscallInvoke -> SyscallAfterVforkStop;
SyscallAfterVforkStop -> SyscallExit;
// Vsyscalls
App -> Vsyscall;
Vsyscall -> VsyscallInvoke;
Vsyscall -> App; // fault while reading return address from stack
VsyscallInvoke -> App;
// ptrace-specific branches
Interrupt -> InterruptAfterSignalDeliveryStop;
InterruptAfterSignalDeliveryStop -> Interrupt;
SyscallEnter -> SyscallAfterSyscallEnterStop;
SyscallAfterSyscallEnterStop -> SyscallInvoke;
SyscallAfterSyscallEnterStop -> SyscallExit; // skipped by tracer
SyscallAfterSyscallEnterStop -> App; // fatal signal pending
SyscallEnter -> SyscallAfterSysemuStop;
SyscallAfterSysemuStop -> SyscallExit;
SyscallAfterSysemuStop -> App; // fatal signal pending
SyscallInvoke -> SyscallAfterPtraceEventClone;
SyscallAfterPtraceEventClone -> SyscallExit;
SyscallAfterPtraceEventClone -> SyscallAfterVforkStop;
// seccomp
Syscall -> App; // SECCOMP_RET_TRAP, SECCOMP_RET_ERRNO, SECCOMP_RET_KILL, SECCOMP_RET_TRACE without tracer
Syscall -> SyscallAfterPtraceEventSeccomp; // SECCOMP_RET_TRACE
SyscallAfterPtraceEventSeccomp -> SyscallEnter;
SyscallAfterPtraceEventSeccomp -> SyscallExit; // skipped by tracer
SyscallAfterPtraceEventSeccomp -> App; // fatal signal pending
Vsyscall -> VsyscallAfterPtraceEventSeccomp;
VsyscallAfterPtraceEventSeccomp -> VsyscallInvoke;
VsyscallAfterPtraceEventSeccomp -> App;
// Autosave
SyscallInvoke -> SyscallReinvoke;
SyscallReinvoke -> SyscallInvoke;
}
|