From nobody Sun Feb 1 14:34:28 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 4f3shP0Sqpz6QRhw for ; Sun, 01 Feb 2026 14:34:29 +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 4f3shN4hsfz3Ryx for ; Sun, 01 Feb 2026 14:34:28 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1769956468; 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=Cj3oHemc+t639w/v3bnmaF5sHw/tIS1wbKfT8GDR7Io=; b=KNL6bPz2Cy+ApwyoFbrUxf3S/DRIrvrbuhRWADOmewR6bMIS16J17Ah1WwY8HbjqcHuZCb Ozwy7nPSxojiJOU9CwZtUQtIJc9V28nabik2AqXJSNSGkmodOl8vHGIZLgw9a1yA5aLvJS nkUSDsSiUHYLY60ld9Qfomt1/vZBnQBCcdlSy+3NeOr0cQSijJgPsGHtmO9D3XTRlnQsE6 daQSRmUqAIYeBmGFRWrj/D0UQ3dZSVrd149zTI4lGtcyXKq9yj2MCe2BhiBBIY++ndhI82 kbTMdIag6sF9njLY3Bb+U40PeqQquV9tiXTUH2QtfAI0RoUFd+vwFeoteJ5K1A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1769956468; a=rsa-sha256; cv=none; b=G+Vy7tQtQHgWN2e71VCGru/nyU3jCtqhDTVI+oBtWunVxgw/QkK1DeA6dCVFjdDPf6oQke n5pdrsbLQWFnqFG0+UM05tntlv3jFGLz3JbxUApR+j5C+XzG1tkght9GJP8IYgfEkkPj0u TvAHL2PyQFCOnd8IWjOzNtvafdd7uIxGuIwyK3VgUluCc9r4KYtT/4Y4LNwNhGNhYwg/Z/ pqOuKIbo58+cZ5mm8wKAiKwG8DgS/fFmfjY0uVoMaUE7Agc1d6LWH5ivAwvgPbnApcY1Kd uV3I4SNRnn/Q051ocGqgGc0qIdobw0j0XHkpgRieuvzh2xhG+X1OG8skdGCFuA== 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=1769956468; 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=Cj3oHemc+t639w/v3bnmaF5sHw/tIS1wbKfT8GDR7Io=; b=sAmo9ZgTOdad6TfDcgzMOmZX8DS5QSRWpc9tp+Hr41zFCR3M5bPlpJZMTt/Lh71bGwtp6V brpvVvzkqk0bFk4Kh4gbTXBKK6Y2Xpg1VCgKPJlJ1IhnSroWn9slEaj5Fy4kxvyYLqR5eu 8QQpHZ1whvwCNAl9zw5fAry7RaUb0lz6VuQwmacmP8BUsnz/v1rCpb+92Y+Io79vpUFAFD sHE5LP7R0Q6GT8GfwyLQy0Ph83QyEcSUunWkcZyMo+K4a8I/ztVn0gTP53Ux6mDHS0O7oA B9CbOtcBDI7utZUdFCrifncvFoHSss1pxUCz3MkUFIh/6xtXlWqTeChTTFNujg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4f3shN3Tzkzl24 for ; Sun, 01 Feb 2026 14:34:28 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 38030 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 01 Feb 2026 14:34:28 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Jilles Tjoelker Subject: git: c0dcdc3decb4 - stable/14 - 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/14 X-Git-Reftype: branch X-Git-Commit: c0dcdc3decb413af6188da624b22aa6b45126317 Auto-Submitted: auto-generated Date: Sun, 01 Feb 2026 14:34:28 +0000 Message-Id: <697f6474.38030.18fdd050@gitrepo.freebsd.org> The branch stable/14 has been updated by jilles: URL: https://cgit.FreeBSD.org/src/commit/?id=c0dcdc3decb413af6188da624b22aa6b45126317 commit c0dcdc3decb413af6188da624b22aa6b45126317 Author: Jilles Tjoelker AuthorDate: 2025-11-15 16:43:03 +0000 Commit: Jilles Tjoelker CommitDate: 2026-02-01 14:33:50 +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 47835cb1b5b2..3c34897a803c 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; } @@ -605,7 +606,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 56de5e57732b..cb05ee6c7d34 100644 --- a/bin/sh/tests/builtins/Makefile +++ b/bin/sh/tests/builtins/Makefile @@ -189,5 +189,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 ]