Subject: kern/21628: Locking bug in linux_sys_fcntl
To: None <gnats-bugs@gnats.netbsd.org>
From: Wolfgang Solfrank <ws@fred.tools.de>
List: netbsd-bugs
Date: 05/20/2003 16:12:16
>Number:         21628
>Category:       kern
>Synopsis:       Locking bug in linux_sys_fcntl
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May 20 14:13:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Wolfgang Solfrank
>Release:        NetBSD 1.6T (2003/05/19)
>Organization:
TooLs GmbH
>Environment:
System: NetBSD fred.tools.de 1.6T NetBSD 1.6T (fred) #27: Mon May 19 17:34:12 MEST 2003 ws@fred.tools.de:/src/obj/sys/arch/i386/compile/fred i386
Architecture: i386
Machine: i386
>Description:

There is a comment in linux_sys_fcntl that states that it's not
neccessary to call FILE_USE here.

Since FILE_USE has the side effect (as documented at the definition
of FILE_USE) of unlocking the file locked by the preceding call
to fd_getfile, this is not correct.

While this works in the common case of a simgle processor kernel
without LOCKDEBUG, it hangs on multiprocessor machines.

The patch below is somewhat non-optimal, as it includes repeated
locking of the file structure.  Maybe there should be a new
macro in sys/file.h for just doing the unlock on a file.

>How-To-Repeat:

Try to use javac from sun-jdk13.

>Fix:

Index: linux_file.c
===================================================================
RCS file: /cvsroot/src/sys/compat/linux/common/linux_file.c,v
retrieving revision 1.58
diff -c -r1.58 linux_file.c
*** linux_file.c	2003/03/19 11:36:35	1.58
--- linux_file.c	2003/05/20 13:58:49
***************
*** 427,433 ****
  		fdp = p->p_fd;
  		if ((fp = fd_getfile(fdp, fd)) == NULL)
  			return EBADF;
! 		/* FILE_USE() not needed here */
  		if (fp->f_type != DTYPE_VNODE) {
  	    not_tty:
  			/* Not a tty, proceed with common fcntl() */
--- 427,434 ----
  		fdp = p->p_fd;
  		if ((fp = fd_getfile(fdp, fd)) == NULL)
  			return EBADF;
! 		FILE_USE(fp);
! 		FILE_UNUSE(fp, p);
  		if (fp->f_type != DTYPE_VNODE) {
  	    not_tty:
  			/* Not a tty, proceed with common fcntl() */
>Release-Note:
>Audit-Trail:
>Unformatted: