golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.97k stars 17.53k forks source link

syscall: synchronization between clone() and execve() #14180

Open stefanberger opened 8 years ago

stefanberger commented 8 years ago

I would like to see a synchronization primitive to be added between the clone() and the execve() call in the function forkAndExecInChild here https://golang.org/src/syscall/exec_linux.go so that the parent can setup the child after the clone() but before the execve().

ianlancetaylor commented 8 years ago

I assume you mean a callback that is executed in the child context. That is not going to happen. There is almost nothing that can be safely done in the child context. You can not allocate memory. You can not start a goroutine. You can call almost none of the functions in the syscall package. Instead our procedure has been that for things that have to happen between clone and exec in the child, we add entries to syscall.SysProcAttr.

I'm going to close this, but please feel free to reopen if you meant something else. An example would help.

minux commented 8 years ago

This has been asked numerous times in the past. It's no safe to execute arbitrary Go code between fork (clone) and exec.

And the actual requirements for different Go versions might be different, so we can't add a hook there and document what it could do and couldn't.

What do you want to do between fork and exec?

stefanberger commented 8 years ago

I am working on namespacing the Linux integrity measurement architecture. Here a new IMA namespace will be created as part of the clone(). We intend to hook up a virtual TPM (TPM emulator) to the IMA namespace but have to do this after the clone() and before the execve(). The problem with the execve() is that it creates 'measurements' and these measurements will be extended into a PCR of the TPM emulator. So the hook-up of the vTPM with the IMA-namespace has to be done by the parent before the child executes the execve(). I initially wrote 'callback' in the title but removed that. It likely would not work so well, so a synchronization primitive, such as two pipes, could be used to indicate to the parent that it can do its job and then indicate to the child that it can proceed. As stated, we would like to be able to execute code in the parent before the child runs the execve().

ianlancetaylor commented 8 years ago

Thanks for the description. It sounds like it would be sufficient to add a descriptor to syscall.SysProcattr, and for the child to read a byte from that descriptor before calling exec. I think that could be implemented.

stefanberger commented 8 years ago

:-) A single pipe will do .

jessfraz commented 7 years ago

I think this should be ok once #20676 is in?