I have enabled seccomp via python-prctl in a project. I can't quite figure out how to exit cleanly - the result is always a kill.
I saw some examples that use ctypes or ffi to try to reference libc, but if I expect them with WIFEXITED they also seem to have the same issue.
Example code below. The result is always "We were killed to death".
def main():
pid = os.fork()
if not pid:
prctl.set_seccomp(True)
os.write(0, 'Hi\n')
# os._exit(0)
# _exit(0)
# sys._exit(0)
# return
# ?!@#(*! What do?
endpid, status = os.waitpid(pid, 0)
print 'Child forked as %d and returned with %d' % (endpid, status)
if not os.WIFEXITED(status):
print 'Exitted abnormally'
if os.WIFSIGNALED:
if os.WTERMSIG(status) == signal.SIGKILL:
print 'We were killed to death'
else:
print 'Returned with %d' % (os.WEXITSTATUS(status))
Quick update since I forgot the libc stuff:
Defining _exit() above with either of these still resulted in a kill.
# FFI Method
ffi = cffi.FFI()
# Use _exit, which avoids atexit(), etc
ffi.cdef('void _exit(int);')
libc = ffi.dlopen(None)
_exit = libc._exit
.... or ....
# ctypes method
libc = cdll.LoadLibrary('libc-2.18.so')
_exit = libc._exit
Someone helped me find this answer:
In glibc up to version 2.3, the _exit() wrapper function invoked the kernel system
call of the same name. Since glibc 2.3, the wrapper function invokes
exit_group(2), in order to terminate all of the threads in a process.
Since the _exit wraps exit_group and exit_group is not in the seccomp filter.... it gets killed. strace of the python execution shows the exit_group call.
来源:https://stackoverflow.com/questions/25678139/how-do-you-cleanly-exit-after-enabling-seccomp-in-python