From nobody@FreeBSD.org  Sun May  9 08:01:23 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id DEE33106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  9 May 2010 08:01:23 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [69.147.83.33])
	by mx1.freebsd.org (Postfix) with ESMTP id CD2C88FC12
	for <freebsd-gnats-submit@FreeBSD.org>; Sun,  9 May 2010 08:01:23 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o4981Ncl024855
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 9 May 2010 08:01:23 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o4981N6h024854;
	Sun, 9 May 2010 08:01:23 GMT
	(envelope-from nobody)
Message-Id: <201005090801.o4981N6h024854@www.freebsd.org>
Date: Sun, 9 May 2010 08:01:23 GMT
From: Alex Bakhtin <Alex.Bakhtin@gmail.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [geli][panic][patch] kernel panic if geli autodetach is configured and geli provider is detached.
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         146429
>Category:       kern
>Synopsis:       [geli][panic][patch] kernel panic if geli autodetach is configured and geli provider is detached.
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    pjd
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun May 09 08:10:02 UTC 2010
>Closed-Date:    
>Last-Modified:  Sun May 09 20:52:13 UTC 2010
>Originator:     Alex Bakhtin
>Release:        8.0-STABLE
>Organization:
>Environment:
FreeBSD tarzan-new.private.flydrag.ru 8.0-STABLE FreeBSD 8.0-STABLE #1: Sun May  9 05:05:56 UTC 2010     bakhtin@tarzan-new.private.flydrag.ru:/storage/obj/storage/src/8-STABLE/src/sys/DEBUG  amd64

>Description:
g_eli_access: calling pp->geom->softc in the case of pp->geom is NULL causes kernel panic.


kernel panic if geli is configurad for autodetach,
some consumer exists and low-level provider is detached.

If geli is configured for autodetach, is uses it's own
g_eli_access instead of g_std_access. If the underlying provider
is detached, g_eli_access is called with pp->geom->softc set to
NULL. This causes kernel panic because g_eli_access assumes that
pp->geom->softc is not NULL.



GEOM_ELI: Crypto WRITE request failed (error=6). ad10.eli[WRITE(offset=0, length=1024)]


Fatal trap 12: page fault while in kernel mode
cpuid = 1; apic id = 01
fault virtual address   = 0x234
fault code              = supervisor read data, page not present
instruction pointer     = 0x20:0xffffffff814234c6
stack pointer           = 0x28:0xffffff80eb7df5c0
frame pointer           = 0x28:0xffffff80eb7df630
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 1442 (dd)



(kgdb) bt
#0  doadump () at pcpu.h:223
#1  0xffffffff801df82c in db_fncall (dummy1=Variable "dummy1" is not available.
) at /storage/src/8-STABLE/src/sys/ddb/db_command.c:548
#2  0xffffffff801dfadd in db_command (last_cmdp=0xffffffff80c2b0a0, cmd_table=Variable "cmd_table" is not available.
) at /storage/src/8-STABLE/src/sys/ddb/db_command.c:445
#3  0xffffffff801e4323 in db_script_exec (scriptname=0xffffffff808f61b5 "kdb.enter.default", warnifnotfound=0)
    at /storage/src/8-STABLE/src/sys/ddb/db_script.c:302
#4  0xffffffff801e441e in db_script_kdbenter (eventname=Variable "eventname" is not available.
) at /storage/src/8-STABLE/src/sys/ddb/db_script.c:325
#5  0xffffffff801e1d84 in db_trap (type=Variable "type" is not available.
) at /storage/src/8-STABLE/src/sys/ddb/db_main.c:228
#6  0xffffffff805ce2a5 in kdb_trap (type=12, code=0, tf=0xffffff8000065960) at /storage/src/8-STABLE/src/sys/kern/subr_kdb.c:535
#7  0xffffffff8088585d in trap_fatal (frame=0xffffff8000065960, eva=Variable "eva" is not available.
) at /storage/src/8-STABLE/src/sys/amd64/amd64/trap.c:860
#8  0xffffffff80885bcd in trap_pfault (frame=0xffffff8000065960, usermode=0) at /storage/src/8-STABLE/src/sys/amd64/amd64/trap.c:781
#9  0xffffffff8088642b in trap (frame=0xffffff8000065960) at /storage/src/8-STABLE/src/sys/amd64/amd64/trap.c:499
#10 0xffffffff8086b783 in calltrap () at /storage/src/8-STABLE/src/sys/amd64/amd64/exception.S:224
#11 0xffffffff814235e6 in g_eli_access (pp=0xffffff0005913100, dr=0, dw=0, de=0)
    at /storage/src/8-STABLE/src/sys/modules/geom/geom_eli/../../../geom/eli/g_eli.c:485
