Subject: kern/7228: Accessing /dev/ss0 causes panic
To: None <gnats-bugs@gnats.netbsd.org>
From: None <R.S.Brooks@liverpool.ac.uk>
List: netbsd-bugs
Date: 03/24/1999 23:13:12
>Number:         7228
>Category:       kern
>Synopsis:       Accessing /dev/ss0 causes panic
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Mar 24 15:20:00 1999
>Last-Modified:
>Originator:     Roger Brooks
>Organization:
	The University of Liverpool
>Release:        1.3.2
>Environment:
i386
System: NetBSD tallis 1.3.2 NetBSD 1.3.2 (TALLIS) #21: Tue Mar 2 23:43:12 GMT 1999 root@tallis:/usr/src/sys/arch/i386/compile/TALLIS i386


>Description:
	Accessing /dev/ss0 (SCSI scanner) causes kernel page fault trap.
>How-To-Repeat:
	Attach Mustek 6000SP scanner, and attempt to scan a document using
	the sane pkg.
>Fix:
	See below.  If the scanner is Mustek MFS-06000CX, Mustek MFS-12000CX
	or HP Scanjet, ssattach() leaves ss->special pointing to a struct
	of quirk functions (and there is presumably no problem).  With any
	other scanner (including Mustek 6000SP) ss->special is a NULL pointer,
	thus accessing ss->special->XXX causes page fault trap.

	This patch also fixes a further problem which prevents ioctl's
	working on the rewind (minor & 0x3 == 0) and no-rewind
	(minor & 0x3 == 1) devices.  The control device (minor & 0x3 == 3)
	is supposed to allow ioctl's ONLY, but this shouldn't mean ioctl's
	aren't allowed on the other device modes (this breaks the sane
	package).


--- ss.c.orig	Tue May  5 07:52:24 1998
+++ ss.c	Wed Mar  3 22:21:35 1999
@@ -252,7 +252,7 @@
 	SC_DEBUG(ss->sc_link, SDEV_DB1, ("closing\n"));
 
 	if (SSMODE(dev) == MODE_REWIND) {
-		if (ss->special->rewind_scanner) {
+		if (ss->special && ss->special->rewind_scanner) {
 			/* call special handler to rewind/abort scan */
 			error = (ss->special->rewind_scanner)(ss);
 			if (error)
@@ -288,7 +288,7 @@
 	 * time, also some cannot disconnect, so the read must be
 	 * short enough to happen quickly
 	 */
-	if (ss->special->minphys)
+	if (ss->special && ss->special->minphys)
 		(ss->special->minphys)(ss, bp);
 }
 
@@ -308,7 +308,7 @@
 
 	/* if the scanner has not yet been started, do it now */
 	if (!(ss->flags & SSF_TRIGGERED)) {
-		if (ss->special->trigger_scanner) {
+		if (ss->special && ss->special->trigger_scanner) {
 			error = (ss->special->trigger_scanner)(ss);
 			if (error)
 				return (error);
@@ -422,7 +422,7 @@
 			ss->buf_queue.b_actb = bp->b_actb;
 		*bp->b_actb = dp;
 
-		if (ss->special->read) {
+		if (ss->special && ss->special->read) {
 			(ss->special->read)(ss, bp);
 		} else {
 			/* generic scsi2 scanner read */
@@ -449,7 +449,7 @@
 
 	switch (cmd) {
 	case SCIOCGET:
-		if (ss->special->get_params) {
+		if (ss->special && ss->special->get_params) {
 			/* call special handler */
 			error = (ss->special->get_params)(ss);
 			if (error)
@@ -463,7 +463,7 @@
 	case SCIOCSET:
 		sio = (struct scan_io *)addr;
 
-		if (ss->special->set_params) {
+		if (ss->special && ss->special->set_params) {
 			/* call special handler */
 			error = (ss->special->set_params)(ss, sio);
 			if (error)
@@ -474,7 +474,7 @@
 		}
 		break;
 	case SCIOCRESTART:
-		if (ss->special->rewind_scanner ) {
+		if (ss->special && ss->special->rewind_scanner ) {
 			/* call special handler */
 			error = (ss->special->rewind_scanner)(ss);
 			if (error)
@@ -489,8 +489,6 @@
 		break;
 #endif
 	default:
-		if (SSMODE(dev) != MODE_CONTROL)
-			return (ENOTTY);
 		return (scsipi_do_ioctl(ss->sc_link, dev, cmd, addr, flag, p));
 	}
 	return (error);
>Audit-Trail:
>Unformatted: