Subject: kern/21946: compat/ossaudio returning from within FILE_USE/FILE_UNUSE blocks
To: None <gnats-bugs@gnats.netbsd.org>
From: None <tv@pobox.com>
List: netbsd-bugs
Date: 06/20/2003 20:18:51
>Number:         21946
>Category:       kern
>Synopsis:       compat/ossaudio returning from within FILE_USE/FILE_UNUSE blocks
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jun 21 00:22:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Todd Vierling
>Release:        NetBSD 1.6.1_STABLE
>Organization:
	DUH.ORG:  Pointing out the obvious since 1994.
>Environment:
System: NetBSD server.duh.org 1.6.1_STABLE NetBSD 1.6.1_STABLE (HOME) #2: Wed May 21 13:10:29 EDT 2003 tv@server.duh.org:/export/SRC/duh/netbsd-kernels/HOME i386
Architecture: i386
Machine: i386

>Description:

Linux binaries using ossaudio kernel emulation may, in some circumstances,
get hosed waiting in tsleep on the "closef" wchan because some file
descriptors end up with a use count > 1.  Tracing back, it seems that there
are indeed places where ossaudio will do a FILE_USE() and then "return"
without a corresponding FILE_UNUSE().

>How-To-Repeat:

Run most Linux binaries that use ossaudio.

>Fix:

If happy with this, please also pull up to 1.6.  This is one of several
changes that are required to get CrossOver Office to run on NetBSD/i386.

Index: compat/ossaudio/ossaudio.c
===================================================================
RCS file: /cvsroot/src/sys/compat/ossaudio/ossaudio.c,v
retrieving revision 1.39
diff -u -r1.39 ossaudio.c
--- compat/ossaudio/ossaudio.c	2001/12/24 00:10:49	1.39
+++ compat/ossaudio/ossaudio.c	2003/06/21 00:14:08
@@ -762,11 +762,12 @@
 	case OSS_SOUND_OLD_MIXER_INFO:
 		error = ioctlf(fp, AUDIO_GETDEV, (caddr_t)&adev, p);
 		if (error)
-			return (error);
+			goto out;
 		omi.modify_counter = 1;
 		strncpy(omi.id, adev.name, sizeof omi.id);
 		strncpy(omi.name, adev.name, sizeof omi.name);
-		return copyout(&omi, SCARG(uap, data), OSS_IOCTL_SIZE(com));
+		error = copyout(&omi, SCARG(uap, data), OSS_IOCTL_SIZE(com));
+		goto out;
 	case OSS_SOUND_MIXER_READ_RECSRC:
 		if (di->source == -1) {
 			error = EINVAL;
@@ -819,16 +820,20 @@
 				if (idat & (1 << i))
 					break;
 			if (i >= OSS_SOUND_MIXER_NRDEVICES ||
-			    di->devmap[i] == -1)
-				return EINVAL;
+			    di->devmap[i] == -1) {
+				error = EINVAL;
+				goto out;
+			}
 			mc.un.ord = enum_to_ord(di, di->devmap[i]);
 		} else {
 			mc.type = AUDIO_MIXER_SET;
 			mc.un.mask = 0;
 			for(i = 0; i < OSS_SOUND_MIXER_NRDEVICES; i++) {
 				if (idat & (1 << i)) {
-					if (di->devmap[i] == -1)
-						return EINVAL;
+					if (di->devmap[i] == -1) {
+						error = EINVAL;
+						goto out;
+					}
 					mc.un.mask |= enum_to_mask(di, di->devmap[i]);
 				}
 			}
>Release-Note:
>Audit-Trail:
>Unformatted: