SCSI sd: udev accessing an uninitialized scsi_disk results in a crash
PATCH 1/1 SCSI sd: udev accessing an uninitialized scsi_disk results in a crash
Hi,
sd_probe() calls class_device_add() even before initializing thesdkp->device variable. class_device_add() eventually results in the user mode udev program to be called. udev program can read the the allow_restart attribute of the newly created scsi device. This is resulting in a crash as the show function for allow_restart (i.e sd_show_allow_restart) returns the attribute value by reading the sdkp->device->allow_restart variable. As the sdkp->device is not initialized before calling the user mode hotplug helper, this results in a crash.
The patch below solves it by calling class_device_add() only after the
necessary fields in the scsi_disk structure are initialized properly.
Thanx,
Tomar
---
drivers/scsi/sd.c renamed from drivers/scsi/sd.c.orig +10 -10
@@ -1646,16 +1646,6 @@ static int sd_probe(struct device *dev)if (error) goto out_put; -class_device_initialize (&sdkp->cdev); - sdkp->cdev.dev = &sdp->sdev_gendev; - sdkp->cdev.class = &sd_disk_class; -strncpy (sdkp->cdev.class_id, sdp->sdev_gendev.bus_id,BUS_ID_SIZE ); - -if (class_device_add (&sdkp->cdev)) - goto out_put; - -get_device (&sdp->sdev_gendev); - sdkp->device = sdp; sdkp->driver = &sd_template; sdkp->disk = gd;
@@ -1669,6 +1659,16 @@ static int sd_probe(struct device *dev) sdp->timeout =SD_MOD_TIMEOUT ; } +class_device_initialize (&sdkp->cdev); + sdkp->cdev.dev = &sdp->sdev_gendev; + sdkp->cdev.class = &sd_disk_class; +strncpy (sdkp->cdev.class_id, sdp->sdev_gendev.bus_id,BUS_ID_SIZE ); + +if (class_device_add (&sdkp->cdev)) + goto out_put; + +get_device (&sdp->sdev_gendev); + gd->major =sd_major ((index &0xf0 ) >>4 ); gd->first_minor = ((index &0xf ) <<4 ) | (index &0xfff00 ); gd->minors =16 ;
Quoted 40 lines · On Fri, 2 Feb 2007 17:34:56 +0530 Nagendra Singh Tomar…
Hi,
sd_probe()callsclass_device_add()even before initializing thesdkp->devicevariable.class_device_add()eventually results in the user mode udev program to be called. udev program can read the theallow_restartattribute of the newly created scsi device. This is resulting in a crash as the show function forallow_restart(i.esd_show_allow_restart) returns the attribute value by reading thesdkp->device->allow_restartvariable. As thesdkp->deviceis not initialized before calling the user mode hotplug helper, this results in a crash.
The patch below solves it by callingclass_device_add()only after the
necessary fields in thescsi_diskstructure are initialized properly.drivers/scsi/sd.c renamed from drivers/scsi/sd.c.orig +3
-10@@ -1646,16 +1646,6 @@ static int sd_probe(struct device *dev)if (error) goto out_put; -class_device_initialize (&sdkp->cdev); - sdkp->cdev.dev = &sdp->sdev_gendev; - sdkp->cdev.class = &sd_disk_class; -strncpy (sdkp->cdev.class_id, sdp->sdev_gendev.bus_id,BUS_ID_SIZE ); - -if (class_device_add (&sdkp->cdev)) - goto out_put; - -get_device (&sdp->sdev_gendev); - sdkp->device = sdp; sdkp->driver = &sd_template; sdkp->disk = gd;@@ -1669,6 +1659,16 @@ static int sd_probe(struct device *dev) sdp->timeout =SD_MOD_TIMEOUT ; } +class_device_initialize (&sdkp->cdev); + sdkp->cdev.dev = &sdp->sdev_gendev; + sdkp->cdev.class = &sd_disk_class;
drivers/scsi/sd.c static int sd_probe(struct device *dev) · line 1674
Quoted 10 lines
drivers/scsi/sd.c renamed from drivers/scsi/sd.c.orig +7
-0+strncpy (sdkp->cdev.class_id, sdp->sdev_gendev.bus_id,BUS_ID_SIZE ); + +if (class_device_add (&sdkp->cdev)) + goto out_put; + +get_device (&sdp->sdev_gendev); + gd->major =sd_major ((index &0xf0 ) >>4 ); gd->first_minor = ((index &0xf ) <<4 ) | (index &0xfff00 ); gd->minors =16 ;
Thanks - I'll queue this up for 2.6.20 also.
Quoted 40 lines · Andrew Morton
Quoted 37 lines · On Fri, 2 Feb 2007 17:34:56 +0530 Nagendra Singh Tomar…
Hi,
sd_probe()callsclass_device_add()even before initializing thesdkp->devicevariable.class_device_add()eventually results in the user mode udev program to be called. udev program can read the theallow_restartattribute of the newly created scsi device. This is resulting in a crash as the show function forallow_restart(i.esd_show_allow_restart) returns the attribute value by reading thesdkp->device->allow_restartvariable. As thesdkp->deviceis not initialized before calling the user mode hotplug helper, this results in a crash.
The patch below solves it by callingclass_device_add()only after the
necessary fields in thescsi_diskstructure are initialized properly.drivers/scsi/sd.c renamed from drivers/scsi/sd.c.orig +0
-10@@ -1646,16 +1646,6 @@ static int sd_probe(struct device *dev)if (error) goto out_put; -class_device_initialize (&sdkp->cdev); - sdkp->cdev.dev = &sdp->sdev_gendev; - sdkp->cdev.class = &sd_disk_class; -strncpy (sdkp->cdev.class_id, sdp->sdev_gendev.bus_id,BUS_ID_SIZE ); - -if (class_device_add (&sdkp->cdev)) - goto out_put; - -get_device (&sdp->sdev_gendev); - sdkp->device = sdp; sdkp->driver = &sd_template; sdkp->disk = gd;@@ -1669,6 +1659,16 @@ static int sd_probe(struct device *dev) sdp->timeout =SD_MOD_TIMEOUT ; }
Quoted 15 lines
drivers/scsi/sd.c static int sd_probe(struct device *dev) · line 1674
Quoted 13 lines
drivers/scsi/sd.c renamed from drivers/scsi/sd.c.orig +10
-0+class_device_initialize (&sdkp->cdev); + sdkp->cdev.dev = &sdp->sdev_gendev; + sdkp->cdev.class = &sd_disk_class; +strncpy (sdkp->cdev.class_id, sdp->sdev_gendev.bus_id,BUS_ID_SIZE ); + +if (class_device_add (&sdkp->cdev)) + goto out_put; + +get_device (&sdp->sdev_gendev); + gd->major =sd_major ((index &0xf0 ) >>4 ); gd->first_minor = ((index &0xf ) <<4 ) | (index &0xfff00 ); gd->minors =16 ;Thanks - I'll queue this up for 2.6.20 also.
No objection from me, as long as James says this is ok.
I wonder why we haven't noticed this in the past?
thanks,
greg k-h
Quoted 5 lines · Greg KH
Quoted 1 line
Thanks - I'll queue this up for 2.6.20 also.
No objection from me, as long as James says this is ok.
I wonder why we haven't noticed this in the past?
Because the race is so small ...
I'll queue it in the rc-fixes tree .. I have three others for 2.6.20
James