Messages in this thread | | | Date | Mon, 11 Jan 2021 13:53:10 +0800 | From | Can Guo <> | Subject | Re: [PATCH] scsi: ufs: should not override buffer lengh |
| |
Hi Jaegeuk,
I think the problem is that func ufshcd_read_desc_param() is not expecting one access unsupported descriptors on all W-LUs, not just RPMB LU.
If we can get the right buf_len from func ufshcd_map_desc_id_to_length(), the issue won't happen. - https://lore.kernel.org/patchwork/patch/1323421/.
What do you think if we update ufshcd_map_desc_id_to_length(add one param - desc_index) so that it can tell the correct buf_len in case of W-LUs?
Thanks, Can Guo.
On 2021-01-11 12:44, Jaegeuk Kim wrote: > From: Jaegeuk Kim <jaegeuk@google.com> > > Kernel stack violation when getting unit_descriptor/wb_buf_alloc_units > from > rpmb lun. The reason is the unit descriptor length is different per LU. > > The lengh of Normal LU is 45, while the one of rpmb LU is 35. > > int ufshcd_read_desc_param(struct ufs_hba *hba, ...) > { > param_offset=41; > param_size=4; > buff_len=45; > ... > buff_len=35 by rpmb LU; > > if (is_kmalloc) { > /* Make sure we don't copy more data than available */ > if (param_offset + param_size > buff_len) > param_size = buff_len - param_offset; > --> param_size = 250; > memcpy(param_read_buf, &desc_buf[param_offset], param_size); > --> memcpy(param_read_buf, desc_buf+41, 250); > > [ 141.868974][ T9174] Kernel panic - not syncing: stack-protector: > Kernel stack is corrupted in: wb_buf_alloc_units_show+0x11c/0x11c > } > } > > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> > --- > drivers/scsi/ufs/ufshcd.c | 8 ++++++-- > 1 file changed, 6 insertions(+), 2 deletions(-) > > diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c > index 2a715f13fe1d..722697b57777 100644 > --- a/drivers/scsi/ufs/ufshcd.c > +++ b/drivers/scsi/ufs/ufshcd.c > @@ -3293,8 +3293,12 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, > > if (is_kmalloc) { > /* Make sure we don't copy more data than available */ > - if (param_offset + param_size > buff_len) > - param_size = buff_len - param_offset; > + if (param_offset + param_size > buff_len) { > + if (buff_len > param_offset) > + param_size = buff_len - param_offset; > + else > + param_size = 0; > + } > memcpy(param_read_buf, &desc_buf[param_offset], param_size); > } > out:
| |