-
Notifications
You must be signed in to change notification settings - Fork 12
Avoid allocating in pre_exec closure
#109
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
Conversation
Signed-off-by: Alisa Sireneva <[email protected]>
f748ab2 to
031b2f8
Compare
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.
Code Review
This pull request correctly addresses a subtle but critical issue with memory allocation within a pre_exec closure, which could lead to deadlocks in a multi-threaded context. The fix is correct and effectively prevents this by using a non-allocating error conversion. My review includes a minor suggestion to improve code clarity and make the intent more explicit.
| Ok(rustix::process::set_parent_process_death_signal(Some( | ||
| rustix::process::Signal::TERM, | ||
| )) | ||
| .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e)) | ||
| ))?) |
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.
While the Ok(...?) pattern works correctly here because the success type is (), it can be a bit subtle. A more direct and idiomatic approach is to use map_err to handle the error conversion explicitly. This makes the intent of the code clearer to future readers.
rustix::process::set_parent_process_death_signal(Some(
rustix::process::Signal::TERM,
))
.map_err(Into::into)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.
consider: nuh-uh
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 kinda agree with this comment. That ? is carrying an awful lot of weight here, and it's not clear to me what implementation we're going to end up using or if it's going to allocate. A more explicit constructor (more explicit even than what the bot recommended) and comment that we're trying to avoid allocations would also be nice....
|
In balance, since What we really need here is some notion of "this API may allocate" as an annotation/effect on functions, then we could deny those in pre_exec. Or you know...rustix could have an allowlist of functions that are safe to call. Actually also we should try to add this pdeathsig as an extension to |
|
I'd love to see some variation on pdeathsig in I'm not opposed to using |
Error::newallocates memory (see rust-lang/rust#148971). This is bad in multi-threaded programs, andcontainers-image-proxy-rsis a library which can be used in such. If the fork occurs while the allocator lock is held by another thread, deadlocks can occur, since there's no one left in the new process to unlock the mutex. I do not believe this is UB, and modern libc offer protections against this issue, but this isn't POSIX-compliant and should preferably be avoided.rustixprovides a non-allocatingimpl From<Errno> for std::io::Error, use it instead. This also ensures the correct error code is forwarded to the parent process, instead of the default-EINVAL.