From nobody Thu Aug 13 15:29:53 2026 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 4hLTnM4C2Cz6nrDG for ; Thu, 13 Aug 2026 15:29:59 +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 "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hLTnM1GY0z3HDX for ; Thu, 13 Aug 2026 15:29:59 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786634999; 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=+Z1boxfrt7aLEXl9smeJJz7o5X+RoHd0y1Ja0cBEvjo=; b=yCxoPNmJ8DDY8aBmaVOVAbVZaB2PuKk7aPugHSki9tiqDn/61TVDBjnZfknsEQ8xnGCgIy WiTxBBlMs79ZDXeBn+mZ6oP9xhk8repSd7v/zKFdhIiTqlAK9i2rHSybx7n3q/46ovP5r4 NQ0haWL+jpvo1yY8P/3p2RABELtfbmulvwPz5HWRTPk6dXNH0Tl9PbKkuXg0o4syZa2Frr ywNct0NHXBlYlaqhtGZjZzBi9y+HQeChtI0vSx+TJ53BcEVnGQPrO8obDSAUEmGGlPhXUJ FS0aMzHcgN/VRDi8BZ/GzdJCfl7VngPRigiDupttMZzSpYta6zVnWAOxKiEDnA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786634999; a=rsa-sha256; cv=none; b=xoOAaBfLVy6CnANjpo4RcJbSigo4G3SlQwOg5yiF+auSTMa9BG45QeATD0Nf4GMGDGT981 FI8eK3vqbtqIil9vj3hD7Qg4CHbwdJ06kvMM3etLfEO2mp5MELUXdxjIIItoEi1uCElpO8 qSrXfWodxkxAroB9SgzytWyfnMTLLDk+S1O9XCvAjGwCmItdTNaSumAA8H+ZTDZ6IQBoQb YBla0ZrSlTBTz8eBqHFpMUNJiPN85bj+nl0qBh0kkSJ7I8oUWw07+vHNnOQrzoVVCUQyyN 6uLhhDkImQPoZ0Vl6uOUgcNfAI0rPYowxqHVrMzvIY3XNLzzO6Cik1efyVrF8Q== 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=1786634999; 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=+Z1boxfrt7aLEXl9smeJJz7o5X+RoHd0y1Ja0cBEvjo=; b=r4RCSts0pwqhSecQUzVWnSohLJbdRvyyHJE6KyMX/bIKq5ZSz1ki+N0VhwiAvWOto0L2f4 uSgPtHOiiBCFb83hx2g92QVOaAJfVr3pWrgNp/2zOQRv172rJVxEoK+Cpgi07h8Ofyrwfg lDAoSec8K0Z66JnxBkHvBA4LNyKHbl7nSXCn79auRJrc1rrACUDdCRf46S9iEWdYGG9ouv RcAXWVYIKtHrA8wedU8iUC3dqWGHSc3KmGVQJ5IHwb1d9hry3aPRvFzkY6wvQKE8qvuIq8 QBJqGsNIs6swhfK82i0c7ZaJF+lTYCAbn5UR9hUqDuSRCX0CVrNi00hOwt774g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hLTnM0B6Kz2n5 for ; Thu, 13 Aug 2026 15:29:59 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3ff5d by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 13 Aug 2026 15:29:53 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: e2cfbd498af8 - main - tty: do not recurse on ttydev_close() 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 List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e2cfbd498af88a211b0b347861cfd989e57cd1fb Auto-Submitted: auto-generated Date: Thu, 13 Aug 2026 15:29:53 +0000 Message-Id: <6a7de2f1.3ff5d.2cfcd213@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=e2cfbd498af88a211b0b347861cfd989e57cd1fb commit e2cfbd498af88a211b0b347861cfd989e57cd1fb Author: Konstantin Belousov AuthorDate: 2026-08-07 19:48:31 +0000 Commit: Konstantin Belousov CommitDate: 2026-08-13 15:29:14 +0000 tty: do not recurse on ttydev_close() When the terminal cdev is closed due to revoke, ttydev_close() destroys t_inpoll and t_outpoll selinfos. Since corresponding knotes reference files pointing to the same tty cdev, it fdrop()s them. But then the VOP_CLOSE() call would recurse into the ttydev_close() for the same tty. More, because the devfs vnode is already doomed, each close call gets the FREVOKE flag set. As result, the kernel is recursing as deep into the ttydev_close() as there are opened files referencing the same tty, which have the knotes installed. Basically, the recursion level is controlled by userspace. Prevent it by marking the tty that is handled by ttydev_close(), with the TF_INDEVCLOSE flag. Do nothing in ttydev_close() when the flag is already set, avoiding recursion. Fixes: acd5638e268a ("tty: delete knotes when TTY is revoked") Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D58706 --- sys/kern/tty.c | 30 +++++++++++++++++++++--------- sys/sys/tty.h | 1 + 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 3de1aabae36b..bf1ef6ea6c88 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -73,7 +73,7 @@ static MALLOC_DEFINE(M_TTY, "tty", "tty device"); -static void tty_rel_free(struct tty *tp); +static void tty_rel_free(struct tty *tp, bool inttydevclose); static TAILQ_HEAD(, tty) tty_list = TAILQ_HEAD_INITIALIZER(tty_list); static struct sx tty_list_sx; @@ -231,13 +231,15 @@ ttydev_enter(struct tty *tp) } static void -ttydev_leave(struct tty *tp) +ttydev_leave(struct tty *tp, bool inttydevclose) { tty_assert_locked(tp); if (tty_opened(tp) || tp->t_flags & TF_OPENCLOSE) { /* Device is still opened somewhere. */ + if (inttydevclose) + tp->t_flags &= ~TF_INDEVCLOSE; tty_unlock(tp); return; } @@ -264,7 +266,7 @@ ttydev_leave(struct tty *tp) tp->t_flags &= ~TF_OPENCLOSE; cv_broadcast(&tp->t_dcdwait); - tty_rel_free(tp); + tty_rel_free(tp, inttydevclose); } /* @@ -365,7 +367,7 @@ ttydev_open(struct cdev *dev, int oflags, int devtype __unused, done: tp->t_flags &= ~TF_OPENCLOSE; cv_broadcast(&tp->t_dcdwait); - ttydev_leave(tp); + ttydev_leave(tp, false); return (error); } @@ -377,6 +379,11 @@ ttydev_close(struct cdev *dev, int fflag, int devtype __unused, struct tty *tp = dev->si_drv1; tty_lock(tp); + if ((tp->t_flags & TF_INDEVCLOSE) != 0) { + tty_unlock(tp); + return (0); + } + tp->t_flags |= TF_INDEVCLOSE; /* * Don't actually close the device if it is being used as the @@ -390,6 +397,7 @@ ttydev_close(struct cdev *dev, int fflag, int devtype __unused, tp->t_flags &= ~(TF_OPENED_IN|TF_OPENED_OUT); if (tp->t_flags & TF_OPENED) { + tp->t_flags &= ~TF_INDEVCLOSE; tty_unlock(tp); return (0); } @@ -409,7 +417,7 @@ ttydev_close(struct cdev *dev, int fflag, int devtype __unused, cv_broadcast(&tp->t_bgwait); cv_broadcast(&tp->t_dcdwait); - ttydev_leave(tp); + ttydev_leave(tp, true); return (0); } @@ -1146,7 +1154,7 @@ tty_dealloc(void *arg) } static void -tty_rel_free(struct tty *tp) +tty_rel_free(struct tty *tp, bool inttydevclose) { struct cdev *dev; @@ -1155,6 +1163,8 @@ tty_rel_free(struct tty *tp) #define TF_ACTIVITY (TF_GONE|TF_OPENED|TF_HOOK|TF_OPENCLOSE) if (tp->t_sessioncnt != 0 || (tp->t_flags & TF_ACTIVITY) != TF_GONE) { /* TTY is still in use. */ + if (inttydevclose) + tp->t_flags &= ~TF_INDEVCLOSE; tty_unlock(tp); return; } @@ -1165,6 +1175,8 @@ tty_rel_free(struct tty *tp) /* TTY can be deallocated. */ dev = tp->t_dev; tp->t_dev = NULL; + if (inttydevclose) + tp->t_flags &= ~TF_INDEVCLOSE; tty_unlock(tp); if (dev != NULL) { @@ -1201,7 +1213,7 @@ tty_rel_sess(struct tty *tp, struct session *sess) MPASS(tp->t_pgrp == NULL); } tp->t_sessioncnt--; - tty_rel_free(tp); + tty_rel_free(tp, false); } void @@ -1220,7 +1232,7 @@ tty_rel_gone(struct tty *tp) cv_broadcast(&tp->t_dcdwait); tp->t_flags |= TF_GONE; - tty_rel_free(tp); + tty_rel_free(tp, false); } static int @@ -2231,7 +2243,7 @@ ttyhook_unregister(struct tty *tp) ttydisc_optimize(tp); /* Maybe deallocate the TTY as well. */ - tty_rel_free(tp); + tty_rel_free(tp, false); } /* diff --git a/sys/sys/tty.h b/sys/sys/tty.h index f1b2646c942d..6a58908d97a4 100644 --- a/sys/sys/tty.h +++ b/sys/sys/tty.h @@ -87,6 +87,7 @@ struct tty { #define TF_BUSY_IN 0x20000 /* Process busy in read() -- not supported. */ #define TF_BUSY_OUT 0x40000 /* Process busy in write(). */ #define TF_BUSY (TF_BUSY_IN|TF_BUSY_OUT) +#define TF_INDEVCLOSE 0x80000 /* In ttydev_close() */ unsigned int t_revokecnt; /* (t) revoke() count. */ /* Buffering mechanisms. */