aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2026-05-13 12:32:26 +0100
committerRon Yorston <rmy@pobox.com>2026-05-13 12:32:26 +0100
commitbda604a70761e7791e5bfd00337bfc6f9e6ae640 (patch)
treead6dee6f25ce01989ea45e6dffbb224087552be4
parent4bc07f64b678e3e614e659d44b55ad1100d80d32 (diff)
downloadbusybox-w32-master.tar.gz
busybox-w32-master.tar.bz2
busybox-w32-master.zip
ash: prevent leakage of process handlesHEADmaster
When the shell invoked process substitution it retained a process handle to the child. These handles could accumulate without limit. The shell in upstream BusyBox doesn't bother to create a job structure for process substitutions or here documents. This isn't appropriate on Windows, where we need to track the child process handles. Create job structures as required. Saves 32-48 bytes. (GitHub issue #587)
Diffstat (limited to '')
-rw-r--r--shell/ash.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 0a63c434f..49556f256 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -6275,7 +6275,7 @@ forkshell(struct job *jp, union node *n, int mode)
6275static int 6275static int
6276write2pipe(int pip[2], const char *p, size_t len) 6276write2pipe(int pip[2], const char *p, size_t len)
6277{ 6277{
6278 IF_PLATFORM_MINGW32(struct forkshell fs); 6278 IF_PLATFORM_MINGW32(struct forkshell fs;)
6279 6279
6280 if (len <= PIPE_BUF) { 6280 if (len <= PIPE_BUF) {
6281 xwrite(pip[1], p, len); 6281 xwrite(pip[1], p, len);
@@ -6288,7 +6288,8 @@ write2pipe(int pip[2], const char *p, size_t len)
6288 fs.fd[0] = pip[0]; 6288 fs.fd[0] = pip[0];
6289 fs.fd[1] = pip[1]; 6289 fs.fd[1] = pip[1];
6290 fs.path = p; 6290 fs.path = p;
6291 spawn_forkshell(&fs, NULL, NULL, FORK_NOJOB); 6291 // We need a job to track the process handle.
6292 spawn_forkshell(&fs, makejob(1), NULL, FORK_NOJOB);
6292#else 6293#else
6293 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { 6294 if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
6294 /* child */ 6295 /* child */
@@ -7806,9 +7807,9 @@ evalbackcmd(union node *n, struct backcmd *result
7806 7807
7807 if (pipe(pip) < 0) 7808 if (pipe(pip) < 0)
7808 ash_msg_and_raise_perror("can't create pipe"); 7809 ash_msg_and_raise_perror("can't create pipe");
7809 /* process substitution uses NULL job, like openhere() */
7810 jp = (ctl == CTLBACKQ) ? makejob(1) : NULL;
7811#if ENABLE_PLATFORM_MINGW32 7810#if ENABLE_PLATFORM_MINGW32
7811 // We need a job to track the process handle.
7812 jp = makejob(1);
7812 memset(&fs, 0, sizeof(fs)); 7813 memset(&fs, 0, sizeof(fs));
7813 fs.fpid = FS_EVALBACKCMD; 7814 fs.fpid = FS_EVALBACKCMD;
7814 fs.n = n; 7815 fs.n = n;
@@ -7817,6 +7818,8 @@ evalbackcmd(union node *n, struct backcmd *result
7817 fs.fd[2] = ctl; 7818 fs.fd[2] = ctl;
7818 spawn_forkshell(&fs, jp, n, FORK_NOJOB); 7819 spawn_forkshell(&fs, jp, n, FORK_NOJOB);
7819#else 7820#else
7821 /* process substitution uses NULL job, like openhere() */
7822 jp = (ctl == CTLBACKQ) ? makejob(1) : NULL;
7820 if (forkshell(jp, n, FORK_NOJOB) == 0) { 7823 if (forkshell(jp, n, FORK_NOJOB) == 0) {
7821 /* child */ 7824 /* child */
7822 reset_exception_handler(); 7825 reset_exception_handler();