@@ -254,6 +254,10 @@ static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id);
254
254
static irqreturn_t do_hpsa_intr_msi (int irq , void * dev_id );
255
255
static int hpsa_ioctl (struct scsi_device * dev , unsigned int cmd ,
256
256
void __user * arg );
257
+ static int hpsa_passthru_ioctl (struct ctlr_info * h ,
258
+ IOCTL_Command_struct * iocommand );
259
+ static int hpsa_big_passthru_ioctl (struct ctlr_info * h ,
260
+ BIG_IOCTL_Command_struct * ioc );
257
261
258
262
#ifdef CONFIG_COMPAT
259
263
static int hpsa_compat_ioctl (struct scsi_device * dev , unsigned int cmd ,
@@ -6217,75 +6221,63 @@ static void cmd_free(struct ctlr_info *h, struct CommandList *c)
6217
6221
static int hpsa_ioctl32_passthru (struct scsi_device * dev , unsigned int cmd ,
6218
6222
void __user * arg )
6219
6223
{
6220
- IOCTL32_Command_struct __user * arg32 =
6221
- ( IOCTL32_Command_struct __user * ) arg ;
6224
+ struct ctlr_info * h = sdev_to_hba ( dev );
6225
+ IOCTL32_Command_struct __user * arg32 = arg ;
6222
6226
IOCTL_Command_struct arg64 ;
6223
- IOCTL_Command_struct __user * p = compat_alloc_user_space (sizeof (arg64 ));
6224
6227
int err ;
6225
6228
u32 cp ;
6226
6229
6227
- memset (& arg64 , 0 , sizeof (arg64 ));
6228
- err = 0 ;
6229
- err |= copy_from_user (& arg64 .LUN_info , & arg32 -> LUN_info ,
6230
- sizeof (arg64 .LUN_info ));
6231
- err |= copy_from_user (& arg64 .Request , & arg32 -> Request ,
6232
- sizeof (arg64 .Request ));
6233
- err |= copy_from_user (& arg64 .error_info , & arg32 -> error_info ,
6234
- sizeof (arg64 .error_info ));
6235
- err |= get_user (arg64 .buf_size , & arg32 -> buf_size );
6236
- err |= get_user (cp , & arg32 -> buf );
6237
- arg64 .buf = compat_ptr (cp );
6238
- err |= copy_to_user (p , & arg64 , sizeof (arg64 ));
6230
+ if (!arg )
6231
+ return - EINVAL ;
6239
6232
6240
- if (err )
6233
+ memset (& arg64 , 0 , sizeof (arg64 ));
6234
+ if (copy_from_user (& arg64 , arg32 , offsetof(IOCTL_Command_struct , buf )))
6235
+ return - EFAULT ;
6236
+ if (get_user (cp , & arg32 -> buf ))
6241
6237
return - EFAULT ;
6238
+ arg64 .buf = compat_ptr (cp );
6242
6239
6243
- err = hpsa_ioctl (dev , CCISS_PASSTHRU , p );
6240
+ if (atomic_dec_if_positive (& h -> passthru_cmds_avail ) < 0 )
6241
+ return - EAGAIN ;
6242
+ err = hpsa_passthru_ioctl (h , & arg64 );
6243
+ atomic_inc (& h -> passthru_cmds_avail );
6244
6244
if (err )
6245
6245
return err ;
6246
- err |= copy_in_user (& arg32 -> error_info , & p -> error_info ,
6247
- sizeof (arg32 -> error_info ));
6248
- if (err )
6246
+ if (copy_to_user (& arg32 -> error_info , & arg64 .error_info ,
6247
+ sizeof (arg32 -> error_info )))
6249
6248
return - EFAULT ;
6250
- return err ;
6249
+ return 0 ;
6251
6250
}
6252
6251
6253
6252
static int hpsa_ioctl32_big_passthru (struct scsi_device * dev ,
6254
6253
unsigned int cmd , void __user * arg )
6255
6254
{
6256
- BIG_IOCTL32_Command_struct __user * arg32 =
6257
- ( BIG_IOCTL32_Command_struct __user * ) arg ;
6255
+ struct ctlr_info * h = sdev_to_hba ( dev );
6256
+ BIG_IOCTL32_Command_struct __user * arg32 = arg ;
6258
6257
BIG_IOCTL_Command_struct arg64 ;
6259
- BIG_IOCTL_Command_struct __user * p =
6260
- compat_alloc_user_space (sizeof (arg64 ));
6261
6258
int err ;
6262
6259
u32 cp ;
6263
6260
6261
+ if (!arg )
6262
+ return - EINVAL ;
6264
6263
memset (& arg64 , 0 , sizeof (arg64 ));
6265
- err = 0 ;
6266
- err |= copy_from_user (& arg64 .LUN_info , & arg32 -> LUN_info ,
6267
- sizeof (arg64 .LUN_info ));
6268
- err |= copy_from_user (& arg64 .Request , & arg32 -> Request ,
6269
- sizeof (arg64 .Request ));
6270
- err |= copy_from_user (& arg64 .error_info , & arg32 -> error_info ,
6271
- sizeof (arg64 .error_info ));
6272
- err |= get_user (arg64 .buf_size , & arg32 -> buf_size );
6273
- err |= get_user (arg64 .malloc_size , & arg32 -> malloc_size );
6274
- err |= get_user (cp , & arg32 -> buf );
6275
- arg64 .buf = compat_ptr (cp );
6276
- err |= copy_to_user (p , & arg64 , sizeof (arg64 ));
6277
-
6278
- if (err )
6264
+ if (copy_from_user (& arg64 , arg32 ,
6265
+ offsetof(BIG_IOCTL32_Command_struct , buf )))
6266
+ return - EFAULT ;
6267
+ if (get_user (cp , & arg32 -> buf ))
6279
6268
return - EFAULT ;
6269
+ arg64 .buf = compat_ptr (cp );
6280
6270
6281
- err = hpsa_ioctl (dev , CCISS_BIG_PASSTHRU , p );
6271
+ if (atomic_dec_if_positive (& h -> passthru_cmds_avail ) < 0 )
6272
+ return - EAGAIN ;
6273
+ err = hpsa_big_passthru_ioctl (h , & arg64 );
6274
+ atomic_inc (& h -> passthru_cmds_avail );
6282
6275
if (err )
6283
6276
return err ;
6284
- err |= copy_in_user (& arg32 -> error_info , & p -> error_info ,
6285
- sizeof (arg32 -> error_info ));
6286
- if (err )
6277
+ if (copy_to_user (& arg32 -> error_info , & arg64 .error_info ,
6278
+ sizeof (arg32 -> error_info )))
6287
6279
return - EFAULT ;
6288
- return err ;
6280
+ return 0 ;
6289
6281
}
6290
6282
6291
6283
static int hpsa_compat_ioctl (struct scsi_device * dev , unsigned int cmd ,
@@ -6358,37 +6350,33 @@ static int hpsa_getdrivver_ioctl(struct ctlr_info *h, void __user *argp)
6358
6350
return 0 ;
6359
6351
}
6360
6352
6361
- static int hpsa_passthru_ioctl (struct ctlr_info * h , void __user * argp )
6353
+ static int hpsa_passthru_ioctl (struct ctlr_info * h ,
6354
+ IOCTL_Command_struct * iocommand )
6362
6355
{
6363
- IOCTL_Command_struct iocommand ;
6364
6356
struct CommandList * c ;
6365
6357
char * buff = NULL ;
6366
6358
u64 temp64 ;
6367
6359
int rc = 0 ;
6368
6360
6369
- if (!argp )
6370
- return - EINVAL ;
6371
6361
if (!capable (CAP_SYS_RAWIO ))
6372
6362
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 )) {
6363
+ if ((iocommand -> buf_size < 1 ) &&
6364
+ (iocommand -> Request .Type .Direction != XFER_NONE )) {
6377
6365
return - EINVAL ;
6378
6366
}
6379
- if (iocommand . buf_size > 0 ) {
6380
- buff = kmalloc (iocommand . buf_size , GFP_KERNEL );
6367
+ if (iocommand -> buf_size > 0 ) {
6368
+ buff = kmalloc (iocommand -> buf_size , GFP_KERNEL );
6381
6369
if (buff == NULL )
6382
6370
return - ENOMEM ;
6383
- if (iocommand . Request .Type .Direction & XFER_WRITE ) {
6371
+ if (iocommand -> Request .Type .Direction & XFER_WRITE ) {
6384
6372
/* Copy the data into the buffer we created */
6385
- if (copy_from_user (buff , iocommand . buf ,
6386
- iocommand . buf_size )) {
6373
+ if (copy_from_user (buff , iocommand -> buf ,
6374
+ iocommand -> buf_size )) {
6387
6375
rc = - EFAULT ;
6388
6376
goto out_kfree ;
6389
6377
}
6390
6378
} else {
6391
- memset (buff , 0 , iocommand . buf_size );
6379
+ memset (buff , 0 , iocommand -> buf_size );
6392
6380
}
6393
6381
}
6394
6382
c = cmd_alloc (h );
@@ -6398,36 +6386,36 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
6398
6386
c -> scsi_cmd = SCSI_CMD_BUSY ;
6399
6387
/* Fill in Command Header */
6400
6388
c -> Header .ReplyQueue = 0 ; /* unused in simple mode */
6401
- if (iocommand . buf_size > 0 ) { /* buffer to fill */
6389
+ if (iocommand -> buf_size > 0 ) { /* buffer to fill */
6402
6390
c -> Header .SGList = 1 ;
6403
6391
c -> Header .SGTotal = cpu_to_le16 (1 );
6404
6392
} else { /* no buffers to fill */
6405
6393
c -> Header .SGList = 0 ;
6406
6394
c -> Header .SGTotal = cpu_to_le16 (0 );
6407
6395
}
6408
- memcpy (& c -> Header .LUN , & iocommand . LUN_info , sizeof (c -> Header .LUN ));
6396
+ memcpy (& c -> Header .LUN , & iocommand -> LUN_info , sizeof (c -> Header .LUN ));
6409
6397
6410
6398
/* Fill in Request block */
6411
- memcpy (& c -> Request , & iocommand . Request ,
6399
+ memcpy (& c -> Request , & iocommand -> Request ,
6412
6400
sizeof (c -> Request ));
6413
6401
6414
6402
/* Fill in the scatter gather information */
6415
- if (iocommand . buf_size > 0 ) {
6403
+ if (iocommand -> buf_size > 0 ) {
6416
6404
temp64 = dma_map_single (& h -> pdev -> dev , buff ,
6417
- iocommand . buf_size , DMA_BIDIRECTIONAL );
6405
+ iocommand -> buf_size , DMA_BIDIRECTIONAL );
6418
6406
if (dma_mapping_error (& h -> pdev -> dev , (dma_addr_t ) temp64 )) {
6419
6407
c -> SG [0 ].Addr = cpu_to_le64 (0 );
6420
6408
c -> SG [0 ].Len = cpu_to_le32 (0 );
6421
6409
rc = - ENOMEM ;
6422
6410
goto out ;
6423
6411
}
6424
6412
c -> SG [0 ].Addr = cpu_to_le64 (temp64 );
6425
- c -> SG [0 ].Len = cpu_to_le32 (iocommand . buf_size );
6413
+ c -> SG [0 ].Len = cpu_to_le32 (iocommand -> buf_size );
6426
6414
c -> SG [0 ].Ext = cpu_to_le32 (HPSA_SG_LAST ); /* not chaining */
6427
6415
}
6428
6416
rc = hpsa_scsi_do_simple_cmd (h , c , DEFAULT_REPLY_QUEUE ,
6429
6417
NO_TIMEOUT );
6430
- if (iocommand . buf_size > 0 )
6418
+ if (iocommand -> buf_size > 0 )
6431
6419
hpsa_pci_unmap (h -> pdev , c , 1 , DMA_BIDIRECTIONAL );
6432
6420
check_ioctl_unit_attention (h , c );
6433
6421
if (rc ) {
@@ -6436,16 +6424,12 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
6436
6424
}
6437
6425
6438
6426
/* 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 ) {
6427
+ memcpy (& iocommand -> error_info , c -> err_info ,
6428
+ sizeof (iocommand -> error_info ));
6429
+ if ((iocommand -> Request .Type .Direction & XFER_READ ) &&
6430
+ iocommand -> buf_size > 0 ) {
6447
6431
/* Copy the data out of the buffer we created */
6448
- if (copy_to_user (iocommand . buf , buff , iocommand . buf_size )) {
6432
+ if (copy_to_user (iocommand -> buf , buff , iocommand -> buf_size )) {
6449
6433
rc = - EFAULT ;
6450
6434
goto out ;
6451
6435
}
@@ -6457,9 +6441,9 @@ static int hpsa_passthru_ioctl(struct ctlr_info *h, void __user *argp)
6457
6441
return rc ;
6458
6442
}
6459
6443
6460
- static int hpsa_big_passthru_ioctl (struct ctlr_info * h , void __user * argp )
6444
+ static int hpsa_big_passthru_ioctl (struct ctlr_info * h ,
6445
+ BIG_IOCTL_Command_struct * ioc )
6461
6446
{
6462
- BIG_IOCTL_Command_struct * ioc ;
6463
6447
struct CommandList * c ;
6464
6448
unsigned char * * buff = NULL ;
6465
6449
int * buff_size = NULL ;
@@ -6470,29 +6454,17 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
6470
6454
u32 sz ;
6471
6455
BYTE __user * data_ptr ;
6472
6456
6473
- if (!argp )
6474
- return - EINVAL ;
6475
6457
if (!capable (CAP_SYS_RAWIO ))
6476
6458
return - EPERM ;
6477
- ioc = vmemdup_user (argp , sizeof (* ioc ));
6478
- if (IS_ERR (ioc )) {
6479
- status = PTR_ERR (ioc );
6480
- goto cleanup1 ;
6481
- }
6459
+
6482
6460
if ((ioc -> buf_size < 1 ) &&
6483
- (ioc -> Request .Type .Direction != XFER_NONE )) {
6484
- status = - EINVAL ;
6485
- goto cleanup1 ;
6486
- }
6461
+ (ioc -> Request .Type .Direction != XFER_NONE ))
6462
+ return - EINVAL ;
6487
6463
/* 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
- }
6464
+ if (ioc -> malloc_size > MAX_KMALLOC_SIZE )
6465
+ return - EINVAL ;
6466
+ if (ioc -> buf_size > ioc -> malloc_size * SG_ENTRIES_IN_CMD )
6467
+ return - EINVAL ;
6496
6468
buff = kcalloc (SG_ENTRIES_IN_CMD , sizeof (char * ), GFP_KERNEL );
6497
6469
if (!buff ) {
6498
6470
status = - ENOMEM ;
@@ -6565,10 +6537,6 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
6565
6537
6566
6538
/* Copy the error information out */
6567
6539
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
- }
6572
6540
if ((ioc -> Request .Type .Direction & XFER_READ ) && ioc -> buf_size > 0 ) {
6573
6541
int i ;
6574
6542
@@ -6594,7 +6562,6 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, void __user *argp)
6594
6562
kfree (buff );
6595
6563
}
6596
6564
kfree (buff_size );
6597
- kvfree (ioc );
6598
6565
return status ;
6599
6566
}
6600
6567
@@ -6610,14 +6577,11 @@ static void check_ioctl_unit_attention(struct ctlr_info *h,
6610
6577
* ioctl
6611
6578
*/
6612
6579
static int hpsa_ioctl (struct scsi_device * dev , unsigned int cmd ,
6613
- void __user * arg )
6580
+ void __user * argp )
6614
6581
{
6615
- struct ctlr_info * h ;
6616
- void __user * argp = (void __user * )arg ;
6582
+ struct ctlr_info * h = sdev_to_hba (dev );
6617
6583
int rc ;
6618
6584
6619
- h = sdev_to_hba (dev );
6620
-
6621
6585
switch (cmd ) {
6622
6586
case CCISS_DEREGDISK :
6623
6587
case CCISS_REGNEWDISK :
@@ -6628,18 +6592,35 @@ static int hpsa_ioctl(struct scsi_device *dev, unsigned int cmd,
6628
6592
return hpsa_getpciinfo_ioctl (h , argp );
6629
6593
case CCISS_GETDRIVVER :
6630
6594
return hpsa_getdrivver_ioctl (h , argp );
6631
- case CCISS_PASSTHRU :
6595
+ case CCISS_PASSTHRU : {
6596
+ IOCTL_Command_struct iocommand ;
6597
+
6598
+ if (!argp )
6599
+ return - EINVAL ;
6600
+ if (copy_from_user (& iocommand , argp , sizeof (iocommand )))
6601
+ return - EFAULT ;
6632
6602
if (atomic_dec_if_positive (& h -> passthru_cmds_avail ) < 0 )
6633
6603
return - EAGAIN ;
6634
- rc = hpsa_passthru_ioctl (h , argp );
6604
+ rc = hpsa_passthru_ioctl (h , & iocommand );
6635
6605
atomic_inc (& h -> passthru_cmds_avail );
6606
+ if (!rc && copy_to_user (argp , & iocommand , sizeof (iocommand )))
6607
+ rc = - EFAULT ;
6636
6608
return rc ;
6637
- case CCISS_BIG_PASSTHRU :
6609
+ }
6610
+ case CCISS_BIG_PASSTHRU : {
6611
+ BIG_IOCTL_Command_struct ioc ;
6612
+ if (!argp )
6613
+ return - EINVAL ;
6614
+ if (copy_from_user (& ioc , argp , sizeof (ioc )))
6615
+ return - EFAULT ;
6638
6616
if (atomic_dec_if_positive (& h -> passthru_cmds_avail ) < 0 )
6639
6617
return - EAGAIN ;
6640
- rc = hpsa_big_passthru_ioctl (h , argp );
6618
+ rc = hpsa_big_passthru_ioctl (h , & ioc );
6641
6619
atomic_inc (& h -> passthru_cmds_avail );
6620
+ if (!rc && copy_to_user (argp , & ioc , sizeof (ioc )))
6621
+ rc = - EFAULT ;
6642
6622
return rc ;
6623
+ }
6643
6624
default :
6644
6625
return - ENOTTY ;
6645
6626
}
0 commit comments