summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulien Vuillaumier <julien.vuillaumier@nxp.com>2025-05-27 17:56:15 +0200
committerKieran Bingham <kieran.bingham@ideasonboard.com>2025-05-29 12:30:12 +0100
commit5b7c83d8ccd45f5ff533e6bed2001260c765dbb9 (patch)
tree3758332d09e952ff852d526906bad1954a5b4967
parent32905fdd0b63a10886dc43bd8d0a0b2e843de47b (diff)
libcamera: process: Pass stderr and reserve stdin and stdout fds
When a child process is started from Process::start(), the file descriptors inherited from the parent process are closed, except the ones explicitly listed in the fds[] argument. One issue is that the file descriptors for stdin, stdout and stderr being closed, the subsequent file descriptors created by the child process will reuse the values 0, 1 and 2 that are now available. Thus, usage of printf(), assert() or alike may direct its output to the new resource bound to one of these reused file descriptors. The other issue is that the child process can no longer log on the console because stderr has been closed. To address the 2 issues, Process:start() is amended as below: - Child process inherits from parent's stderr fd in order to share the same logging descriptor - Child process stdin, stdout and stderr fds are bound to /dev/null if not inherited from parent. That is to prevent those descriptors to be reused for any other resource, that could be corrupted by the presence of printf(), assert() or alike. Signed-off-by: Julien Vuillaumier <julien.vuillaumier@nxp.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
-rw-r--r--src/libcamera/process.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/src/libcamera/process.cpp b/src/libcamera/process.cpp
index 7f3a6518..d836fb07 100644
--- a/src/libcamera/process.cpp
+++ b/src/libcamera/process.cpp
@@ -259,7 +259,21 @@ int Process::start(const std::string &path,
if (isolate())
_exit(EXIT_FAILURE);
- closeAllFdsExcept(fds);
+ std::vector<int> v(fds);
+ v.push_back(STDERR_FILENO);
+ closeAllFdsExcept(v);
+
+ const auto tryDevNullLowestFd = [](int expected, int oflag) {
+ int fd = open("/dev/null", oflag);
+ if (fd < 0)
+ _exit(EXIT_FAILURE);
+ if (fd != expected)
+ close(fd);
+ };
+
+ tryDevNullLowestFd(STDIN_FILENO, O_RDONLY);
+ tryDevNullLowestFd(STDOUT_FILENO, O_WRONLY);
+ tryDevNullLowestFd(STDERR_FILENO, O_WRONLY);
const char *file = utils::secure_getenv("LIBCAMERA_LOG_FILE");
if (file && strcmp(file, "syslog"))