From owner-freebsd-bugs@FreeBSD.ORG Thu May 1 07:40:01 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BA39A1065676 for ; Thu, 1 May 2008 07:40:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 9597A8FC19 for ; Thu, 1 May 2008 07:40:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m417e190086243 for ; Thu, 1 May 2008 07:40:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m417e1IF086242; Thu, 1 May 2008 07:40:01 GMT (envelope-from gnats) Resent-Date: Thu, 1 May 2008 07:40:01 GMT Resent-Message-Id: <200805010740.m417e1IF086242@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Arthur Hartwig Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7713F106566B for ; 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 ; 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 ; 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 To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/123287: structure used after freed in destroy_devl() in kern/kern_conf.c X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 May 2008 07:40:01 -0000 >Number: 123287 >Category: kern >Synopsis: structure used after freed in destroy_devl() in kern/kern_conf.c >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu May 01 07:40:01 UTC 2008 >Closed-Date: >Last-Modified: >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: >Unformatted: