From nobody@FreeBSD.org  Thu May  1 07:37:12 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 7713F106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  1 May 2008 07:37:12 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 647538FC0C
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  1 May 2008 07:37:12 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m417aVrI042224
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 1 May 2008 07:36:31 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.2/8.14.1/Submit) id m417aVxE042215;
	Thu, 1 May 2008 07:36:31 GMT
	(envelope-from nobody)
Message-Id: <200805010736.m417aVxE042215@www.freebsd.org>
Date: Thu, 1 May 2008 07:36:31 GMT
From: Arthur Hartwig <arthur.hartwig@nokia.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: structure used after freed in destroy_devl() in kern/kern_conf.c
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         123287
>Category:       kern
>Synopsis:       [devfs] structure used after freed in destroy_devl() in kern/kern_conf.c
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu May 01 07:40:01 UTC 2008
>Closed-Date:    Sat Nov 06 18:09:56 UTC 2010
>Last-Modified:  Sat Nov 06 18:09:56 UTC 2010
>Originator:     Arthur Hartwig
>Release:        6.3
>Organization:
Nokia
>Environment:
>Description:
In kern/kern_conf.c destroy_devl() calls devfs_destroy() in fs/devfs/devfs_devs.c.
devfs_destroy() clears CDP_ACTIVE in cdp_flags in the structure pointed to by si_priv in the cdev structure. Then destroy_devl() calls msleep() giving devmtx as the mutex to be released then reacquired before returning. 

Since devmtx is released, it opens the way for another thread to notice that CDP_ACTIVE has been cleared and free the structure pointed to be si_priv in the cdev structure. It might happen like this: open() calls devfs_populate() in fs/devfs/devfs_devs.c which calls devfs_populate_loop() in the same file. devfs_populate_loop() walks the cdevp_list and finds the cdev with associated cdev_priv with CDP_ACTIVE cleared and calls dev_rel() in kern/kern_conf.c which calls devfs_free() which frees the structure pointed to be si_priv in the cdev struct.

Some time later, the thread in destroy_devl() wakes from its sleep but now si_priv   points to a freed structure. The cdev is either put on the dead_cdevsw.devs list or given to dev_free_devlocked() in kern/kern_conf.c. dev_free_devlocked() puts the address of the already freed structure pointed to by si_priv in the cdev onto the cdev_free_list and hence modifies it. It's possible no-one will notice this use of a structure after it has been freed, but it may cause havoc if the structure has already been reallocated and will certainly cause a panic if the kernel has been build with options INVARIANTS.

>How-To-Repeat:
Unknown. This is a race condition which has not proved easy to reproduce.

>Fix:
In destroy_devl() move the call to devfs_destroy() to somewhere after the msleep() call, for example, just before the test on dev->si_refcount.

A quick glance at the 7.0-RELEASE code suggests this problem is also present there. I haven't checked HEAD.

>Release-Note:
>Audit-Trail:

From: Arthur Hartwig <Arthur.Hartwig@nokia.com>
To: bug-followup@FreeBSD.org, arthur.hartwig@nokia.com
Cc:  
Subject: Re: kern/123287: [devfs] structure used after freed in destroy_devl()
 in kern/kern_conf.c
Date: Mon, 19 May 2008 17:31:31 +1000

 Is there any update available for this PR? Does the responsible 
 maintainer agree with the analysis?
 
 
State-Changed-From-To: open->closed 
State-Changed-By: jh 
State-Changed-When: Sat Nov 6 18:09:54 UTC 2010 
State-Changed-Why:  
Fixed in r163328. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=123287 
>Unformatted:
