From aecd620a087e1550e951d3089e51e5723e2b59f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Sj=C3=B6lund?= Date: Sun, 15 Feb 2026 13:10:40 +0100 Subject: [PATCH] libcrun: document vfork shared error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are examples in the source code where the vfork parent process reuses an error created by the vfork child process. Document that there is no need to create an error in the parent process in such cases. Related issue: https://github.com/containers/crun/issues/2015 Incorporate a suggestion from gemini-code-assist in https://github.com/containers/crun/pull/2018 Signed-off-by: Erik Sjölund --- src/libcrun/linux.c | 7 +++++++ src/libcrun/net_device.c | 11 +++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libcrun/linux.c b/src/libcrun/linux.c index 34c3a140c4..9f4a38a317 100644 --- a/src/libcrun/linux.c +++ b/src/libcrun/linux.c @@ -6198,17 +6198,21 @@ run_in_container_namespace (libcrun_container_status_t *status, int (*callback) ret = setns (pidfd, CLONE_NEWNS); if (UNLIKELY (ret < 0)) { + /* Create an error for the parent proc. */ crun_make_error (err, 0, "setns to target pid"); _safe_exit (ret); } ret = chdir ("/"); if (UNLIKELY (ret < 0)) { + /* Create an error for the parent proc. */ crun_make_error (err, errno, "chdir to `/`"); _safe_exit (ret); } ret = callback (arg, err); + /* On failure (ret < 0) the created error will be + used by the parent proc */ _safe_exit (ret); } @@ -6216,6 +6220,9 @@ run_in_container_namespace (libcrun_container_status_t *status, int (*callback) if (UNLIKELY (ret < 0)) return crun_make_error (err, errno, "waitpid for exec child pid"); + /* The vfork() child shares the parent's memory space, so the error + object populated by the child is available to the parent. + Do not call crun_make_error() here. */ return get_process_exit_status (wait_status); } diff --git a/src/libcrun/net_device.c b/src/libcrun/net_device.c index df3dbf4897..8c5b54f039 100644 --- a/src/libcrun/net_device.c +++ b/src/libcrun/net_device.c @@ -474,7 +474,10 @@ move_network_device (const char *ifname, const char *newifname, int netns_fd, li { ret = setup_network_device_in_ns_helper (buffer, buffer_size, netns_fd, newifname, ips, err); if (UNLIKELY (ret < 0)) - _safe_exit (-ret); + { + /* Do not release the error as it will be used by the parent proc. */ + _safe_exit (-ret); + } _safe_exit (0); } @@ -484,7 +487,11 @@ move_network_device (const char *ifname, const char *newifname, int netns_fd, li return crun_make_error (err, errno, "waitpid for exec child pid"); if (wait_status != 0) - return -get_process_exit_status (wait_status); + { + /* Reuse the error from the child proc. + In other words, do not call crun_make_error() here. */ + return -get_process_exit_status (wait_status); + } return 0; }