mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-04-09 01:47:20 -04:00
scsi: mpi3mr: Synchronize access to ioctl data buffer
The driver serializes ioctls through a mutex lock but access to the ioctl data buffer is not guarded by the mutex. This results in multiple user threads being able to write to the driver's ioctl buffer simultaneously. Protect the ioctl buffer with the ioctl mutex. Signed-off-by: Sumit Saxena <sumit.saxena@broadcom.com> Signed-off-by: Ranjan Kumar <ranjan.kumar@broadcom.com> Link: https://lore.kernel.org/r/20241110194405.10108-2-ranjan.kumar@broadcom.com Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
committed by
Martin K. Petersen
parent
6050471545
commit
367ac16e5f
@@ -2329,6 +2329,15 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
if (!mrioc)
|
||||
return -ENODEV;
|
||||
|
||||
if (mutex_lock_interruptible(&mrioc->bsg_cmds.mutex))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (mrioc->bsg_cmds.state & MPI3MR_CMD_PENDING) {
|
||||
dprint_bsg_err(mrioc, "%s: command is in use\n", __func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (!mrioc->ioctl_sges_allocated) {
|
||||
dprint_bsg_err(mrioc, "%s: DMA memory was not allocated\n",
|
||||
__func__);
|
||||
@@ -2339,13 +2348,16 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
karg->timeout = MPI3MR_APP_DEFAULT_TIMEOUT;
|
||||
|
||||
mpi_req = kzalloc(MPI3MR_ADMIN_REQ_FRAME_SZ, GFP_KERNEL);
|
||||
if (!mpi_req)
|
||||
if (!mpi_req) {
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mpi_header = (struct mpi3_request_header *)mpi_req;
|
||||
|
||||
bufcnt = karg->buf_entry_list.num_of_entries;
|
||||
drv_bufs = kzalloc((sizeof(*drv_bufs) * bufcnt), GFP_KERNEL);
|
||||
if (!drv_bufs) {
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -2353,6 +2365,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dout_buf = kzalloc(job->request_payload.payload_len,
|
||||
GFP_KERNEL);
|
||||
if (!dout_buf) {
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -2360,6 +2373,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
din_buf = kzalloc(job->reply_payload.payload_len,
|
||||
GFP_KERNEL);
|
||||
if (!din_buf) {
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@@ -2435,6 +2449,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
(mpi_msg_size > MPI3MR_ADMIN_REQ_FRAME_SZ)) {
|
||||
dprint_bsg_err(mrioc, "%s: invalid MPI message size\n",
|
||||
__func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2447,6 +2462,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
if (invalid_be) {
|
||||
dprint_bsg_err(mrioc, "%s: invalid buffer entries passed\n",
|
||||
__func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2454,12 +2470,14 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
if (sgl_dout_iter > (dout_buf + job->request_payload.payload_len)) {
|
||||
dprint_bsg_err(mrioc, "%s: data_out buffer length mismatch\n",
|
||||
__func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (sgl_din_iter > (din_buf + job->reply_payload.payload_len)) {
|
||||
dprint_bsg_err(mrioc, "%s: data_in buffer length mismatch\n",
|
||||
__func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2472,6 +2490,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dprint_bsg_err(mrioc, "%s:%d: invalid data transfer size passed for function 0x%x din_size = %d, dout_size = %d\n",
|
||||
__func__, __LINE__, mpi_header->function, din_size,
|
||||
dout_size);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2480,6 +2499,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dprint_bsg_err(mrioc,
|
||||
"%s:%d: invalid data transfer size passed for function 0x%x din_size=%d\n",
|
||||
__func__, __LINE__, mpi_header->function, din_size);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2487,6 +2507,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dprint_bsg_err(mrioc,
|
||||
"%s:%d: invalid data transfer size passed for function 0x%x dout_size = %d\n",
|
||||
__func__, __LINE__, mpi_header->function, dout_size);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2497,6 +2518,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
dprint_bsg_err(mrioc, "%s:%d: invalid message size passed:%d:%d:%d:%d\n",
|
||||
__func__, __LINE__, din_cnt, dout_cnt, din_size,
|
||||
dout_size);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
rval = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -2544,6 +2566,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
continue;
|
||||
if (mpi3mr_map_data_buffer_dma(mrioc, drv_buf_iter, desc_count)) {
|
||||
rval = -ENOMEM;
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
dprint_bsg_err(mrioc, "%s:%d: mapping data buffers failed\n",
|
||||
__func__, __LINE__);
|
||||
goto out;
|
||||
@@ -2556,20 +2579,11 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job)
|
||||
sense_buff_k = kzalloc(erbsz, GFP_KERNEL);
|
||||
if (!sense_buff_k) {
|
||||
rval = -ENOMEM;
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (mutex_lock_interruptible(&mrioc->bsg_cmds.mutex)) {
|
||||
rval = -ERESTARTSYS;
|
||||
goto out;
|
||||
}
|
||||
if (mrioc->bsg_cmds.state & MPI3MR_CMD_PENDING) {
|
||||
rval = -EAGAIN;
|
||||
dprint_bsg_err(mrioc, "%s: command is in use\n", __func__);
|
||||
mutex_unlock(&mrioc->bsg_cmds.mutex);
|
||||
goto out;
|
||||
}
|
||||
if (mrioc->unrecoverable) {
|
||||
dprint_bsg_err(mrioc, "%s: unrecoverable controller\n",
|
||||
__func__);
|
||||
|
||||
Reference in New Issue
Block a user