NetBSD Problem Report #1677
From gnats Mon Oct 23 19:28:14 1995
Received: from bloom-beacon.MIT.EDU by pain.lcs.mit.edu (8.6.9/8.6.9) with ESMTP id TAA29725 for <gnats-bugs@gnats.netbsd.org>; Mon, 23 Oct 1995 19:27:47 -0400
Message-Id: <199510232310.TAA00701@pattern.arlington.ma.us>
Date: Mon, 23 Oct 1995 19:10:21 -0400
From: John Kohl <jtk@kolvir.arlington.ma.us>
Reply-To: jtk@kolvir.arlington.ma.us
To: gnats-bugs@gnats.netbsd.org
Cc: Trevin Beattie <trevin@xmission.com>, jsp@sequent.com
Subject: union FS can return bogus value for lookup of `.', causing later panic
X-Send-Pr-Version: 3.95
>Number: 1677
>Category: kern
>Synopsis: union FS can return bogus value for lookup of `.', causing later panic
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Oct 23 19:35:03 +0000 1995
>Closed-Date:
>Last-Modified: Sat May 21 17:25:01 +0000 2022
>Originator: John Kohl
>Release: 1.1_ALPHA
>Organization:
NetBSD Kernel Hackers `R` Us
>Environment:
System: NetBSD pattern 1.1_ALPHA NetBSD 1.1_ALPHA (PATTERN) #195: Sun Oct 22 13:31:09 EDT 1995 jtk@pattern:/u1/NetBSD-current/src/sys/arch/i386/compile/PATTERN i386
>Description:
If the union FS is looking up `.' in a directory which is searchable in
the top level but unsearchable in the bottom level, it returns a union vnode
that is not the same as the starting vnode. This returned vnode is only
half-locked, in that another union vnode points to the same lower layer
vnode.
Because the lower layer could not be looked up, union_lookup() called
union_allocvp() with lowervp == NULLVP. This resulted in
union_allocvp() failing to find the "real" cached vnode for `.' and it
creates a new one. The new one has UN_LOCKED set, and the uppervp is
indeed locked, but the lock was taken on behalf of the "real" vnode for `.'
This causes trouble in things like sys_lstat() and it kin which have
code like:
NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF | LOCKPARENT, UIO_USERSPACE,
SCARG(uap, path), p);
if (error = namei(&nd))
return (error);
vp = nd.ni_vp;
dvp = nd.ni_dvp;
if (dvp == vp)
vrele(dvp);
else
vput(dvp);
error = vn_stat(vp, &sb, p);
vput(vp);
if (error)
return (error);
The second vput() results in a panic from UFS (if DIAGNOSTIC) when it
attempts to unlock an unlocked UFS vnode.
>How-To-Repeat:
1) in the lower layer:
mkdir Foo
chmod 700 Foo
chown otheruser Foo
2) in the upper layer:
mkdir Foo
3) mount the union FS
4) ls -la /union_mountpoint/Foo
5) watch the machine croak
>Fix:
Not sure what the "right thing" is. Maybe short-circuit `.'?
What about other cases where some user might not have the appropriate
lookup permissions in the lower layer? It seems like we must never let
union_allocvp() be called in such a way as to generate two union vnodes
for the same underlying object.
>Release-Note:
>Audit-Trail:
From: coypu@sdf.org
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/1677: union FS can return bogus value for lookup of `.',
causing later panic
Date: Sun, 26 Mar 2017 19:40:53 +0000
I believe this bug was fixed, I can't reproduce it.
From: Taylor R Campbell <riastradh@NetBSD.org>
To: gnats-bugs@NetBSD.org
Cc:
Subject: Re: kern/1677: union FS can return bogus value for lookup of `.', causing later panic
Date: Sat, 21 May 2022 17:24:41 +0000
onionfs is still broken, news at 11!
Someone^TM should adapt this to an atf test at tests/fs/union/t_pr.c.
arm64# su -m nobody -c 'ls -la /test/lower/foo'
[ 266.7691234] Reader / writer lock error: rw_vector_enter,305: locking aga=
inst myself
[ 266.7766932] lock address : 0xffff0000772d0a80 type : sleep/adapt=
ive
[ 266.7766932] initialized : 0xffffc00000639748
[ 266.7766932] shared holds : 0 exclusive: =
1
[ 266.7766932] shares wanted: 1 exclusive: =
0
[ 266.7766932] relevant cpu : 1 last held: =
1
[ 266.7766932] relevant lwp : 0xffff00007eb9db00 last held: 0xffff00007eb9d=
b00
[ 266.7867213] last locked* : 0xffffc000006543a0 unlocked : 0xffffc00000654=
3e4
[ 266.7867213] owner/count : 0xffff00007eb9db00 flags : 0x0000000000000=
004
[ 266.7867213] Turnstile: no active turnstile for this lock.
[ 266.7867213] panic: LOCKDEBUG: Reader / writer lock error: rw_vector_ente=
r,305: locking against myself
[ 266.7867213] cpu1: Begin traceback...
[ 266.7967503] trace fp ffffc000903c73b0
[ 266.7967503] fp ffffc000903c73e0 vpanic() at ffffc000005cdba8 netbsd:vpan=
ic+0x178
[ 266.7967503] fp ffffc000903c7440 panic() at ffffc000005cdcb4 netbsd:panic=
+0x44
[ 266.8067882] fp ffffc000903c74d0 lockdebug_abort1() at ffffc000005c0af0 n=
etbsd:lockdebug_abort1+0x100
[ 266.8067882] fp ffffc000903c7520 rw_enter() at ffffc0000058925c netbsd:rw=
_enter+0x388
[ 266.8175394] fp ffffc000903c75e0 genfs_lock() at ffffc0000065439c netbsd:=
genfs_lock+0x8c
[ 266.8175394] fp ffffc000903c7600 VOP_LOCK() at ffffc00000648f14 netbsd:VO=
P_LOCK+0x90
[ 266.8269275] fp ffffc000903c7670 vn_lock() at ffffc0000063e61c netbsd:vn_=
lock+0x9c
[ 266.8269275] fp ffffc000903c76a0 union_loadvnode() at ffffc0000048cb2c ne=
tbsd:union_loadvnode+0xbc
[ 266.8377005] fp ffffc000903c77a0 vcache_get() at ffffc0000063c88c netbsd:=
vcache_get+0x188
[ 266.8377005] fp ffffc000903c7840 union_allocvp() at ffffc0000048c7f4 netb=
sd:union_allocvp+0x5a0
[ 266.8470422] fp ffffc000903c7910 union_lookup() at ffffc0000048e9ac netbs=
d:union_lookup+0x238
[ 266.8470422] fp ffffc000903c7a40 VOP_LOOKUP() at ffffc0000064759c netbsd:=
VOP_LOOKUP+0x3c
[ 266.8572209] fp ffffc000903c7a80 lookup_once() at ffffc00000626e38 netbsd=
:lookup_once+0x1b8
[ 266.8572209] fp ffffc000903c7b00 namei_tryemulroot() at ffffc0000062799c =
netbsd:namei_tryemulroot+0x4bc
[ 266.8671509] fp ffffc000903c7c70 namei() at ffffc0000062936c netbsd:namei=
+0x2c
[ 266.8671509] fp ffffc000903c7cb0 do_sys_statat() at ffffc00000634fcc netb=
sd:do_sys_statat+0xec
[ 266.8772127] fp ffffc000903c7d60 sys___lstat50() at ffffc000006350c4 netb=
sd:sys___lstat50+0x20
[ 266.8772127] fp ffffc000903c7e20 syscall() at ffffc000000b255c netbsd:sys=
call+0x19c
[ 266.8872275] tf ffffc000903c7ed0 el0_trap() at ffffc000000b57f0 netbsd:el=
1_trap_exit+0x68
[ 266.8872275] ---- trapframe 0xffffc000903c7ed0 (304 bytes) ----
[ 266.8973727] pc=3D0000f5fbdc0a03fc, spsr=3D0000000040000000
[ 266.8973727] esr=3D00000000560001b9, far=3D0000f5fbdbf14010
[ 266.8973727] x0=3D0000f5fbdc3342f0, x1=3D0000f5fbdc334300
[ 266.8973727] x2=3D0000000000000000, x3=3D0000f5fbdc334280
[ 266.8973727] x4=3D0000000000000027, x5=3D0000000000000011
[ 266.8973727] x6=3D0000f5fbdc3342f2, x7=3D00000000000000d4
[ 266.9073198] x8=3D0000000000000003, x9=3D0000f5fbdc37c308
[ 266.9073198] x10=3D000000000000003d, x11=3D00000000ffffffff
[ 266.9073198] x12=3D0000f5fbdc374100, x13=3D0000f5fbdba00b90
[ 266.9073198] x14=3D0000000000000000, x15=3D0000000000000000
[ 266.9073198] x16=3D0000f5fbdc10cbe8, x17=3D0000f5fbdc0a03f8
[ 266.9073198] x18=3D0000000000000064, x19=3D0000f5fbdc334280
[ 266.9174361] x20=3D0000f5fbdc334300, x21=3D0000000000000000
[ 266.9174361] x22=3D0000000000000000, x23=3D0000000000000001
[ 266.9174361] x24=3D0000f5fbdc33b050, x25=3D0000000000000001
[ 266.9174361] x26=3D0000f5fbdc333000, x27=3D0000f5fbdc33b000
[ 266.9174361] x28=3D0000f5fbdc334140, fp=3Dx29=3D0000fffffffb2a20
[ 266.9174361] lr=3Dx30=3D0000f5fbdbfdab14, sp=3D0000fffffffb2a20
[ 266.9273784] ------------------------------------------------
[ 266.9273784] cpu1: End traceback...
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.