* [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode
@ 2022-03-07 11:17 peter.wang
2022-03-07 17:52 ` Bart Van Assche
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: peter.wang @ 2022-03-07 11:17 UTC (permalink / raw)
To: stanley.chu, linux-scsi, martin.petersen, avri.altman,
alim.akhtar, jejb
Cc: wsd_upstream, linux-mediatek, peter.wang, chun-hung.wu,
alice.chao, cc.chou, chaotian.jing, jiajie.hao, powen.kao,
qilin.tan, lin.gui, mikebi, beanhuo
From: Peter Wang <peter.wang@mediatek.com>
When ufs init without scmd->device->sector_size set,
scsi_get_lba will get a wrong shift number and ubsan error.
shift exponent 4294967286 is too large for 64-bit type
'sector_t' (aka 'unsigned long long')
Call scsi_get_lba only when opcode is READ_10/WRITE_10/UNMAP.
Signed-off-by: Peter Wang <peter.wang@mediatek.com>
---
drivers/scsi/ufs/ufshcd.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 9349557b8a01..3c4caee8fb93 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -367,7 +367,7 @@ static void ufshcd_add_uic_command_trace(struct ufs_hba *hba,
static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag,
enum ufs_trace_str_t str_t)
{
- u64 lba;
+ u64 lba = 0;
u8 opcode = 0, group_id = 0;
u32 intr, doorbell;
struct ufshcd_lrb *lrbp = &hba->lrb[tag];
@@ -384,7 +384,6 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag,
return;
opcode = cmd->cmnd[0];
- lba = scsi_get_lba(cmd);
if (opcode == READ_10 || opcode == WRITE_10) {
/*
@@ -392,6 +391,7 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag,
*/
transfer_len =
be32_to_cpu(lrbp->ucd_req_ptr->sc.exp_data_transfer_len);
+ lba = scsi_get_lba(cmd);
if (opcode == WRITE_10)
group_id = lrbp->cmd->cmnd[6];
} else if (opcode == UNMAP) {
@@ -399,6 +399,7 @@ static void ufshcd_add_command_trace(struct ufs_hba *hba, unsigned int tag,
* The number of Bytes to be unmapped beginning with the lba.
*/
transfer_len = blk_rq_bytes(rq);
+ lba = scsi_get_lba(cmd);
}
intr = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
--
2.18.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode
2022-03-07 11:17 [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode peter.wang
@ 2022-03-07 17:52 ` Bart Van Assche
2022-03-08 11:24 ` Peter Wang
2022-03-08 22:11 ` Bart Van Assche
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Bart Van Assche @ 2022-03-07 17:52 UTC (permalink / raw)
To: peter.wang, stanley.chu, linux-scsi, martin.petersen, avri.altman,
alim.akhtar, jejb
Cc: wsd_upstream, linux-mediatek, chun-hung.wu, alice.chao, cc.chou,
chaotian.jing, jiajie.hao, powen.kao, qilin.tan, lin.gui, mikebi,
beanhuo
On 3/7/22 03:17, peter.wang@mediatek.com wrote:
> When ufs init without scmd->device->sector_size set,
> scsi_get_lba will get a wrong shift number and ubsan error.
> shift exponent 4294967286 is too large for 64-bit type
> 'sector_t' (aka 'unsigned long long')
> Call scsi_get_lba only when opcode is READ_10/WRITE_10/UNMAP.
Hmm ... how can it happen that sector_size has not been set? I think
that can only happen for LUNs of type SCSI DISK if sd_read_capacity()
fails? If sd_read_capacity() fails I think the sd driver is expected to
set the capacity to zero?
rq->__sector == -1 for flush requests and the type of that member
(sector_t) is unsigned. I think that it is allowed for a shift left of
an unsigned type to overflow. From the C standard: "The result of E1 <<
E2 is E1 left-shifted E2 bit positions; vacated bits are filled with
zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2 ,
reduced modulo one more than the maximum value representable in the
result type."
Thanks,
Bart.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode
2022-03-07 17:52 ` Bart Van Assche
@ 2022-03-08 11:24 ` Peter Wang
0 siblings, 0 replies; 6+ messages in thread
From: Peter Wang @ 2022-03-08 11:24 UTC (permalink / raw)
To: Bart Van Assche, stanley.chu, linux-scsi, martin.petersen,
avri.altman, alim.akhtar, jejb
Cc: wsd_upstream, linux-mediatek, chun-hung.wu, alice.chao, cc.chou,
chaotian.jing, jiajie.hao, powen.kao, qilin.tan, lin.gui, mikebi,
beanhuo
Hi Bart,
When scsi scan in scsi_probe_lun function, there have much INQUIRY(0x12)
command
with sector_size is 0.
unsigned int shift will get 4294967286 (signed -10) and an sector_t type
is 64 bit.
Shift 64bit right 4294967286 will have ubsan error because ubsan think
shift number should be wrong and return 0 always.
BTW, we only need the lba information when read/write/unmap. Other
command such
as INQUIRY is useless.
static inline sector_t scsi_get_lba(struct scsi_cmnd *scmd)
{
unsigned int shift = ilog2(scmd->device->sector_size) -
SECTOR_SHIFT; <= shift is 4294967286 (-1-9=-10)
return blk_rq_pos(scsi_cmd_to_rq(scmd)) >> shift; <= sector_t type
>> 4294967286 will always get 0.
}
On 3/8/22 1:52 AM, Bart Van Assche wrote:
>
> Hmm ... how can it happen that sector_size has not been set? I think
> that can only happen for LUNs of type SCSI DISK if sd_read_capacity()
> fails? If sd_read_capacity() fails I think the sd driver is expected
> to set the capacity to zero?
>
> rq->__sector == -1 for flush requests and the type of that member
> (sector_t) is unsigned. I think that it is allowed for a shift left of
> an unsigned type to overflow. From the C standard: "The result of E1
> << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with
> zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2
> , reduced modulo one more than the maximum value representable in the
> result type."
>
> Thanks,
>
> Bart.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode
2022-03-07 11:17 [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode peter.wang
2022-03-07 17:52 ` Bart Van Assche
@ 2022-03-08 22:11 ` Bart Van Assche
2022-03-09 3:52 ` Martin K. Petersen
2022-03-15 5:02 ` Martin K. Petersen
3 siblings, 0 replies; 6+ messages in thread
From: Bart Van Assche @ 2022-03-08 22:11 UTC (permalink / raw)
To: peter.wang, stanley.chu, linux-scsi, martin.petersen, avri.altman,
alim.akhtar, jejb
Cc: wsd_upstream, linux-mediatek, chun-hung.wu, alice.chao, cc.chou,
chaotian.jing, jiajie.hao, powen.kao, qilin.tan, lin.gui, mikebi,
beanhuo
On 3/7/22 03:17, peter.wang@mediatek.com wrote:
> When ufs init without scmd->device->sector_size set,
> scsi_get_lba will get a wrong shift number and ubsan error.
> shift exponent 4294967286 is too large for 64-bit type
> 'sector_t' (aka 'unsigned long long')
> Call scsi_get_lba only when opcode is READ_10/WRITE_10/UNMAP.
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode
2022-03-07 11:17 [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode peter.wang
2022-03-07 17:52 ` Bart Van Assche
2022-03-08 22:11 ` Bart Van Assche
@ 2022-03-09 3:52 ` Martin K. Petersen
2022-03-15 5:02 ` Martin K. Petersen
3 siblings, 0 replies; 6+ messages in thread
From: Martin K. Petersen @ 2022-03-09 3:52 UTC (permalink / raw)
To: peter.wang
Cc: stanley.chu, linux-scsi, martin.petersen, avri.altman,
alim.akhtar, jejb, wsd_upstream, linux-mediatek, chun-hung.wu,
alice.chao, cc.chou, chaotian.jing, jiajie.hao, powen.kao,
qilin.tan, lin.gui, mikebi, beanhuo
> When ufs init without scmd->device->sector_size set, scsi_get_lba will
> get a wrong shift number and ubsan error. shift exponent 4294967286
> is too large for 64-bit type 'sector_t' (aka 'unsigned long long')
> Call scsi_get_lba only when opcode is READ_10/WRITE_10/UNMAP.
Applied to 5.18/scsi-staging, thanks!
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode
2022-03-07 11:17 [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode peter.wang
` (2 preceding siblings ...)
2022-03-09 3:52 ` Martin K. Petersen
@ 2022-03-15 5:02 ` Martin K. Petersen
3 siblings, 0 replies; 6+ messages in thread
From: Martin K. Petersen @ 2022-03-15 5:02 UTC (permalink / raw)
To: linux-scsi, jejb, peter.wang, avri.altman, alim.akhtar,
stanley.chu
Cc: Martin K . Petersen, linux-mediatek, chun-hung.wu, chaotian.jing,
beanhuo, wsd_upstream, alice.chao, jiajie.hao, powen.kao, cc.chou,
mikebi, qilin.tan, lin.gui
On Mon, 7 Mar 2022 19:17:52 +0800, peter.wang@mediatek.com wrote:
> From: Peter Wang <peter.wang@mediatek.com>
>
> When ufs init without scmd->device->sector_size set,
> scsi_get_lba will get a wrong shift number and ubsan error.
> shift exponent 4294967286 is too large for 64-bit type
> 'sector_t' (aka 'unsigned long long')
> Call scsi_get_lba only when opcode is READ_10/WRITE_10/UNMAP.
>
> [...]
Applied to 5.18/scsi-queue, thanks!
[1/1] scsi: ufs: scsi_get_lba error fix by check cmd opcode
https://git.kernel.org/mkp/scsi/c/2bd3b6b75946
--
Martin K. Petersen Oracle Linux Engineering
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2022-03-15 5:17 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-03-07 11:17 [PATCH v1] scsi: ufs: scsi_get_lba error fix by check cmd opcode peter.wang
2022-03-07 17:52 ` Bart Van Assche
2022-03-08 11:24 ` Peter Wang
2022-03-08 22:11 ` Bart Van Assche
2022-03-09 3:52 ` Martin K. Petersen
2022-03-15 5:02 ` Martin K. Petersen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox