Commit 37e6ba00720c2786330dec2a9a5081e9e049422f
1 parent
2caa731819
Exists in
master
and in
4 other branches
[SCSI] fix memory leak in initialization
The root cause of the problem is the fact that dev_set_name() now allocates storage instead of using the original array within the kobj. That means that the SCSI assumption that if you haven't made the containing object or any sub objects visible, you can just destroy it (and its component devices) lock stock and barrel becomes false. Fix this by doing the get of sdev_dev at parent time and thus do an extra put of it in scsi_destroy_sdev() (and all other destruction without add paths). Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Showing 2 changed files with 4 additions and 5 deletions Side-by-side Diff
drivers/scsi/scsi_scan.c
... | ... | @@ -317,6 +317,7 @@ |
317 | 317 | out_device_destroy: |
318 | 318 | scsi_device_set_state(sdev, SDEV_DEL); |
319 | 319 | transport_destroy_device(&sdev->sdev_gendev); |
320 | + put_device(&sdev->sdev_dev); | |
320 | 321 | put_device(&sdev->sdev_gendev); |
321 | 322 | out: |
322 | 323 | if (display_failure_msg) |
... | ... | @@ -957,6 +958,7 @@ |
957 | 958 | if (sdev->host->hostt->slave_destroy) |
958 | 959 | sdev->host->hostt->slave_destroy(sdev); |
959 | 960 | transport_destroy_device(&sdev->sdev_gendev); |
961 | + put_device(&sdev->sdev_dev); | |
960 | 962 | put_device(&sdev->sdev_gendev); |
961 | 963 | } |
962 | 964 |
drivers/scsi/scsi_sysfs.c
... | ... | @@ -864,10 +864,6 @@ |
864 | 864 | goto clean_device; |
865 | 865 | } |
866 | 866 | |
867 | - /* take a reference for the sdev_dev; this is | |
868 | - * released by the sdev_class .release */ | |
869 | - get_device(&sdev->sdev_gendev); | |
870 | - | |
871 | 867 | /* create queue files, which may be writable, depending on the host */ |
872 | 868 | if (sdev->host->hostt->change_queue_depth) |
873 | 869 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); |
... | ... | @@ -917,6 +913,7 @@ |
917 | 913 | |
918 | 914 | device_del(&sdev->sdev_gendev); |
919 | 915 | transport_destroy_device(&sdev->sdev_gendev); |
916 | + put_device(&sdev->sdev_dev); | |
920 | 917 | put_device(&sdev->sdev_gendev); |
921 | 918 | |
922 | 919 | return error; |
... | ... | @@ -1065,7 +1062,7 @@ |
1065 | 1062 | sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); |
1066 | 1063 | |
1067 | 1064 | device_initialize(&sdev->sdev_dev); |
1068 | - sdev->sdev_dev.parent = &sdev->sdev_gendev; | |
1065 | + sdev->sdev_dev.parent = get_device(&sdev->sdev_gendev); | |
1069 | 1066 | sdev->sdev_dev.class = &sdev_class; |
1070 | 1067 | dev_set_name(&sdev->sdev_dev, "%d:%d:%d:%d", |
1071 | 1068 | sdev->host->host_no, sdev->channel, sdev->id, sdev->lun); |