#12 0xffffffff8054246a in g_access (cp=0xffffff0005dc0a00, dcr=-1, dcw=-1, dce=-1) at /storage/src/8-STABLE/src/sys/geom/geom_subr.c:814
#13 0xffffffff8054246a in g_access (cp=0xffffff0005dc0900, dcr=-1, dcw=-1, dce=0) at /storage/src/8-STABLE/src/sys/geom/geom_subr.c:814
#14 0xffffffff8053b558 in g_dev_orphan (cp=0xffffff0005dc0900) at /storage/src/8-STABLE/src/sys/geom/geom_dev.c:445
#15 0xffffffff8053e072 in g_run_events () at /storage/src/8-STABLE/src/sys/geom/geom_event.c:163
#16 0xffffffff8053fb0c in g_event_procbody () at /storage/src/8-STABLE/src/sys/geom/geom_kern.c:141
#17 0xffffffff805747ea in fork_exit (callout=0xffffffff8053faa0 <g_event_procbody>, arg=0x0, frame=0xffffff8000065c80)
    at /storage/src/8-STABLE/src/sys/kern/kern_fork.c:843
#18 0xffffffff8086bc5e in fork_trampoline () at /storage/src/8-STABLE/src/sys/amd64/amd64/exception.S:561


(kgdb) up 11
#11 0xffffffff814235e6 in g_eli_access (pp=0xffffff0005913100, dr=0, dw=0, de=0)
    at /storage/src/8-STABLE/src/sys/modules/geom/geom_eli/../../../geom/eli/g_eli.c:485
485             if (pp->acr + dr > 0 || pp->acw + dw > 0 || pp->ace + de > 0)

(kgdb) list 470
465
466     int
467     g_eli_access(struct g_provider *pp, int dr, int dw, int de)
468     {
469             struct g_eli_softc *sc;
470             struct g_geom *gp;
471
472             gp = pp->geom;
473             sc = gp->softc;
474
(kgdb) list
475             if (dw > 0) {
476                     if (sc->sc_flags & G_ELI_FLAG_RO) {
477                             /* Deny write attempts. */
478                             return (EROFS);
479                     }
480                     /* Someone is opening us for write, we need to remember that. */
481                     sc->sc_flags |= G_ELI_FLAG_WOPEN;
482                     return (0);
483             }
484             /* Is this the last close? */
(kgdb)
(kgdb) p pp
$1 = (struct g_provider *) 0xffffff0005913100
(kgdb) p pp->geom
$2 = (struct g_geom *) 0xffffff0005a52a00
(kgdb) p sc
$3 = (struct g_eli_softc *) 0x0
(kgdb) p sc->sc_flags
Cannot access memory at address 0x234
(kgdb)



Geom name: ad10.eli
EncryptionAlgorithm: AES-CBC
KeyLength: 128
Crypto: software
UsedKey: 0
Flags: RW-DETACH
Providers:
1. Name: ad10.eli
   Mediasize: 80026361344 (75G)
   Sectorsize: 512
   Mode: r0w0e0
Consumers:
1. Name: ad10
   Mediasize: 80026361856 (75G)
   Sectorsize: 512
   Mode: r1w1e1


Geom name: ad10.eli
Providers:
1. Name: label/testl
   Mediasize: 80026360832 (75G)
   Sectorsize: 512
   Mode: r0w0e0
   secoffset: 0
   offset: 0
   seclength: 156301486
   length: 80026360832
   index: 0
Consumers:
1. Name: ad10.eli
   Mediasize: 80026361344 (75G)
   Sectorsize: 512
   Mode: r0w0e0

>How-To-Repeat:
1. Create geli on top of physical disc.
2. Create glabel on top of geli
3. Attach geli with auto-detach enabled.
4. detach (physically) underlying disk.
5. run dd if=/dev/zero of=/dev/label/testl count=1 to access geli
6. wait for crash

>Fix:
Two choices:
1. Don't use auto-detach flag for geli.
2. Apply attached patch.

The patch is extremely simple, I looked briefly into the code and discovered that it's safe to just return here.


Patch attached with submission follows:

--- geom/eli/g_eli.c.orig	2010-05-09 04:28:32.377542675 +0000
+++ geom/eli/g_eli.c	2010-05-09 15:46:22.535882353 +0000
@@ -472,6 +472,9 @@
 	gp = pp->geom;
 	sc = gp->softc;
 
+	if ( sc == NULL )
+		return (0);
+
 	if (dw > 0) {
 		if (sc->sc_flags & G_ELI_FLAG_RO) {
 			/* Deny write attempts. */


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-geom 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun May 9 20:48:36 UTC 2010 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=146429 
Responsible-Changed-From-To: freebsd-geom->pjd 
Responsible-Changed-By: pjd 
Responsible-Changed-When: ndz 9 maj 2010 20:51:55 UTC 
Responsible-Changed-Why:  
I'll take this one. 

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