NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/46990: tmpfs_gro_genealogy() panic - rename/rmdir race condition not handled
>Number: 46990
>Category: kern
>Synopsis: tmpfs_gro_genealogy() panic - rename/rmdir race condition not
>handled
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Sep 20 14:50:00 +0000 2012
>Originator: Dr. Wolfgang Stukenbrock
>Release: NetBSD-current (Head)
>Organization:
Dr. Nagler & Company GmbH
>Environment:
System: NetBSD test-s0 4.0 NetBSD 4.0 (NSW-WS) #0: Tue Aug 17 17:28:09 CEST
2010 wgstuken@test-s0:/usr/src/sys/arch/amd64/compile/NSW-WS amd64
Architecture: x86_64
Machine: amd64
>Description:
There is a race condition between rename() and rmdir(9 operations that
may lead to a NULL pointer
reference in the kernel in tmpfs.
The rename() call determine all relevant vnode's but than gives up all
lock's on them.
At this point, the directory to that the the object should be moved may
get deleted.
If this happens, tmpfs_gro_genealogy() will lock the directory-vnode
again, but that is no longer
valid. The functions simply gets the no longer valid pointer to the
parent-tmpfs-node structure and
will try to lock the tn_vlock mutex in it - segfault in kernel ...
>How-To-Repeat:
I run a dirconc version that uses seperate seed information in each
worker on tmpfs on a system with
12 CPU's found by NetBSD to validate my backport of tmpfs to 5.1_STABLE.
It crashes from time to time with a reference to address 0x10.
The code rm sys_rmdir() has not relay changed from 5.1_STABLE to
current.
I use the complete tmpfs-code from Head, so the problem exists there
too.
>Fix:
The comment in tmpfs_rename.c tmpfs_gro_genealogy() that dnode may not
be NULL is simply
not true. Need to check if dnode is NULL and return an error (e.g.
ENOENT) instead.
--- potential patch:
- KASSERT(dnode != NULL);
+ if (dnode == NULL) {
+ vput(vp);
+ *intermediate_node_ret = NULL;
+ return ENOENT;
and correct the comment above ...
+ }
>Unformatted:
Home |
Main Index |
Thread Index |
Old Index