-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add clone3
and statx
syscalls
#40
base: master
Are you sure you want to change the base?
Add clone3
and statx
syscalls
#40
Conversation
clone3
and statx
sys callsclone3
and statx
syscalls
src/limits/ThreadsLimitListener.cc
Outdated
syscallRules_.emplace_back(seccomp::SeccompRule( | ||
"clone3", | ||
seccomp::action::ActionAllow{}, | ||
(Arg(2) & CLONE_VM) == CLONE_VM)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uhh... just checked what the args of clone3
are, and
long syscall(SYS_clone3, struct clone_args *cl_args, size_t size);
which translates to
clone3(struct clone_args *cl_args, size_t size);
Arg(0)
is a pointer to a struct with all the stuff that'd normally go into clone
args
Arg(1)
is the size of that struct
Arg(2)
is not a thing
So our check for CLONE_VM
flag won't work correctly.
I don't think we can support clone3
. Unless the kernel and libseccomp have some nice way of getting at the parameters in the struct, I think we should just ENOSYS
this one too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added ENOSYS
for clone3
, but now this test is failing:
1: ======================================================================
1: ERROR: test_1_sec_program_threads_1 (testsuits.test_times.TestReportedTimes)
1: ----------------------------------------------------------------------
1: Traceback (most recent call last):
1: File "/sio2jail/test/testsuits/test_times.py", line 24, in test_1_sec_program_threads_1
1: self.assertAlmostEqual(result.time, 1.0)
1: File "/usr/local/lib/python3.9/unittest/case.py", line 868, in assertAlmostEqual
1: diff = abs(first - second)
1: TypeError: unsupported operand type(s) for -: 'NoneType' and 'float'
1: -------------------- >> begin captured stdout << ---------------------
1: running:
1: /sio2jail/build/./src/sio2jail -b /sio2jail/build/./boxes/./minimal/:/:ro -t 1 -m 1G /sio2jail/build/./test/src/1-sec-prog-th flat 1
1:
1: result: 2
1:
1: stdout:
1:
1: stderr:
1: Exception occurred: System error occured: ptrace setopts child failed: No such process: error 3: No such process
1:
1:
1: --------------------- >> end captured stdout << ----------------------
1:
1: ----------------------------------------------------------------------
1: Ran 14 tests in 1.575s
1:
1: FAILED (errors=1)
1/1 Test #1: python ...........................***Failed 1.75 sec
When clone3
is allowed, this test passes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I think I know why this happens.
TraceExecutor gets clone events here
sio2jail/src/tracer/TraceExecutor.cc
Lines 94 to 95 in 8e65e31
if (executeEvent.signal == (SIGTRAP | (PTRACE_EVENT_CLONE << 8))) { | |
action = std::max(action, onEventClone(event, tracee)); |
not due to seccomp traps, but due to PTRACE_O_TRACECLONE
.
It then tries to get child's pid, and set up ptrace of the child too:
sio2jail/src/tracer/TraceExecutor.cc
Lines 137 to 156 in 8e65e31
TraceAction TraceExecutor::onEventClone( | |
const TraceEvent& event, | |
Tracee& tracee) { | |
pid_t traceeChildPid{-1}; | |
withErrnoCheck( | |
"ptrace get child pid", | |
ptrace, | |
PTRACE_GETEVENTMSG, | |
event.executeEvent.pid, | |
nullptr, | |
&traceeChildPid); | |
logger::debug(VAR(event.executeEvent.pid), VAR(traceeChildPid)); | |
withErrnoCheck( | |
"ptrace setopts child", | |
ptrace, | |
PTRACE_SETOPTIONS, | |
traceeChildPid, | |
nullptr, | |
PTRACE_OPTIONS); |
I suspect this triggers even if the a clone (in this case clone3
) fails, and TraceExecutor doesn't check for that.
Maybe ptrace has some way to get the clone's error code, so that we can check if it succeeded.
If there's no way to do that, I guess we can just catch the ESRCH
returned by PTRACE_SETOPTIONS
, assume clone failed and move on, so that the process can retry with the old clone
instead of clone3
.
I also added |
We can't merge this, the tests are currently failing |
oh, that's weird |
ok, looks like it failed when trying to trace the cloned thread, see comment in diff |
Closes #39