Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 25 Jul 2001 23:00:02 -0700 (PDT)
From:      wea@llnl.gov
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/29203: Kernel panic reading a non-fixated CD
Message-ID:  <200107260600.f6Q602N29687@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/29203; it has been noted by GNATS.

From: wea@llnl.gov
To: FreeBSD-gnats-submit@freebsd.org
Cc: wea@llnl.gov
Subject: Re: kern/29203: Kernel panic reading a non-fixated CD
Date: Wed, 25 Jul 2001 22:51:40 -0700 (PDT)

 >Submitter-Id:	current-users
 >Originator:	Ed Alley
 >Organization:	Lawrence Livermore National Lab.
 >Confidential:	no
 >Synopsis:	Kernel panics when mounting non-fixated CD
 >Severity:	non-critical
 >Priority:	low
 >Category:	kern
 >Class:		change-request
 >Release:	FreeBSD 4.3-RELEASE i386
 >Environment:
 System: FreeBSD jordan.llnl.gov 4.3-RELEASE #0: Tue Jul 24 13:38:25 PDT 2001 wea@llnl.gov: /usr/src/sys/compile/JORDAN.5.ipfw i386
 
 >Description:
 
 	RE: PR kern/29203
 
 	I am running FreeBSD 4.3 with an IDE HP cd-writer 9500 series.
 
 	I appologize if this is a double submit but I never got a
 	reply from gnats concerning my second submission. This may
 	have been due to a corrupted subject line which didn't have
 	the RE: in it. 
 
 	By looking at code I have discovered that the bytecount should
 	never exceed the maximum size of an signed integer! This can be
 	seen in the file atapi-all.c and the routine atapi_queue_cmd()
 	that queues up the atapi requests. The bytecount is passed
 	through the argument list of atapi_queue_cmd() as the variable
 	count which is typed as an int! Therefore, my concern about
 	bytecount being limited to 2G was unfounded. On my machine
 	ints and longs are both 32 bits. So limiting bytecount to
 	2G is correct.
 
 	The page fault was triggered by atapi_read() when it tried to
 	read a bytecount = 0xffff8000 which is larger that 2G. It is
 	curious that when we convert the hex to a signed long we
 	get -32768 which is -2^(15) where ^ means power. According
 	to <machine/limits.h> on my machine this is the value of
 	the smallest short. If the hardware returns short integers
 	and it thinks that -0 = 0x8000 this may be the problem
 	since 0x8000 would get sign extended for int32 so the
 	argument count would be equal to -32768 and then bytecount
 	would get set to 0xffff8000. (I'm speculating here since
 	I don't know how the hardware works.)
 
 	(In view of the above discussion perhaps a better place for a
 	 patch is in atapi_queue_cmd(): a simple test on the sign of
 	 count would suffice. I'll look at this also.)
 
 	I have previously submitted a patch to avoid the panic that
 	resulted after I tried to mount a non-fixated iso 9660 CD
 	previously burned with my CD writer. The previous patch had
 	the problem that it tested every ATAPI read for a large bytecount
 	including IDE disk reads. The patch below only tests CD reads,
 	and hence, only applies the 2G limit to these.
 
 >How-To-Repeat:
 	Unless you have my hardware configuration you can't repeat
 	the error. However, I don't doubt that other CDRWs may
 	do something similar.
 
 >Fix:
 	The patch has been changed: It now tests the bytecount
 	only for the case of reading a CD. This eliminates
 	the problem of limiting the bytecount to 2G for disk reads.
 	It now only does this for CDs.
 
 	Note: I have tried to print out a meaningful message
 	and also tried to get the atapi error mechanism to
 	say something meaningful, but I was not too successful.
 	If someone can improve this I would be grateful.
 
 	Also note: It may be better to do this in atapi_queue_cmd().
 
 	The patch must be installed in /usr/src/sys/dev/ata as:
 
 		patch -p < patch.file
 
 	Here is the patch:
 
 *** atapi-all.c.orig	Tue Jul 24 13:21:03 2001
 --- atapi-all.c	Wed Jul 25 16:03:47 2001
 ***************
 *** 382,387 ****
 --- 382,397 ----
   	    return ATA_OP_CONTINUES;
   	
   	case ATAPI_P_READ:
 + 	    if (ATP_PARAM->device_type == ATAPI_TYPE_CDROM) {
 + 		if ((long)request->bytecount < 0) {
 + 		    printf("%s: %s trying to read CD with bytecount = %lu\n",
 + 			atp->devname, atapi_cmd2str(atp->cmd),
 + 			(unsigned long)request->bytecount);
 + 			request->result =
 + 			    ATAPI_E_ILI | ATAPI_SK_ILLEGAL_REQUEST;
 + 			break;
 + 		}
 + 	    }
   	    if (!(request->flags & ATPR_F_READ)) {
   		request->result = inb(atp->controller->ioaddr + ATA_ERROR);
   		printf("%s: %s trying to read on write buffer\n",
 
 	End of patch.
 
 
 Thank-you in anticipation of your comments.
 
 	Ed

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200107260600.f6Q602N29687>