From nobody Mon Nov 17 18:33:09 2025 X-Original-To: dev-commits-src-all@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 4d9GZs5CRVz6Gjd5; Mon, 17 Nov 2025 18:33:09 +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 "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4d9GZs4N6vz3wbG; Mon, 17 Nov 2025 18:33:09 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1763404389; 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=BRgZA7EmQhuhAPKKUwAdlwJZhGaYGDkbe8IrqswAzzs=; b=P2kiuxpyC2qBmBgLKAWo908NM2sqAaB56yTNdFKRSj0iR2fPN3pMmRRj0yQ94VLr1kePkw vb1zqr7elNWognLEUpSJAOt1tw+TWxlvMfDJGzxaASj/MFjJ97Q97TCQbmXF1n13vR4YOI p/R23Jlxfko3LOOJvWaFGLpq/A2AoweCvVwe88vjss61mHJyjxqJcmGPzhM1AIG0s4EJlT aw7XtAiPjkeQiKA5RCiF39GAJEqk2+4issgtg7fqmIHfPm1yNjpitMjbUlXpwvhuZBaxMV n3309AhTAScRLBsGuiZ4dGVFxsFKTHeshJY3mcBJ00cREWdXGs+fu3IS1v7KGw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1763404389; 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=BRgZA7EmQhuhAPKKUwAdlwJZhGaYGDkbe8IrqswAzzs=; b=j715JTiUB0q75xt21YbdV5LiEDr+qaTIeDA/uRfFdre4XqaPGSTDeuH7fZa+eDfSLmzzQV FugC0hgB6zjLPfLKbvMA1TXIcZzLlcGeT2Xx2CfuOotbsa02Geu3F7NKTmCz9yC2k+a1yK RR/qPa5VH4pNgDZ5J5RuVRF1aBRYI53B1l7KCFRZNkkhC+hpzdBRizufl0qpHXsBFVqfh8 hrUs00qr1yM5yrfPZ36iOm/3x597N23pFi5PHjbY0dJS1mBnxoMVDle5UTYs4jBsZ97UKF wiT4fDkNtyvQwMPN29oEYjsF13i5RtVHZct+bV9dcJ9+N3SGOOjSZcRkMdtnhA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1763404389; a=rsa-sha256; cv=none; b=Tg1ReIMs1amMH/wkqOrO/3p6qJi/WW9krywiFuynHlVADTPmkZ1amJhfsDP8fXqXPDdWWh n152QkNy6xwToQywn4HVwWYsY8zQxjLHgpMGPeozBFBZPRmcWi06/J5OBZyHEhEwzhFl2p CHMLgzI3mHjQ8rQq8HtUMt4s1UvPL7Y4+YR9HZVkgz42G+0WgkacJQWIxhJwfDQ6z1qbah dPLyl2cagtJoEJ4c5nPgBjlBk15pDuB3xMH+Z3SqUFEpTMtX3UFbkk9H5d1HnVClFmbg27 B8JpRERphU2uszxv6QNq62LI+9WddjXmzanWIozXvEvtaIwJvzDeIrS5CO7K8A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (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 did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4d9GZs3qwRz4GK; Mon, 17 Nov 2025 18:33:09 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 5AHIX96m033112; Mon, 17 Nov 2025 18:33:09 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 5AHIX9Cr033109; Mon, 17 Nov 2025 18:33:09 GMT (envelope-from git) Date: Mon, 17 Nov 2025 18:33:09 GMT Message-Id: <202511171833.5AHIX9Cr033109@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Jilles Tjoelker Subject: git: 75a6c38e4d5c - main - sh: Fix a double free in a rare scenario with pipes List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@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/main X-Git-Reftype: branch X-Git-Commit: 75a6c38e4d5c651b7398bf2bea5baa41a0939e92 Auto-Submitted: auto-generated The branch main has been updated by jilles: URL: https://cgit.FreeBSD.org/src/commit/?id=75a6c38e4d5c651b7398bf2bea5baa41a0939e92 commit 75a6c38e4d5c651b7398bf2bea5baa41a0939e92 Author: Jilles Tjoelker AuthorDate: 2025-11-15 16:43:03 +0000 Commit: Jilles Tjoelker CommitDate: 2025-11-17 18:32:38 +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 --- 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 1328ae50edef..0aaff5e1e140 100644 --- a/bin/sh/jobs.c +++ b/bin/sh/jobs.c @@ -573,6 +573,7 @@ waitcmdloop(struct job *job) freejob(job); else { job->remembered = 0; + deljob(job); if (job == bgjob) bgjob = NULL; } @@ -599,7 +600,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 7fdecb23c817..407d2aeaa061 100644 --- a/bin/sh/tests/builtins/Makefile +++ b/bin/sh/tests/builtins/Makefile @@ -188,5 +188,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 ]