Skip to content

Commit de5c38c

Browse files
committed
CA-208547: Avoid races in pointing stdin/stdout/stderr at /dev/null
The two calls to Unix.dup are intended to point stdout and stderr at /dev/null - this will normally be the case, as Unix.dup will open the next available file descriptor and stdout/stderr have just been closed. However, there are many ways this can go wrong - if an open() happens in another thread it could mean that... * nullfd <> Unix.stdin - this is checked for, but there is no error handling if this fails * one or both of the Unix.dup calls do not point stdout/stderr at /dev/null as intended, but instead open new file descriptors. This change instead uses Unix.dup2 which atomically closes the second file descriptor and copies it from the first. This also allows the explicit calls to Unix.close to be removed. Finally, nullfd is closed as it is not needed after the calls to Unix.dup2. Signed-off-by: John Else <[email protected]>
1 parent e977fa9 commit de5c38c

File tree

1 file changed

+4
-6
lines changed

1 file changed

+4
-6
lines changed

lib/xcp_service.ml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -554,13 +554,11 @@ let daemonize ?start_fn () =
554554
Unix.chdir "/";
555555
mkdir_rec (Filename.dirname !pidfile) 0o755;
556556
pidfile_write !pidfile;
557-
Unix.close Unix.stdin;
558-
Unix.close Unix.stdout;
559-
Unix.close Unix.stderr;
560557
let nullfd = Unix.openfile "/dev/null" [ Unix.O_RDWR ] 0 in
561-
assert (nullfd = Unix.stdin);
562-
let (_:Unix.file_descr) = Unix.dup nullfd in ();
563-
let (_:Unix.file_descr) = Unix.dup nullfd in ();
558+
Unix.dup2 nullfd Unix.stdin;
559+
Unix.dup2 nullfd Unix.stdout;
560+
Unix.dup2 nullfd Unix.stderr;
561+
Unix.close nullfd
564562
| _ -> exit 0)
565563
| _ -> exit 0
566564

0 commit comments

Comments
 (0)