diff options
| author | Hauke Mehrtens | 2026-05-31 15:25:08 +0000 |
|---|---|---|
| committer | Hauke Mehrtens | 2026-06-03 23:19:49 +0000 |
| commit | 26dba5206e1721efb217f6e7bafa27cd225bb698 (patch) | |
| tree | a10d9940eb1a55aeb91138dd4e85640cd08bb562 | |
| parent | 46fce7d5efc9c893d37aef47ec8389b0974ce7a9 (diff) | |
| download | rpcd-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.c | 6 |
1 files changed, 6 insertions, 0 deletions
@@ -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); } |