Early-boot kernel panics from udev-165/extras/ata_id/ata_id.c

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello,
There is a problem in udev-165/extras/ata_id/ata_id.c resulting in random early boot kernel panics. As it stands, udev-165 is not usable because the boot panics occur to frequently. The systems are GNU/Linux i686 with linux-2.6.36.2 and linux-2.6.37, gcc-4.5.1, and glibc-2.12.1.

By "random," I mean that the panics don't occur on every boot, or on every pc I've tried. The panics do not occur for udev-164. The problem code in udev-165 is in the "disk_identify_packet_device_command" function (see line 270) where an sg3 'ATA Pass-Through' command is issued to a cd/dvd device:

253         ret = ioctl(fd, SG_IO, &io_v4);
254         if (ret != 0) {
255 /* could be that the driver doesn't do version 4, try version 3 */
256                 if (errno == EINVAL) {
257                         struct sg_io_hdr io_hdr;
258
259                         memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
260                         io_hdr.interface_id = 'S';
261                         io_hdr.cmdp = (unsigned char*) cdb;
262                         io_hdr.cmd_len = sizeof (cdb);
263                         io_hdr.dxferp = buf;
264                         io_hdr.dxfer_len = buf_len;
265                         io_hdr.sbp = sense;
266                         io_hdr.mx_sb_len = sizeof (sense);
267                         io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
268                         io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
269
270 ret = ioctl(fd, SG_IO, &io_hdr); <-- random kernel panics result from this call ***
271                         if (ret != 0)
272                                 goto out;
273                 } else {
274                         goto out;
275                 }
276         }
277
278         if (!(sense[0] == 0x72 && desc[0] == 0x9 && desc[1] == 0x0c)) {
279                 errno = EIO;
280                 ret = -1;
281                 goto out;
282         }
283
284  out:
285         return ret;
286 }

While by no means a fix of course, simply commenting out line 270 above appears to side-step the issue. Also, suspecting a buffer alignment issue, I built udev-165 with the attached patch, and thus far, no kernel panics have occurred.

I realize that allocating the sense and response buffers in this manner shouldn't be necessary or even a good idea; my hope is that it might shed some light on the cause of the panics. I suspect that this issue is likely a kernel problem (not a udev problem), but do you have any thoughts/ideas on how to track down the problem?

John
--- udev-165.old/extras/ata_id/ata_id.c	2010-11-09 19:30:53.000000000 -0500
+++ udev-165.new/extras/ata_id/ata_id.c	2011-01-05 03:11:06.629999372 -0500
@@ -208,7 +208,9 @@
 {
 	struct sg_io_v4 io_v4;
 	uint8_t cdb[16];
-	uint8_t sense[32];
+	// Allocate page-aligned memory, rather than using an array (uint8_t sense[32]); jps
+	uint8_t* sense;
+	posix_memalign((void**)&sense, sysconf(_SC_PAGESIZE), 32);
 	uint8_t *desc = sense+8;
 	int ret;
 
@@ -251,7 +253,7 @@
 	io_v4.timeout = COMMAND_TIMEOUT_MSEC;
 
 	ret = ioctl(fd, SG_IO, &io_v4);
-	if (ret != 0) {
+	if (ret < 0) {
 		/* could be that the driver doesn't do version 4, try version 3 */
 		if (errno == EINVAL) {
 			struct sg_io_hdr io_hdr;
@@ -268,7 +270,7 @@
 			io_hdr.timeout = COMMAND_TIMEOUT_MSEC;
 
 			ret = ioctl(fd, SG_IO, &io_hdr);
-			if (ret != 0)
+			if (ret < 0)
 				goto out;
 		} else {
 			goto out;
@@ -282,6 +284,7 @@
 	}
 
  out:
+	free(sense);
 	return ret;
 }
 
@@ -447,7 +450,9 @@
 {
 	struct udev *udev;
 	struct hd_driveid id;
-	uint8_t identify[512];
+	// Allocate page-aligned memory, rather than using an array (uint8_t identify[512]); jps
+	uint8_t* identify;
+	posix_memalign((void**)&identify, sysconf(_SC_PAGESIZE), 512);
 	char model[41];
 	char model_enc[256];
 	char serial[21];
@@ -709,5 +714,6 @@
 exit:
 	udev_unref(udev);
 	udev_log_close();
+	free(identify);
 	return rc;
 }

[Index of Archives]     [Linux Kernel]     [Linux DVB]     [Asterisk Internet PBX]     [DCCP]     [Netdev]     [X.org]     [Util Linux NG]     [Fedora Women]     [ALSA Devel]     [Linux USB]

  Powered by Linux