Re: [PATCH v2 3/3] scsi: core: Call blk_mq_free_tag_set() earlier

Li, Zhijian
2022-07-01T07:45:13Z

Send again, the format of previous one is wrong.

on 7/1/2022 11:44 AM, Ming Lei wrote:
> On Thu, Jun 30, 2022 at 02:37:33PM -0700, Bart Van Assche wrote:
>> There are two .exit_cmd_priv implementations. Both implementations use
>> resources associated with the SCSI host. Make sure that these resources are
> Please document what the exact resources associated with this SCSI host is.
>
> We need the root cause.
>
> I understand it might be related with module unloading, since ib_srp may
> be gone already, but not sure if it is the exact one in this report.
>
>> still available when .exit_cmd_priv is called by moving the .exit_cmd_priv
>> calls from scsi_host_dev_release() to scsi_forget_host(). Moving
>> blk_mq_free_tag_set() from scsi_host_dev_release() to scsi_forget_host() is
>> safe because scsi_forget_host() drains all the request queues that use the
>> host tag set. This guarantees that no requests are in flight and also that
>> no new requests will be allocated from the host tag set.
>>
>> This patch fixes the following use-after-free:
>>
>> ==================================================================
>> BUG: KASAN: use-after-free in srp_exit_cmd_priv+0x27/0xd0 [ib_srp]
>> Read of size 8 at addr ffff888100337000 by task multipathd/16727
> What is the 8bytes buffer which triggers UAF? what does srp_exit_cmd_priv+0x27
> point to?

This bug was reported by me, let's input some debug information.
*Attention*: below debug info came from a modified source, so the offset it is a bit different from above one.

[ 120.400572] ib_srp: lizhijian: srp_exit_cmd_priv:975: target_host ffff88810b8d6000, ffff88810b8d67e0
[ 120.400578] ib_srp: lizhijian: srp_exit_cmd_priv:977: target_host ffff88810b8d6000, ffff88810b8d67e0
[ 120.400590] ==================================================================
[ 120.400592] BUG: KASAN: use-after-free in srp_exit_cmd_priv+0x6c/0x109 [ib_srp]
[ 120.400616] Read of size 8 at addr ffff8881076b1800 by task multipathd/1417
[ 120.400619]
[ 120.400621] CPU: 0 PID: 1417 Comm: multipathd Not tainted 5.19.0-rc1-roce-flush+ #85
[ 120.400626] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-27-g64f37cc530f1-prebuilt.qemu.org 04/01/2014

crash> struct srp_target_port.srp_host ffff88810b8d67e0
srp_host = 0xffff8881076b1800,
crash> struct srp_target_port.srp_host
struct srp_target_port {
[104] struct srp_host *srp_host;
}

crash> struct srp_host.srp_dev 0xffff8881076b1800
srp_dev = 0xffff88800bcd1400,

crash> struct srp_device 0xffff88800bcd1400
struct srp_device {
dev_list = {
next = 0xffff888106fafd00,
prev = 0xb680010900000749
},
dev = 0x0,
pd = 0x0,
global_rkey = 0,
mr_page_mask = 3,
mr_page_size = 181960704,
mr_max_size = -30592,
max_pages_per_mr = 117112064,
has_fr = 129,
use_fast_reg = 136
}

crash> dis -s srp_exit_cmd_priv+0x6c
FILE: ../drivers/infiniband/ulp/srp/ib_srp.c
LINE: 978

973 struct srp_request *req;
974
975 pr_info("lizhijian: %s:%d: target_host %px, %px\n", __func__, __LINE__, shost, shost->hostdata);
976 target = host_to_target(shost);
977 pr_info("lizhijian: %s:%d: target_host %px, %px\n", __func__, __LINE__, shost, shost->hostdata);
* 978 dev = target->srp_host->srp_dev;
979 ibdev = dev->dev;
980 req = scsi_cmd_priv(cmd);
981
982 kfree(req->fr_list);
983 if (req->indirect_dma_addr) {
984 ib_dma_unmap_single(ibdev, req->indirect_dma_addr,
985 target->indirect_size,
986 DMA_TO_DEVICE);
987 }
988 kfree(req->indirect_desc);
989
990 return 0;
991 }

Thanks
Zhijian

>
>
> Thanks,
> Ming
>