From nobody Thu Sep 28 01:42:45 2023 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 4Rwx7T5SBqz4vHnT; Thu, 28 Sep 2023 01:42:45 +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 "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Rwx7T4xXnz3Jky; Thu, 28 Sep 2023 01:42:45 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1695865365; 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=So3GYT0v2YR3GQlDa4UsoeH7V/MHH88PU5K3woZRQdw=; b=elGfrRO6W3MmBwXS4efz4JH/aejDcFqNiXydGUVIh27Wesy4fLRijeJwr7UGpNbxc+iLsk KdSDGl7X2AA+kGN2NSF+e7ZJQpQ6caC4+Yy3mSvOpyInyEhJKMozPMCI2cZrAyrxofhF2B mNXtQjCanwvjS4c3dX0ezmzZn8RRYP7STYA1Vlw5D9+eazeURhKAuMPIyOobW+gIz8uiRp D9XOzpwAZxZ3GnykVJFg5d950qlpKcfoMnxVttwwvdrhlBbeYxgvCYUR3LAQCnavLfg1rJ /YkBkIofjdgFELbeO0sVvxSmx0PjLysHYzwh/4Yw1ukp3MhQku4Sd/ll93IXUQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1695865365; a=rsa-sha256; cv=none; b=l7tKYdUZTD32phvYdmmvuwNuP7xhrQfGY3O4L38LXtX4V2GTa1I6rQJIP9XV2CccYJimxj tK6qBhaDQu1zK1rMNe1X2bi936BLbpVVWoLGWdJ0BUNYiKdOqRG5z6cgvBcMZe7puc4lLO R9OANr98HVzn9iJhfbuQL/09I2qGwonmShEX7Kf9+76xv2VY/UUmyi3mdrw+GyxYigcB6x HBJKzwkicg14cYpOuU8RBovcLqf+GhD8UdlPj37vFLSZdsh4tPAsN53AOuaVB4DI+if6tV MgtC2xlfm7AMTd3wrmjEVQfxQBrJmqSuJQIRMAs9goy/hm+CNJZV0wjXFreprw== 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=1695865365; 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=So3GYT0v2YR3GQlDa4UsoeH7V/MHH88PU5K3woZRQdw=; b=F1xaGVFB/Y95096DMNAZMUHKC62h85l+gTaYtPdqHg4ZYoOjm2isA+f1rxI+6kGCGhH3Ly iHR043ykhlXvDsEl9AJ6pczUIjq040jZF58/8U+B4mV7P/9iW5tLw/yVQDhcUdp+zE2JQU omrSI6dyibIoQBadVde3Sk9VBGgNWtD0dG68RQy3WbjXIwVgycSHWx6WhJNiOqNKKiz+I/ o8qqID2njZAxRr0qeGjM8p7xgn8RS3TmmJ18AdQHDymEncOeHKUf812EnZ4+e06jnNwBAi eUbIdoHa8FQgoqX1ub8ZV11OE2Gy5rd3y+oNmeS5wVqwUIl2AOmGXbAk3r4OMw== 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 4Rwx7T40Nvz131P; Thu, 28 Sep 2023 01:42:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 38S1gjnR005518; Thu, 28 Sep 2023 01:42:45 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 38S1gj4X005515; Thu, 28 Sep 2023 01:42:45 GMT (envelope-from git) Date: Thu, 28 Sep 2023 01:42:45 GMT Message-Id: <202309280142.38S1gj4X005515@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: "Jason A. Harmening" Subject: git: ee596061e5a5 - stable/13 - devfs: add integrity asserts for cdevp_list 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: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jah X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: ee596061e5a5952f1ddc68627492fbe94af8344b Auto-Submitted: auto-generated The branch stable/13 has been updated by jah: URL: https://cgit.FreeBSD.org/src/commit/?id=ee596061e5a5952f1ddc68627492fbe94af8344b commit ee596061e5a5952f1ddc68627492fbe94af8344b Author: Jason A. Harmening AuthorDate: 2023-09-19 13:44:34 +0000 Commit: Jason A. Harmening CommitDate: 2023-09-28 01:29:52 +0000 devfs: add integrity asserts for cdevp_list It's possible for misuse of cdev KPIs or for bugs in devfs itself to result in e.g. a cdev object's container being freed while still on the global list used to populate each devfs mount; see PR 273418 for a recent example. Since a node may be marked inactive well before it is reaped from the list, add a new flag solely to track list membership, and employ it in some basic list integrity assertions to catch bad actors. Discussed with: kib, mjg (cherry picked from commit 67864268da53b792836f13be10299de8cd62997e) --- sys/fs/devfs/devfs_devs.c | 12 +++++++++++- sys/fs/devfs/devfs_int.h | 1 + sys/fs/devfs/devfs_vnops.c | 4 ++++ sys/kern/kern_conf.c | 2 ++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index 6d8ce5cc3a63..1e28db5966a7 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -175,6 +175,9 @@ devfs_free(struct cdev *cdev) struct cdev_priv *cdp; cdp = cdev2priv(cdev); + KASSERT((cdp->cdp_flags & (CDP_ACTIVE | CDP_ON_ACTIVE_LIST)) == 0, + ("%s: cdp %p (%s) still on active list", + __func__, cdp, cdev->si_name)); if (cdev->si_cred != NULL) crfree(cdev->si_cred); devfs_free_cdp_inode(cdp->cdp_inode); @@ -521,6 +524,9 @@ devfs_populate_loop(struct devfs_mount *dm, int cleanup) dev_lock(); TAILQ_FOREACH(cdp, &cdevp_list, cdp_list) { KASSERT(cdp->cdp_dirents != NULL, ("NULL cdp_dirents")); + KASSERT((cdp->cdp_flags & CDP_ON_ACTIVE_LIST) != 0, + ("%s: cdp %p (%s) should not be on active list", + __func__, cdp, cdp->cdp_c.si_name)); /* * If we are unmounting, or the device has been destroyed, @@ -552,6 +558,7 @@ devfs_populate_loop(struct devfs_mount *dm, int cleanup) if (!(cdp->cdp_flags & CDP_ACTIVE)) { if (cdp->cdp_inuse > 0) continue; + cdp->cdp_flags &= ~CDP_ON_ACTIVE_LIST; TAILQ_REMOVE(&cdevp_list, cdp, cdp_list); dev_unlock(); dev_rel(&cdp->cdp_c); @@ -703,7 +710,10 @@ devfs_create(struct cdev *dev) dev_lock_assert_locked(); cdp = cdev2priv(dev); - cdp->cdp_flags |= CDP_ACTIVE; + KASSERT((cdp->cdp_flags & CDP_ON_ACTIVE_LIST) == 0, + ("%s: cdp %p (%s) already on active list", + __func__, cdp, dev->si_name)); + cdp->cdp_flags |= (CDP_ACTIVE | CDP_ON_ACTIVE_LIST); cdp->cdp_inode = alloc_unrl(devfs_inos); dev_refl(dev); TAILQ_INSERT_TAIL(&cdevp_list, cdp, cdp_list); diff --git a/sys/fs/devfs/devfs_int.h b/sys/fs/devfs/devfs_int.h index 26589e0bded6..9cf50c58018d 100644 --- a/sys/fs/devfs/devfs_int.h +++ b/sys/fs/devfs/devfs_int.h @@ -57,6 +57,7 @@ struct cdev_priv { #define CDP_ACTIVE (1 << 0) #define CDP_SCHED_DTR (1 << 1) #define CDP_UNREF_DTR (1 << 2) +#define CDP_ON_ACTIVE_LIST (1 << 3) u_int cdp_inuse; u_int cdp_maxdirent; diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index e8c8956d36fd..a71cfda9fa9a 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -1676,6 +1676,10 @@ devfs_revoke(struct vop_revoke_args *ap) dev_lock(); cdp->cdp_inuse--; if (!(cdp->cdp_flags & CDP_ACTIVE) && cdp->cdp_inuse == 0) { + KASSERT((cdp->cdp_flags & CDP_ON_ACTIVE_LIST) != 0, + ("%s: cdp %p (%s) not on active list", + __func__, cdp, dev->si_name)); + cdp->cdp_flags &= ~CDP_ON_ACTIVE_LIST; TAILQ_REMOVE(&cdevp_list, cdp, cdp_list); dev_unlock(); dev_rel(&cdp->cdp_c); diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index 866788530e7f..a3af24a43b61 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -119,6 +119,8 @@ dev_free_devlocked(struct cdev *cdev) cdp = cdev2priv(cdev); KASSERT((cdp->cdp_flags & CDP_UNREF_DTR) == 0, ("destroy_dev() was not called after delist_dev(%p)", cdev)); + KASSERT((cdp->cdp_flags & CDP_ON_ACTIVE_LIST) == 0, + ("%s: cdp %p (%s) on active list", __func__, cdp, cdev->si_name)); TAILQ_INSERT_HEAD(&cdevp_free_list, cdp, cdp_list); }