Thread (7 messages) 7 messages, 2 authors, 2025-07-15

_exit(2) vs. syscall(SYS_exit) (was: Re: for man seccomp)

From: Terence Kelly <hidden>
Date: 2025-07-14 23:46:04


Hi Alejandro,

[separating out different sub-threads of the conversation]

The attached tarball "exit_example.tar.gz" shows why I don't use 
"_exit(2)" per your suggesion.  On a late-vintage Ubuntu 24.04, it doesn't 
do what I expect, but my way does: Compile and run both my way and yours 
with "run.csh" and look at the output I get from that script in 
"run.csh.out".

I'm not sure I ever figured out why this happens.  Any idea what's going 
on?  Maybe the C wrapper function is making a syscall that seccomp bans.

-- Terence



On Sat, 12 Jul 2025, Alejandro Colomar wrote:
quoted
quoted
Why do you call _exit(2) through syscall(2)?  There's _exit(2).
Try calling _exit(your_favorite_exit_value) from within a sandbox, after
SANDBOX_CREATE_STRICT, on a late-vintage Ubuntu and Fedora box.  I'm pretty
sure we tried doing it the obvious way and seccomp didn't like it. If
necessary I could dig up the details.
Yes, those details would be very interesting.  I expect _exit(2) or 
_Exit(2) to be fine everywhere, since _Exit(2) was standardized in C99, 
and _exit(2) was standardized in POSIX.1-2001.

There are some differences between the system call (using syscall(2))
and the library function:

  C library/kernel differences
    The  text above in DESCRIPTION describes the traditional effect of
    _exit(), which is to terminate a process, and these are the seman‐
    tics specified by POSIX.1 and implemented by the C library wrapper
    function.  On  modern  systems,  this  means  termination  of  all
    threads in the process.

    By  contrast  with  the  C library wrapper function, the raw Linux
    _exit() system call terminates only the calling  thread,  and  ac‐
    tions  such  as  reparenting child processes or sending SIGCHLD to
    the parent process are performed only if this is the  last  thread
    in the thread group.

    Up  to  glibc 2.3, the _exit() wrapper function invoked the kernel
    system call of the same name.  Since glibc 2.3, the wrapper  func‐
    tion  invokes  exit_group(2),  in  order  to  terminate all of the
    threads in a process.

But I don't expect they would be meaningful here, and anyway, you 
probably prefer the semantics from the library call.
quoted
If I recall correctly this was one of several instances where seccomp's
behavior surprised us and made the code more weird.
This would be interesting to note somewhere.

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help