From nobody Thu Aug 13 15:29:53 2026 X-Original-To: dev-commits-src-main@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 4hLTnG1JHCz6nrRs for ; Thu, 13 Aug 2026 15:29:54 +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 4hLTnG0T5cz3HJh for ; Thu, 13 Aug 2026 15:29:54 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786634994; 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=AW8Ca31f9wBZfJsJe/5/raNKc9tQGqUELL3TgSFWe0d3VxFOX/0v39VkmbBxzTkg1BlZMH Z0rAjrz+CS3NbFQSXssiHIx2HDDpawO8WwP6eULJNToyLb8YMmUJaXfe61cDPwaHmR1F/J 7mcYDMywLPDlANzyiGLzzUIGtCCfI38AP2zuZSkRuTi3wHcBtxad0u7Njuw/2S5qn/bORm UAAF+mHEQ+1E1qW/03ng5DlAAQiZPQJdGU/eU/o7a1/M3wIsl85t1LnZlmJd3HuAWgyiAP i6VndwctuMT1MKjkmcfmXtTSYzk+7zLiGhpsxw6hAN06IIdgNZPehRG4C10uuQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786634994; a=rsa-sha256; cv=none; b=Aq0ZIIcoBn/caB4XaymJ8JGmay3vbV6H6iGvCOpT3hYIE4evTe2hRURKQxbxjezxc274Kh 4yFfwwkC/diljkk9/scgnFJNuctfpB4ClqOISanaGenx02t1LGv2xp/8+eFPVEsj+q2OuF +G3UQYbv3ZBEfheWV1NFxLDm8NfQkQl872Co+qnywgV2bWWuHIUvDWeAtmlfZLQARtnW5j n5YY7v+FUhJKTo8DFj17tE67tB/fbOHW5kMUZPcOBU/WkqDYBYP8U6DcUYJaYg9+yu9Bdi YIe9m5OHWWapmk0sFaoFcbf3i5rObBPpM11pZMgkBZjUqnQU9oCWk+hBZphnVA== 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=1786634994; 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=CoJLB+NBnbB7Q1uK22/aEDFOrGlCRNhKZvQMT4PEPBng8370g+ZI0iRffoxhCP0HFG/H91 +St8cxR4e6BA9TObEeywd438v6NJR2Vv1eHKZT3ODTSUOQgVnhiNwJmOlVDtIiVKprj/ON H7QzlSeZBXnWVbE48TmY/Po371jTGxb59wXUbWYONrPQlVhGJaELNiMLpXoNE92e0UHpXh JD9Id9swxb3ZPtZBBJngz5gMYbsl7pNfozLhxg/8wzYYhZLt7s9Nsc2UMWAMV4PAu0lzKn XFqF14l25Ph0MI+vJimuKRRi7Fvr+LdU5yfCmVxIkCl+MuaT3J6Q7YNkH5H4og== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hLTnF6ZlJz2VW for ; Thu, 13 Aug 2026 15:29:53 +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 the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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. */