mbox series

[0/3] scsi: mpi3mr: fix issues found by KASAN

Message ID 20221212015706.2609544-1-shinichiro.kawasaki@wdc.com
Headers show
Series scsi: mpi3mr: fix issues found by KASAN | expand

Message

Shinichiro Kawasaki Dec. 12, 2022, 1:57 a.m. UTC
While I downloaded new firmware to eHBA-9600 on KASAN enabled kernel,
I observed three BUGs. This series addresses them.

Shin'ichiro Kawasaki (3):
  scsi: mpi3mr: fix alltgt_info copy size in mpi3mr_get_all_tgt_info
  scsi: mpi3mr: fix bitmap memory size calculation
  scsi: mpi3mr: fix missing mrioc->evtack_cmds initialization

 drivers/scsi/mpi3mr/mpi3mr_app.c |  9 ++++++++-
 drivers/scsi/mpi3mr/mpi3mr_fw.c  | 25 ++++++++++---------------
 drivers/scsi/mpi3mr/mpi3mr_os.c  |  4 ++++
 3 files changed, 22 insertions(+), 16 deletions(-)

Comments

Damien Le Moal Dec. 12, 2022, 5:27 a.m. UTC | #1
On 12/12/22 10:57, Shin'ichiro Kawasaki wrote:
> The function mpi3mr_get_all_tgt_info calculates size of alltgt_info and
> allocate memory for it. After preparing valid data in alltgt_info, it
> calls sg_copy_from_buffer to copy alltgt_info to job->request_payload,
> specifying length of the payload as copy length. This length is larger
> than the calculated alltgt_info size. It causes memory access to invalid
> address and results in "BUG: KASAN: slab-out-of-bounds". The BUG was
> observed during boot using systems with eHBA-9600. By updating the HBA
> firmware to latest version 8.3.1.0 the BUG was not observed during boot,
> but still observed when command "storcli2 /c0 show" is executed.
> 
> Fix the BUG by specifying the calculated alltgt_info size as copy
> length. Also check that the copy destination payload length is larger
> than the copy length.
> 
> Fixes: f5e6d5a34376 ("scsi: mpi3mr: Add support for driver commands")
> Cc: stable@vger.kernel.org
> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
> ---
>  drivers/scsi/mpi3mr/mpi3mr_app.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c
> index 9baac224b213..f14556d50832 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_app.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c
> @@ -322,6 +322,13 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
>  
>  	kern_entrylen = (num_devices - 1) * sizeof(*devmap_info);
>  	size = sizeof(*alltgt_info) + kern_entrylen;
> +
> +	if (size > job->request_payload.payload_len) {
> +		dprint_bsg_err(mrioc, "%s: too small payload length\n",

"%s: payload length is too small\n" maybe ?

> +			       __func__);
> +		return rval;
> +	}
> +
>  	alltgt_info = kzalloc(size, GFP_KERNEL);
>  	if (!alltgt_info)
>  		return -ENOMEM;
> @@ -358,7 +365,7 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
>  
>  	sg_copy_from_buffer(job->request_payload.sg_list,
>  			    job->request_payload.sg_cnt,
> -			    alltgt_info, job->request_payload.payload_len);
> +			    alltgt_info, size);
>  	rval = 0;
>  out:
>  	kfree(alltgt_info);

Otherwise, looks OK to me.

Reviewed-by: Damien Le Moal
Damien Le Moal Dec. 12, 2022, 5:36 a.m. UTC | #2
On 12/12/22 10:57, Shin'ichiro Kawasaki wrote:
> The commit c1af985d27da ("scsi: mpi3mr: Add Event acknowledgment logic")
> introduced an array mrioc->evtack_cmds. But initialization of the array
> elements was missed. They are just zero cleared. The function
> mpi3mr_complete_evt_ack refers host_tag field of the elements. Due to
> zero value of the host_tag field, the functions calls clear_bit for
> mrico->evtack_cmds_bitmap with wrong bit index. This results in memory
> access to invalid address and "BUG: KASAN: use-after-free". This BUG was
> observed at eHBA-9600 firmware update to version 8.3.1.0. To fix it, add
> the missing initialization of mrioc->evtack_cmds.
> 
> Fixes: c1af985d27da ("scsi: mpi3mr: Add Event acknowledgment logic")
> Cc: stable@vger.kernel.org
> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>

Looks OK to me.

Reviewed-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>


> ---
>  drivers/scsi/mpi3mr/mpi3mr_os.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c
> index 3306de7170f6..6eaeba41072c 100644
> --- a/drivers/scsi/mpi3mr/mpi3mr_os.c
> +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c
> @@ -4952,6 +4952,10 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
>  		mpi3mr_init_drv_cmd(&mrioc->dev_rmhs_cmds[i],
>  		    MPI3MR_HOSTTAG_DEVRMCMD_MIN + i);
>  
> +	for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++)
> +		mpi3mr_init_drv_cmd(&mrioc->evtack_cmds[i],
> +				    MPI3MR_HOSTTAG_EVTACKCMD_MIN + i);
> +
>  	if (pdev->revision)
>  		mrioc->enable_segqueue = true;
>