From owner-freebsd-bugs@FreeBSD.ORG Sat Jun 21 20:30:04 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 CF60C1065691 for ; Sat, 21 Jun 2008 20:30:04 +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 B50B58FC15 for ; Sat, 21 Jun 2008 20:30:04 +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 m5LKU4Gu033661 for ; Sat, 21 Jun 2008 20:30:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m5LKU4R9033660; Sat, 21 Jun 2008 20:30:04 GMT (envelope-from gnats) Resent-Date: Sat, 21 Jun 2008 20:30:04 GMT Resent-Message-Id: <200806212030.m5LKU4R9033660@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, Mateusz Guzik Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 21596106567B for ; Sat, 21 Jun 2008 20:22:48 +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 18FFA8FC17 for ; Sat, 21 Jun 2008 20:22:48 +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 m5LKMlXR086250 for ; Sat, 21 Jun 2008 20:22:47 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.2/8.14.1/Submit) id m5LKMlTN086249; Sat, 21 Jun 2008 20:22:47 GMT (envelope-from nobody) Message-Id: <200806212022.m5LKMlTN086249@www.freebsd.org> Date: Sat, 21 Jun 2008 20:22:47 GMT From: Mateusz Guzik To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/124853: [patch] devfs_ruleset_use may use freed memory, causing panic 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: Sat, 21 Jun 2008 20:30:05 -0000 >Number: 124853 >Category: kern >Synopsis: [patch] devfs_ruleset_use may use freed memory, causing panic >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Jun 21 20:30:04 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Mateusz Guzik >Release: 8.0-CURRENT >Organization: >Environment: FreeBSD eternal 8.0-CURRENT FreeBSD 8.0-CURRENT #3: Sat Jun 21 21:41:16 CEST 2008 root@eternal:/usr/obj/usr/src/sys/ETERNAL i386 >Description: Function devfs_ruleset_use follows the following algorithm: 1. Get ruleset; if it doesn't exists, create it. 2. Decrease reference count of current ruleset of dm. Call devfs_ruleset_reap to free it, if it has no references and no rules. 3. Assign ruleset from 1. to dm, increase its reference count. Ruleset created by this function has no rules. When user types e. g. `devfs ruleset 100', this function creates ruleset 100 for him. When he types this command again, ruleset 100 is freed due to zeroed reference count and empty rules list, then it's assigned to dm. This causes panic few minutes later. >How-To-Repeat: Run `devfs ruleset' twice with non-existent ruleset number, for example `devfs ruleset 100'. Wait a couple of minutes, kernel will panic saying `Most recently used by DEVFS_RULE'. >Fix: Patch is attached. Patch attached with submission follows: --- devfs_rule.c.orig 2008-06-21 21:31:48.000000000 +0200 +++ devfs_rule.c 2008-06-21 21:33:49.000000000 +0200 @@ -733,19 +733,20 @@ static int devfs_ruleset_use(devfs_rsnum rsnum, struct devfs_mount *dm) { struct devfs_ruleset *cds, *ds; - ds = devfs_ruleset_bynum(rsnum); - if (ds == NULL) - ds = devfs_ruleset_create(rsnum); if (dm->dm_ruleset != 0) { cds = devfs_ruleset_bynum(dm->dm_ruleset); --cds->ds_refcount; devfs_ruleset_reap(cds); } + ds = devfs_ruleset_bynum(rsnum); + if (ds == NULL) + ds = devfs_ruleset_create(rsnum); + /* These should probably be made atomic somehow. */ ++ds->ds_refcount; dm->dm_ruleset = rsnum; return (0); >Release-Note: >Audit-Trail: >Unformatted: