Skip to content

Commit e07cbdf

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[dart:io] Use close_range when available during process spawning.
TEST=ci Bug: #60252 Change-Id: Ibfb6fa3d6dc8aff482db5178acb4caa35583fc3f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426906 Reviewed-by: Siva Annamalai <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent aa0a29c commit e07cbdf

File tree

1 file changed

+29
-38
lines changed

1 file changed

+29
-38
lines changed

runtime/bin/process_linux.cc

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,27 @@ static bool PathInNamespace(char* realpath,
282282
return true;
283283
}
284284

285+
// Linux 5.9, glibc 2.34.
286+
extern "C" int close_range(unsigned int first, unsigned int last, int flags)
287+
__attribute__((weak));
288+
289+
void CloseAllButStdioAndExecControl(int exec_control_fd) {
290+
if (&close_range != nullptr) {
291+
close_range(3, exec_control_fd - 1, 0);
292+
close_range(exec_control_fd + 1, ~0u, 0);
293+
} else {
294+
int max_fds = sysconf(_SC_OPEN_MAX);
295+
if (max_fds == -1) {
296+
max_fds = _POSIX_OPEN_MAX;
297+
}
298+
for (int fd = 3; fd < max_fds; fd++) {
299+
if (fd != exec_control_fd) {
300+
close(fd);
301+
}
302+
}
303+
}
304+
}
305+
285306
class ProcessStarter {
286307
public:
287308
ProcessStarter(Namespace* namespc,
@@ -644,63 +665,33 @@ class ProcessStarter {
644665
void SetupDetached() {
645666
ASSERT(mode_ == kDetached);
646667

647-
// Close all open file descriptors except for exec_control_[1].
648-
int max_fds = sysconf(_SC_OPEN_MAX);
649-
if (max_fds == -1) {
650-
max_fds = _POSIX_OPEN_MAX;
651-
}
652-
for (int fd = 0; fd < max_fds; fd++) {
653-
if (fd != exec_control_[1]) {
654-
close(fd);
655-
}
656-
}
657-
658-
// Re-open stdin, stdout and stderr and connect them to /dev/null.
659-
// The loop above should already have closed all of them, so
660-
// creating new file descriptors should start at STDIN_FILENO.
668+
// Connect stdin, stdout and stderr to /dev/null.
661669
int fd = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR));
662-
if (fd != STDIN_FILENO) {
670+
if (TEMP_FAILURE_RETRY(dup2(fd, STDIN_FILENO)) != STDIN_FILENO) {
663671
ReportChildError();
664672
}
665-
if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDOUT_FILENO)) !=
666-
STDOUT_FILENO) {
673+
if (TEMP_FAILURE_RETRY(dup2(fd, STDOUT_FILENO)) != STDOUT_FILENO) {
667674
ReportChildError();
668675
}
669-
if (TEMP_FAILURE_RETRY(dup2(STDIN_FILENO, STDERR_FILENO)) !=
670-
STDERR_FILENO) {
676+
if (TEMP_FAILURE_RETRY(dup2(fd, STDERR_FILENO)) != STDERR_FILENO) {
671677
ReportChildError();
672678
}
679+
680+
CloseAllButStdioAndExecControl(exec_control_[1]);
673681
}
674682

675683
void SetupDetachedWithStdio() {
676-
// Close all open file descriptors except for
677-
// exec_control_[1], write_out_[0], read_in_[1] and
678-
// read_err_[1].
679-
int max_fds = sysconf(_SC_OPEN_MAX);
680-
if (max_fds == -1) {
681-
max_fds = _POSIX_OPEN_MAX;
682-
}
683-
for (int fd = 0; fd < max_fds; fd++) {
684-
if ((fd != exec_control_[1]) && (fd != write_out_[0]) &&
685-
(fd != read_in_[1]) && (fd != read_err_[1])) {
686-
close(fd);
687-
}
688-
}
689-
690684
if (TEMP_FAILURE_RETRY(dup2(write_out_[0], STDIN_FILENO)) == -1) {
691685
ReportChildError();
692686
}
693-
close(write_out_[0]);
694-
695687
if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
696688
ReportChildError();
697689
}
698-
close(read_in_[1]);
699-
700690
if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
701691
ReportChildError();
702692
}
703-
close(read_err_[1]);
693+
694+
CloseAllButStdioAndExecControl(exec_control_[1]);
704695
}
705696

706697
int CleanupAndReturnError() {

0 commit comments

Comments
 (0)