From aa8a5cd47475aba84f65bb58892b618bfa76580b Mon Sep 17 00:00:00 2001 From: Jindrich Novy Date: Wed, 29 Oct 2025 19:23:34 +0100 Subject: [PATCH] Fix sync_pipe_fd validation and add missing error reporting This commit addresses multiple issues related to sync_pipe_fd handling: 1. Change sync_pipe_fd checks from > 0 to >= 0 to properly handle the case where file descriptor 0 is used for the sync pipe. 2. Add missing error reporting in terminal_accept_cb() when receiving the console file descriptor fails. Previously, conmon would call pexit() directly, exiting without writing to sync_pipe_fd. This caused podman to receive empty data and show JSON parse errors. 3. Add missing error reporting when pidfile read fails. Previously, if g_file_get_contents() failed to read the container pidfile, conmon would exit(1) without writing to sync_pipe_fd, causing podman to receive empty data and show JSON parse errors. This fix ensures that when the runtime fails (e.g., due to missing cgroup controllers), conmon properly reports the error to podman instead of silently closing the pipe. Fixes: https://github.com/containers/podman/issues/27335 Signed-off-by: Jindrich Novy --- src/conmon.c | 6 ++++-- src/ctrl.c | 6 +++++- src/parent_pipe_fd.c | 7 +++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/conmon.c b/src/conmon.c index 1b225d41..248ebcf1 100644 --- a/src/conmon.c +++ b/src/conmon.c @@ -378,7 +378,7 @@ int main(int argc, char *argv[]) error_msg = buf; } /* Always report failure to parent, even if we couldn't read stderr */ - if (sync_pipe_fd > 0) { + if (sync_pipe_fd >= 0) { int to_report = -1; if (opt_exec && container_status > 0) { to_report = -1 * container_status; @@ -389,7 +389,7 @@ int main(int argc, char *argv[]) } if (opt_terminal && mainfd_stdout == -1) { - if (sync_pipe_fd > 0) + if (sync_pipe_fd >= 0) write_or_close_sync_fd(&sync_pipe_fd, -1, "Runtime did not set up terminal"); nexit("Runtime did not set up terminal"); } @@ -398,6 +398,8 @@ int main(int argc, char *argv[]) _cleanup_free_ char *contents = NULL; if (!g_file_get_contents(opt_container_pid_file, &contents, NULL, &err)) { nwarnf("Failed to read pidfile: %s", err->message); + if (sync_pipe_fd >= 0) + write_or_close_sync_fd(&sync_pipe_fd, -1, err->message); exit(1); } diff --git a/src/ctrl.c b/src/ctrl.c index c525b3ae..539ac0f5 100644 --- a/src/ctrl.c +++ b/src/ctrl.c @@ -9,6 +9,7 @@ #include "cmsg.h" #include "cli.h" // opt_bundle_path #include "seccomp_notify.h" +#include "parent_pipe_fd.h" #include #include @@ -47,7 +48,10 @@ gboolean terminal_accept_cb(int fd, G_GNUC_UNUSED GIOCondition condition, G_GNUC struct file_t console = recvfd(connfd); if (console.fd < 0) { - pexit("Failed to receive console file descriptor"); + if (sync_pipe_fd >= 0) { + write_or_close_sync_fd(&sync_pipe_fd, -1, "Failed to receive console file descriptor"); + } + nexit("Failed to receive console file descriptor"); } ndebugf("console = {.name = '%s'; .fd = %d}", console.name, console.fd); diff --git a/src/parent_pipe_fd.c b/src/parent_pipe_fd.c index 733dc8e6..4858e513 100644 --- a/src/parent_pipe_fd.c +++ b/src/parent_pipe_fd.c @@ -39,8 +39,9 @@ void write_or_close_sync_fd(int *fd, int res, const char *message) ssize_t len; - if (*fd == -1) + if (*fd == -1) { return; + } _cleanup_free_ char *json = NULL; if (message && strlen(message) > 0) { @@ -62,8 +63,10 @@ void write_or_close_sync_fd(int *fd, int res, const char *message) } len = strlen(json); - if (write_all(*fd, json, len) != len) { + ssize_t written = write_all(*fd, json, len); + if (written != len) { if (errno == EPIPE) { + nwarnf("Got EPIPE when writing to sync_pipe_fd, closing it"); close(*fd); *fd = -1; return;