struct request *rq;
struct bio *bio;
char sense[SCSI_SENSE_BUFFERSIZE];
- unsigned char cdb[BLK_MAX_CDB];
void *buffer;
if (hdr->interface_id != 'S')
if (hdr->dxfer_len > (q->max_sectors << 9))
return -EIO;
- if (copy_from_user(cdb, hdr->cmdp, hdr->cmd_len))
- return -EFAULT;
-
reading = writing = 0;
buffer = NULL;
bio = NULL;
* fill in request structure
*/
rq->cmd_len = hdr->cmd_len;
- memcpy(rq->cmd, cdb, hdr->cmd_len);
+ memcpy(rq->cmd, hdr->cmdp, hdr->cmd_len);
if (sizeof(rq->cmd) != hdr->cmd_len)
memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len);
break;
case SG_IO: {
struct sg_io_hdr hdr;
+ unsigned char cdb[BLK_MAX_CDB], *old_cdb;
- if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr))) {
- err = -EFAULT;
+ err = -EFAULT;
+ if (copy_from_user(&hdr, (struct sg_io_hdr *) arg, sizeof(hdr)))
break;
- }
+ err = -EINVAL;
+ if (hdr.cmd_len > sizeof(rq->cmd))
+ break;
+ err = -EFAULT;
+ if (copy_from_user(cdb, hdr.cmdp, hdr.cmd_len))
+ break;
+
+ old_cdb = hdr.cmdp;
+ hdr.cmdp = cdb;
err = sg_io(q, bdev, &hdr);
+
+ hdr.cmdp = old_cdb;
if (copy_to_user((struct sg_io_hdr *) arg, &hdr, sizeof(hdr)))
err = -EFAULT;
break;