From 2081f66ad07722ba9a808fa4f0d2ced2822950f7 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Fri, 28 Jun 2024 13:20:29 +0200 Subject: executor: fix max signal/cover filter mapping into subprocesses There is a quirk related to posix_spawn_file_actions_adddup2: it just executes the specified dup's in order in the child process. In our case we do dups as follows: 20 -> 4 (output region) 4 -> 5 (max signal) So we dup the output region onto 4 first, and then dup the same output region (fd 4 becomes the output region) onto 5 (max signal). So we have output region as both output region and max signal. --- executor/subprocess.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'executor/subprocess.h') diff --git a/executor/subprocess.h b/executor/subprocess.h index 4477cc482..2553422a9 100644 --- a/executor/subprocess.h +++ b/executor/subprocess.h @@ -17,9 +17,17 @@ public: if (posix_spawn_file_actions_init(&actions)) fail("posix_spawn_file_actions_init failed"); int max_fd = 0; - for (auto pair : fds) { + for (auto pair : fds) max_fd = std::max(max_fd, pair.second); + for (auto pair : fds) { if (pair.first != -1) { + // Remapping won't work if fd's overlap with the target range: + // we can dup something onto fd we need to dup later, in such case the later fd + // will be wrong. Resolving this would require some tricky multi-pass remapping. + // So we just require the caller to not do that. + if (pair.first <= max_fd) + failmsg("bad subprocess fd", "%d->%d max_fd=%d", + pair.first, pair.second, max_fd); if (posix_spawn_file_actions_adddup2(&actions, pair.first, pair.second)) fail("posix_spawn_file_actions_adddup2 failed"); } else { -- cgit mrf-deployment