From b04cbf0c36a250a198bd3590209a1950e382664f Mon Sep 17 00:00:00 2001 From: hselasky Date: Wed, 14 Jan 2015 22:07:13 +0000 Subject: [PATCH] Avoid race with "dev_rel()" when using the recently added "delist_dev()" function. Make sure the character device structure doesn't go away until the end of the "destroy_dev()" function due to concurrently running cleanup code inside "devfs_populate()". MFC after: 1 week Reported by: dchagin@ --- sys/fs/devfs/devfs_devs.c | 6 ++++++ sys/kern/kern_conf.c | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index a408725a604..294bd62be7b 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -137,6 +137,12 @@ devfs_alloc(int flags) vfs_timestamp(&ts); cdev->si_atime = cdev->si_mtime = cdev->si_ctime = ts; cdev->si_cred = NULL; + /* + * Avoid race with dev_rel() by setting the initial + * reference count to 1. This last reference is taken + * by the destroy_dev() function. + */ + cdev->si_refcount = 1; return (cdev); } diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index 8b1fdc198cf..bcd6fb926fe 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -1048,8 +1048,6 @@ destroy_devl(struct cdev *dev) /* Remove name marking */ dev->si_flags &= ~SI_NAMED; - dev->si_refcount++; /* Avoid race with dev_rel() */ - /* If we are a child, remove us from the parents list */ if (dev->si_flags & SI_CHILD) { LIST_REMOVE(dev, si_siblings); -- 2.45.0