Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[PATCH] sd: fix memory corruption with broken mode page headers

There's a problem in sd where we blindly believe the length of the
headers and block descriptors. Some devices return insane values for
these and cause our length to end up greater than the actual buffer
size, so check to make sure.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Also removed the buffer size magic number (512) and added DPOFUA of
zero to the defaults

Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Al Viro and committed by
Linus Torvalds
48970800 a0124d78

+17 -3
+17 -3
drivers/scsi/sd.c
··· 89 89 #define SD_MAX_RETRIES 5 90 90 #define SD_PASSTHROUGH_RETRIES 1 91 91 92 + /* 93 + * Size of the initial data buffer for mode and read capacity data 94 + */ 95 + #define SD_BUF_SIZE 512 96 + 92 97 static void scsi_disk_release(struct kref *kref); 93 98 94 99 struct scsi_disk { ··· 1244 1239 1245 1240 /* 1246 1241 * read write protect setting, if possible - called only in sd_revalidate_disk() 1247 - * called with buffer of length 512 1242 + * called with buffer of length SD_BUF_SIZE 1248 1243 */ 1249 1244 static void 1250 1245 sd_read_write_protect_flag(struct scsi_disk *sdkp, char *diskname, ··· 1302 1297 1303 1298 /* 1304 1299 * sd_read_cache_type - called only from sd_revalidate_disk() 1305 - * called with buffer of length 512 1300 + * called with buffer of length SD_BUF_SIZE 1306 1301 */ 1307 1302 static void 1308 1303 sd_read_cache_type(struct scsi_disk *sdkp, char *diskname, ··· 1347 1342 1348 1343 /* Take headers and block descriptors into account */ 1349 1344 len += data.header_length + data.block_descriptor_length; 1345 + if (len > SD_BUF_SIZE) 1346 + goto bad_sense; 1350 1347 1351 1348 /* Get the data */ 1352 1349 res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr); ··· 1360 1353 }; 1361 1354 int ct = 0; 1362 1355 int offset = data.header_length + data.block_descriptor_length; 1356 + 1357 + if (offset >= SD_BUF_SIZE - 2) { 1358 + printk(KERN_ERR "%s: malformed MODE SENSE response", 1359 + diskname); 1360 + goto defaults; 1361 + } 1363 1362 1364 1363 if ((buffer[offset] & 0x3f) != modepage) { 1365 1364 printk(KERN_ERR "%s: got wrong page\n", diskname); ··· 1411 1398 diskname); 1412 1399 sdkp->WCE = 0; 1413 1400 sdkp->RCD = 0; 1401 + sdkp->DPOFUA = 0; 1414 1402 } 1415 1403 1416 1404 /** ··· 1435 1421 if (!scsi_device_online(sdp)) 1436 1422 goto out; 1437 1423 1438 - buffer = kmalloc(512, GFP_KERNEL | __GFP_DMA); 1424 + buffer = kmalloc(SD_BUF_SIZE, GFP_KERNEL | __GFP_DMA); 1439 1425 if (!buffer) { 1440 1426 printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation " 1441 1427 "failure.\n");