Skip to content

Commit 138125f

Browse files
Al Viromartinkpetersen
authored andcommitted
scsi: hpsa: Lift {BIG_,}IOCTL_Command_struct copy{in,out} into hpsa_ioctl()
Link: https://lore.kernel.org/r/[email protected] Acked-by: Don Brace <[email protected]> Tested-by: Don Brace <[email protected]> Signed-off-by: Al Viro <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 7b6668d commit 138125f

File tree

1 file changed

+56
-60
lines changed

1 file changed

+56
-60
lines changed

drivers/scsi/hpsa.c

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -6358,37 +6358,33 @@ static int hpsa_getdrivver_ioctl(struct ctlr_info *h, void __user *argp)
63586358
return 0;
63596359
}
63606360

6361-
static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
6361+
static int hpsa_passthru_ioctl(struct ctlr_info *h,
6362+
IOCTL_Command_struct *iocommand)
63626363
{
6363-
IOCTL_Command_struct iocommand;
63646364
struct CommandList *c;
63656365
char *buff = NULL;
63666366
u64 temp64;
63676367
int rc = 0;
63686368

6369-
if (!argp)
6370-
return -EINVAL;
63716369
if (!capable(CAP_SYS_RAWIO))
63726370
return -EPERM;
6373-
if (copy_from_user(&iocommand, argp, sizeof(iocommand)))
6374-
return -EFAULT;
6375-
if ((iocommand.buf_size < 1) &&
6376-
(iocommand.Request.Type.Direction != XFER_NONE)) {
6371+
if ((iocommand->buf_size < 1) &&
6372+
(iocommand->Request.Type.Direction != XFER_NONE)) {
63776373
return -EINVAL;
63786374
}
6379-
if (iocommand.buf_size > 0) {
6380-
buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
6375+
if (iocommand->buf_size > 0) {
6376+
buff = kmalloc(iocommand->buf_size, GFP_KERNEL);
63816377
if (buff == NULL)
63826378
return -ENOMEM;
6383-
if (iocommand.Request.Type.Direction & XFER_WRITE) {
6379+
if (iocommand->Request.Type.Direction & XFER_WRITE) {
63846380
/* Copy the data into the buffer we created */
6385-
if (copy_from_user(buff, iocommand.buf,
6386-
iocommand.buf_size)) {
6381+
if (copy_from_user(buff, iocommand->buf,
6382+
iocommand->buf_size)) {
63876383
rc = -EFAULT;
63886384
goto out_kfree;
63896385
}
63906386
} else {
6391-
memset(buff, 0, iocommand.buf_size);
6387+
memset(buff, 0, iocommand->buf_size);
63926388
}
63936389
}
63946390
c = cmd_alloc(h);
@@ -6398,36 +6394,36 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
63986394
c->scsi_cmd = SCSI_CMD_BUSY;
63996395
/* Fill in Command Header */
64006396
c->Header.ReplyQueue = 0; /* unused in simple mode */
6401-
if (iocommand.buf_size > 0) { /* buffer to fill */
6397+
if (iocommand->buf_size > 0) { /* buffer to fill */
64026398
c->Header.SGList = 1;
64036399
c->Header.SGTotal = cpu_to_le16(1);
64046400
} else { /* no buffers to fill */
64056401
c->Header.SGList = 0;
64066402
c->Header.SGTotal = cpu_to_le16(0);
64076403
}
6408-
memcpy(&c->Header.LUN, &iocommand.LUN_info, sizeof(c->Header.LUN));
6404+
memcpy(&c->Header.LUN, &iocommand->LUN_info, sizeof(c->Header.LUN));
64096405

64106406
/* Fill in Request block */
6411-
memcpy(&c->Request, &iocommand.Request,
6407+
memcpy(&c->Request, &iocommand->Request,
64126408
sizeof(c->Request));
64136409

64146410
/* Fill in the scatter gather information */
6415-
if (iocommand.buf_size > 0) {
6411+
if (iocommand->buf_size > 0) {
64166412
temp64 = dma_map_single(&h->pdev->dev, buff,
6417-
iocommand.buf_size, DMA_BIDIRECTIONAL);
6413+
iocommand->buf_size, DMA_BIDIRECTIONAL);
64186414
if (dma_mapping_error(&h->pdev->dev, (dma_addr_t) temp64)) {
64196415
c->SG[0].Addr = cpu_to_le64(0);
64206416
c->SG[0].Len = cpu_to_le32(0);
64216417
rc = -ENOMEM;
64226418
goto out;
64236419
}
64246420
c->SG[0].Addr = cpu_to_le64(temp64);
6425-
c->SG[0].Len = cpu_to_le32(iocommand.buf_size);
6421+
c->SG[0].Len = cpu_to_le32(iocommand->buf_size);
64266422
c->SG[0].Ext = cpu_to_le32(HPSA_SG_LAST); /* not chaining */
64276423
}
64286424
rc = hpsa_scsi_do_simple_cmd(h, c, DEFAULT_REPLY_QUEUE,
64296425
NO_TIMEOUT);
6430-
if (iocommand.buf_size > 0)
6426+
if (iocommand->buf_size > 0)
64316427
hpsa_pci_unmap(h->pdev, c, 1, DMA_BIDIRECTIONAL);
64326428
check_ioctl_unit_attention(h, c);
64336429
if (rc) {
@@ -6436,16 +6432,12 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
64366432
}
64376433

64386434
/* Copy the error information out */
6439-
memcpy(&iocommand.error_info, c->err_info,
6440-
sizeof(iocommand.error_info));
6441-
if (copy_to_user(argp, &iocommand, sizeof(iocommand))) {
6442-
rc = -EFAULT;
6443-
goto out;
6444-
}
6445-
if ((iocommand.Request.Type.Direction & XFER_READ) &&
6446-
iocommand.buf_size > 0) {
6435+
memcpy(&iocommand->error_info, c->err_info,
6436+
sizeof(iocommand->error_info));
6437+
if ((iocommand->Request.Type.Direction & XFER_READ) &&
6438+
iocommand->buf_size > 0) {
64476439
/* Copy the data out of the buffer we created */
6448-
if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
6440+
if (copy_to_user(iocommand->buf, buff, iocommand->buf_size)) {
64496441
rc = -EFAULT;
64506442
goto out;
64516443
}
@@ -6457,9 +6449,9 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
64576449
return rc;
64586450
}
64596451

6460-
static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
6452+
static int hpsa_big_passthru_ioctl(struct ctlr_info *h,
6453+
BIG_IOCTL_Command_struct *ioc)
64616454
{
6462-
BIG_IOCTL_Command_struct *ioc;
64636455
struct CommandList *c;
64646456
unsigned char **buff = NULL;
64656457
int *buff_size = NULL;
@@ -6470,29 +6462,17 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
64706462
u32 sz;
64716463
BYTE __user *data_ptr;
64726464

6473-
if (!argp)
6474-
return -EINVAL;
64756465
if (!capable(CAP_SYS_RAWIO))
64766466
return -EPERM;
6477-
ioc = vmemdup_user(argp, sizeof(*ioc));
6478-
if (IS_ERR(ioc)) {
6479-
status = PTR_ERR(ioc);
6480-
goto cleanup1;
6481-
}
6467+
64826468
if ((ioc->buf_size < 1) &&
6483-
(ioc->Request.Type.Direction != XFER_NONE)) {
6484-
status = -EINVAL;
6485-
goto cleanup1;
6486-
}
6469+
(ioc->Request.Type.Direction != XFER_NONE))
6470+
return -EINVAL;
64876471
/* Check kmalloc limits using all SGs */
6488-
if (ioc->malloc_size > MAX_KMALLOC_SIZE) {
6489-
status = -EINVAL;
6490-
goto cleanup1;
6491-
}
6492-
if (ioc->buf_size > ioc->malloc_size * SG_ENTRIES_IN_CMD) {
6493-
status = -EINVAL;
6494-
goto cleanup1;
6495-
}
6472+
if (ioc->malloc_size > MAX_KMALLOC_SIZE)
6473+
return -EINVAL;
6474+
if (ioc->buf_size > ioc->malloc_size * SG_ENTRIES_IN_CMD)
6475+
return -EINVAL;
64966476
buff = kcalloc(SG_ENTRIES_IN_CMD, sizeof(char *), GFP_KERNEL);
64976477
if (!buff) {
64986478
status = -ENOMEM;
@@ -6565,10 +6545,6 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
65656545

65666546
/* Copy the error information out */
65676547
memcpy(&ioc->error_info, c->err_info, sizeof(ioc->error_info));
6568-
if (copy_to_user(argp, ioc, sizeof(*ioc))) {
6569-
status = -EFAULT;
6570-
goto cleanup0;
6571-
}
65726548
if ((ioc->Request.Type.Direction & XFER_READ) && ioc->buf_size > 0) {
65736549
int i;
65746550

@@ -6594,7 +6570,6 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
65946570
kfree(buff);
65956571
}
65966572
kfree(buff_size);
6597-
kvfree(ioc);
65986573
return status;
65996574
}
66006575

@@ -6628,18 +6603,39 @@ static int hpsa_ioctl(struct scsi_device *dev, unsigned int cmd,
66286603
return hpsa_getpciinfo_ioctl(h, argp);
66296604
case CCISS_GETDRIVVER:
66306605
return hpsa_getdrivver_ioctl(h, argp);
6631-
case CCISS_PASSTHRU:
6606+
case CCISS_PASSTHRU: {
6607+
IOCTL_Command_struct iocommand;
6608+
6609+
if (!argp)
6610+
return -EINVAL;
6611+
if (copy_from_user(&iocommand, argp, sizeof(iocommand)))
6612+
return -EFAULT;
66326613
if (atomic_dec_if_positive(&h->passthru_cmds_avail) < 0)
66336614
return -EAGAIN;
6634-
rc = hpsa_passthru_ioctl(h, argp);
6615+
rc = hpsa_passthru_ioctl(h, &iocommand);
66356616
atomic_inc(&h->passthru_cmds_avail);
6617+
if (!rc && copy_to_user(argp, &iocommand, sizeof(iocommand)))
6618+
rc = -EFAULT;
66366619
return rc;
6637-
case CCISS_BIG_PASSTHRU:
6620+
}
6621+
case CCISS_BIG_PASSTHRU: {
6622+
BIG_IOCTL_Command_struct *ioc;
6623+
if (!argp)
6624+
return -EINVAL;
66386625
if (atomic_dec_if_positive(&h->passthru_cmds_avail) < 0)
66396626
return -EAGAIN;
6640-
rc = hpsa_big_passthru_ioctl(h, argp);
6627+
ioc = vmemdup_user(argp, sizeof(*ioc));
6628+
if (IS_ERR(ioc)) {
6629+
atomic_inc(&h->passthru_cmds_avail);
6630+
return PTR_ERR(ioc);
6631+
}
6632+
rc = hpsa_big_passthru_ioctl(h, ioc);
66416633
atomic_inc(&h->passthru_cmds_avail);
6634+
if (!rc && copy_to_user(argp, ioc, sizeof(*ioc)))
6635+
rc = -EFAULT;
6636+
kvfree(ioc);
66426637
return rc;
6638+
}
66436639
default:
66446640
return -ENOTTY;
66456641
}

0 commit comments

Comments
 (0)