From nobody Sun Feb 1 21:08:41 2026 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4f42RF3Vzfz6Qfgc for ; Sun, 01 Feb 2026 21:08:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R13" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4f42RF2rWJz4P5c for ; Sun, 01 Feb 2026 21:08:41 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1769980121; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7Q7qf7SjO8iVMNDLLy5DzVuncljmsRcNQfX4t+aCR5g=; b=aRmv+AEjeS2KM43pJFi0w1h6p0iW2j/Deu2HNGRXQ9H84HmJQM3l2bC/so0kADxYVgwsUF jwC4cGYIr5B3nURO23rvhNtlPNCyHHzf9aRyTrLq/Nt4PWvHWvgWhCJUqD/ZxAxsAZ/WUt r3l2++P1Wqm/qHLHDjqw88TTSoUEYm3MJObh57RiEVYmTofq0ONJe/oLy/B1Wr2V25exqc 3Moe64/+cUqiyMsCrbjrEm2LouRnT/XEYnHOIHUVPKqTjeo6gLaOOwRmDBxfqc3I6wk04/ xkQfl03crM+wAeOJm+xrxHqisrMGwyIWBmRmObrFALvJdFnYrjAciMP7ProSoQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1769980121; a=rsa-sha256; cv=none; b=N4xUHMXvf0fnM1bMzSNuLanNk21sn74tjfgfBkw8g2IQLbMM3yn0ZeYagjao6gwsN5LshL tpVM1iUIDEWE3r82si0d58Fijm4zXN2D8yumP7DW0hJQ13+OclqzaMacw2OyoMym69ycvH MvJ0Xjin6T84WxWLM5MI/tByiZL3lOVRAWg7UFuIeW6vInDOyUtolHJ0LP99gXCFCAX1tK HPgTi/I2q6V4TXSRDUMXUr2cPOYIbqk/fzziJCszgP17lCqBxrp7drKz1Hph4zGO4YdoHr arc2wqd1vH9tOXwxCpbHq0DSTgiGRu56gVjzcbCJgFXpkwArgvbAkbqr1X3qlQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1769980121; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=7Q7qf7SjO8iVMNDLLy5DzVuncljmsRcNQfX4t+aCR5g=; b=B9M816Hj4iy9N6ckpuJHiHZwGpJreQm7iUNeXauU/uILiRw/7jCkG2sZ0dxwVDzK4RXWdb tyeVrrj3mCb5BVEs/Dnv8/4ZdYZ3jdQBYxBECIcqhY9zKxCMsiOx+E1djuWwUlCHV3V5ND QK94uYaoAOIQ5+aAEIMiQVROzvVMYyauiNfvs3QfiA1dAvY7CLKN6SjtUVMdjQyDS/ConP rwBeU5XmNCCU+by+TJbRc/h3377wEpVE8nAZaQTTIeSqrMYdznyGcW8HFI/qki6rqFK9hV Gj/GwouP49rXHHPnbYuXMrca5wmAFBF4VwxnMMT675Zbwynz9I8o1qyMnmOeEg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4f42RF2P6Nzx4q for ; Sun, 01 Feb 2026 21:08:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 39aed by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 01 Feb 2026 21:08:41 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Jilles Tjoelker Subject: git: b9cdb4d34bc4 - stable/13 - sh: Fix a double free in a rare scenario with pipes List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jilles X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: b9cdb4d34bc4ea0093597f2bc4a86ce6ed5ab569 Auto-Submitted: auto-generated Date: Sun, 01 Feb 2026 21:08:41 +0000 Message-Id: <697fc0d9.39aed.3d922c8a@gitrepo.freebsd.org> The branch stable/13 has been updated by jilles: URL: https://cgit.FreeBSD.org/src/commit/?id=b9cdb4d34bc4ea0093597f2bc4a86ce6ed5ab569 commit b9cdb4d34bc4ea0093597f2bc4a86ce6ed5ab569 Author: Jilles Tjoelker AuthorDate: 2025-11-15 16:43:03 +0000 Commit: Jilles Tjoelker CommitDate: 2026-02-01 14:35:54 +0000 sh: Fix a double free in a rare scenario with pipes The command sh -c 'sleep 3 | sleep 2 & sleep 3 & kill %1; wait %1' crashes (with appropriate sanitization such as putting MALLOC_CONF=abort:true,junk:true in the environment or compiling with -fsanitize=address). What happens here is that waitcmdloop() calls dowait() with a NULL job pointer, instructing dowait() to freejob() if it's a non-interactive shell and $! was not and cannot be referenced for it. However, waitcmdloop() then uses fields possibly freed by freejob() and calls freejob() again. This only occurs if the job being waited for is identified via % syntax ($! has never been referenced for it), it is a pipeline with two or more elements and another background job has been started before the wait command. That seems special enough for a bug to remain. Test scripts written by Jilles would almost always use $! and not % syntax. We can instead make waitcmdloop() pass its job pointer to dowait(), fixing up things for that (waitcmdloop() will have to call deljob() if it does not call freejob()). The crash from https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=290330#c2 appears to be the same bug. PR: 290330 Reported by: bdrewery Reviewed by: bdrewery Differential Revision: https://reviews.freebsd.org/D53773 (cherry picked from commit 75a6c38e4d5c651b7398bf2bea5baa41a0939e92) --- bin/sh/jobs.c | 3 ++- bin/sh/tests/builtins/Makefile | 1 + bin/sh/tests/builtins/wait11.0 | 6 ++++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c index e7d14158b555..d5d8ca978bb5 100644 --- a/bin/sh/jobs.c +++ b/bin/sh/jobs.c @@ -579,6 +579,7 @@ waitcmdloop(struct job *job) freejob(job); else { job->remembered = 0; + deljob(job); if (job == bgjob) bgjob = NULL; } @@ -603,7 +604,7 @@ waitcmdloop(struct job *job) break; } } - } while (dowait(DOWAIT_BLOCK | DOWAIT_SIG, (struct job *)NULL) != -1); + } while (dowait(DOWAIT_BLOCK | DOWAIT_SIG, job) != -1); sig = pendingsig_waitcmd; pendingsig_waitcmd = 0; diff --git a/bin/sh/tests/builtins/Makefile b/bin/sh/tests/builtins/Makefile index 5ad9216b4da0..a0c92a78664e 100644 --- a/bin/sh/tests/builtins/Makefile +++ b/bin/sh/tests/builtins/Makefile @@ -186,5 +186,6 @@ ${PACKAGE}FILES+= wait7.0 ${PACKAGE}FILES+= wait8.0 ${PACKAGE}FILES+= wait9.127 ${PACKAGE}FILES+= wait10.0 +${PACKAGE}FILES+= wait11.0 .include diff --git a/bin/sh/tests/builtins/wait11.0 b/bin/sh/tests/builtins/wait11.0 new file mode 100644 index 000000000000..d5fab26fb677 --- /dev/null +++ b/bin/sh/tests/builtins/wait11.0 @@ -0,0 +1,6 @@ +sleep 3 | sleep 2 & +sleep 3 & +kill %1 +wait %1 +r=$? +[ "$r" -gt 128 ] && [ "$(kill -l "$r")" = TERM ]