Skip to content

Commit 93f7320

Browse files
alexandruagalxiord
authored andcommitted
jailer: properly remove FD_CLOEXEC
We know first read the fd flags, unset the FD_CLOEXEC bit, and only then call fcntl with F_SETFD and the resulting flags. This is better than the old approach where we just set the fd flags to 0, which would have been fine only for as long as FD_CLOEXEC remains the only valid flag. Signed-off-by: Alexandru Agache <[email protected]>
1 parent bb43835 commit 93f7320

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

jailer/src/lib.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub enum Error {
3434
FileCreate(PathBuf, io::Error),
3535
FileName(PathBuf),
3636
FileOpen(PathBuf, io::Error),
37+
GetOldFdFlags(sys_util::Error),
3738
Gid(String),
3839
Metadata(PathBuf, io::Error),
3940
NotAFile(PathBuf),
@@ -161,14 +162,18 @@ pub fn run(args: JailerArgs) -> Result<()> {
161162
return Err(Error::UnexpectedListenerFd(listener_fd));
162163
}
163164

164-
// It turns out Rust is so safe, it opens everything with CLOSE_ON_EXEC.
165+
// It turns out Rust is so safe, it opens everything with FD_CLOEXEC, which we have to unset.
165166

166-
// TODO: So as of today (20180612), FD_CLOEXEC is the only file descriptor flag, so setting
167-
// flags to 0 should clear that and only that. Maybe at some point it would make sense to
168-
// get the flags first, clear FD_CLOEXEC, and set the resulting flags.
167+
// This is safe because we know fd and the cmd are valid.
168+
let mut fd_flags = unsafe { libc::fcntl(listener_fd, libc::F_GETFD, 0) };
169+
if fd_flags < 0 {
170+
return Err(Error::GetOldFdFlags(sys_util::Error::last()));
171+
}
172+
173+
fd_flags &= !libc::FD_CLOEXEC;
169174

170-
// This is safe because we know the fd is valid.
171-
if unsafe { libc::fcntl(listener_fd, libc::F_SETFD, 0) } < 0 {
175+
// This is safe because we know the fd, the cmd, and the last arg are valid.
176+
if unsafe { libc::fcntl(listener_fd, libc::F_SETFD, fd_flags) } < 0 {
172177
return Err(Error::UnsetCloexec(sys_util::Error::last()));
173178
}
174179

0 commit comments

Comments
 (0)