summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHauke Mehrtens2026-05-31 15:25:08 +0000
committerHauke Mehrtens2026-06-03 23:19:49 +0000
commit26dba5206e1721efb217f6e7bafa27cd225bb698 (patch)
treea10d9940eb1a55aeb91138dd4e85640cd08bb562
parent46fce7d5efc9c893d37aef47ec8389b0974ce7a9 (diff)
downloadrpcd-26dba5206e1721efb217f6e7bafa27cd225bb698.tar.gz
exec: prevent double close() of exec pipe descriptors
rpc_exec_process_cb() closes the stdout/stderr read descriptors after the child has exited, and rpc_exec_reply() closes them once more during teardown. ustream_free() neither closes nor resets the stored fd, so both code paths operate on the same descriptor number. In the window between the two closes the daemon may open another descriptor that reuses the freed number, which rpc_exec_reply() would then close by mistake. Reset the descriptors to -1 after closing them in the process callback so the later close() in rpc_exec_reply() becomes a harmless no-op. Assisted-by: Claude:claude-opus-4-8 Link: https://github.com/openwrt/rpcd/pull/34 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-rw-r--r--exec.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/exec.c b/exec.c
index 72533e0..7591be5 100644
--- a/exec.c
+++ b/exec.c
@@ -196,6 +196,12 @@ rpc_exec_process_cb(struct uloop_process *p, int stat)
close(c->opipe.fd.fd);
close(c->epipe.fd.fd);
+ /* ustream_free() does not reset the fd, and rpc_exec_reply() closes it
+ * again later. Mark the descriptors as consumed so that the second
+ * close() cannot accidentally close an unrelated, meanwhile reused fd. */
+ c->opipe.fd.fd = -1;
+ c->epipe.fd.fd = -1;
+
ustream_poll(&c->opipe.stream);
ustream_poll(&c->epipe.stream);
}