mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
UPSTREAM: scsi: ufs: core: Fix out-of-bounds warnings in ufshcd_exec_raw_upiu_cmd()
Fix the following out-of-bounds warnings by enclosing some structure
members into new structure objects upiu_req and upiu_rsp:
include/linux/fortify-string.h:20:29: warning: '__builtin_memcpy' offset [29, 48] from the object at 'treq' is out of the bounds of referenced subobject 'req_header' with type 'struct utp_upiu_header' at offset 16 [-Warray-bounds]
include/linux/fortify-string.h:20:29: warning: '__builtin_memcpy' offset [61, 80] from the object at 'treq' is out of the bounds of referenced subobject 'rsp_header' with type 'struct utp_upiu_header' at offset 48 [-Warray-bounds]
arch/m68k/include/asm/string.h:72:25: warning: '__builtin_memcpy' offset [29, 48] from the object at 'treq' is out of the bounds of referenced subobject 'req_header' with type 'struct utp_upiu_header' at offset 16 [-Warray-bounds]
arch/m68k/include/asm/string.h:72:25: warning: '__builtin_memcpy' offset [61, 80] from the object at 'treq' is out of the bounds of referenced subobject 'rsp_header' with type 'struct utp_upiu_header' at offset 48 [-Warray-bounds]
Refactor the code by making it more structured.
The problem is that the original code is trying to copy data into a bunch
of struct members adjacent to each other in a single call to memcpy(). Now
that a new struct _upiu_req_ enclosing all those adjacent members is
introduced, memcpy() doesn't overrun the length of &treq.req_header,
because the address of the new struct object _upiu_req_ is used as the
destination, instead. The same problem is present when memcpy() overruns
the length of the source &treq.rsp_header; in this case the address of the
new struct object _upiu_rsp_ is used, instead.
Also, this helps with the ongoing efforts to enable -Warray-bounds and
avoid confusing the compiler.
Link: https://github.com/KSPP/linux/issues/109
Link: https://lore.kernel.org/lkml/60640558.lsAxiK6otPwTo9rv%25lkp@intel.com/
Link: https://lore.kernel.org/r/20210331224338.GA347171@embeddedor
Reported-by: kernel test robot <lkp@intel.com>
Reviewed-by: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Build-tested-by: kernel test robot <lkp@intel.com>
(cherry picked from commit 1352eec8c0)
Bug: 204438323
Signed-off-by: Bart Van Assche <bvanassche@google.com>
Change-Id: I3d49ddb96803bfdca9d19d33fb359bfd623ce41c
This commit is contained in:
committed by
Bart Van Assche
parent
99b092bf94
commit
17bc03c718
@@ -341,11 +341,15 @@ static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag,
|
||||
|
||||
trace_android_vh_ufs_send_tm_command(hba, tag, str_t_to_str[str_t]);
|
||||
if (str_t == UFS_TM_SEND)
|
||||
trace_ufshcd_upiu(dev_name(hba->dev), str_t, &descp->req_header,
|
||||
&descp->input_param1, UFS_TSF_TM_INPUT);
|
||||
trace_ufshcd_upiu(dev_name(hba->dev), str_t,
|
||||
&descp->upiu_req.req_header,
|
||||
&descp->upiu_req.input_param1,
|
||||
UFS_TSF_TM_INPUT);
|
||||
else
|
||||
trace_ufshcd_upiu(dev_name(hba->dev), str_t, &descp->rsp_header,
|
||||
&descp->output_param1, UFS_TSF_TM_OUTPUT);
|
||||
trace_ufshcd_upiu(dev_name(hba->dev), str_t,
|
||||
&descp->upiu_rsp.rsp_header,
|
||||
&descp->upiu_rsp.output_param1,
|
||||
UFS_TSF_TM_OUTPUT);
|
||||
}
|
||||
|
||||
static void ufshcd_add_uic_command_trace(struct ufs_hba *hba,
|
||||
@@ -6535,7 +6539,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba,
|
||||
|
||||
task_tag = req->tag;
|
||||
hba->tmf_rqs[req->tag] = req;
|
||||
treq->req_header.dword_0 |= cpu_to_be32(task_tag);
|
||||
treq->upiu_req.req_header.dword_0 |= cpu_to_be32(task_tag);
|
||||
|
||||
memcpy(hba->utmrdl_base_addr + task_tag, treq, sizeof(*treq));
|
||||
ufshcd_vops_setup_task_mgmt(hba, task_tag, tm_function);
|
||||
@@ -6609,16 +6613,16 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
|
||||
treq.header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
|
||||
|
||||
/* Configure task request UPIU */
|
||||
treq.req_header.dword_0 = cpu_to_be32(lun_id << 8) |
|
||||
treq.upiu_req.req_header.dword_0 = cpu_to_be32(lun_id << 8) |
|
||||
cpu_to_be32(UPIU_TRANSACTION_TASK_REQ << 24);
|
||||
treq.req_header.dword_1 = cpu_to_be32(tm_function << 16);
|
||||
treq.upiu_req.req_header.dword_1 = cpu_to_be32(tm_function << 16);
|
||||
|
||||
/*
|
||||
* The host shall provide the same value for LUN field in the basic
|
||||
* header and for Input Parameter.
|
||||
*/
|
||||
treq.input_param1 = cpu_to_be32(lun_id);
|
||||
treq.input_param2 = cpu_to_be32(task_id);
|
||||
treq.upiu_req.input_param1 = cpu_to_be32(lun_id);
|
||||
treq.upiu_req.input_param2 = cpu_to_be32(task_id);
|
||||
|
||||
err = __ufshcd_issue_tm_cmd(hba, &treq, tm_function);
|
||||
if (err == -ETIMEDOUT)
|
||||
@@ -6629,7 +6633,7 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
|
||||
dev_err(hba->dev, "%s: failed, ocs = 0x%x\n",
|
||||
__func__, ocs_value);
|
||||
else if (tm_response)
|
||||
*tm_response = be32_to_cpu(treq.output_param1) &
|
||||
*tm_response = be32_to_cpu(treq.upiu_rsp.output_param1) &
|
||||
MASK_TM_SERVICE_RESP;
|
||||
return err;
|
||||
}
|
||||
@@ -6795,7 +6799,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
|
||||
treq.header.dword_0 = cpu_to_le32(UTP_REQ_DESC_INT_CMD);
|
||||
treq.header.dword_2 = cpu_to_le32(OCS_INVALID_COMMAND_STATUS);
|
||||
|
||||
memcpy(&treq.req_header, req_upiu, sizeof(*req_upiu));
|
||||
memcpy(&treq.upiu_req, req_upiu, sizeof(*req_upiu));
|
||||
|
||||
err = __ufshcd_issue_tm_cmd(hba, &treq, tm_f);
|
||||
if (err == -ETIMEDOUT)
|
||||
@@ -6808,7 +6812,7 @@ int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba,
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(rsp_upiu, &treq.rsp_header, sizeof(*rsp_upiu));
|
||||
memcpy(rsp_upiu, &treq.upiu_rsp, sizeof(*rsp_upiu));
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -495,17 +495,21 @@ struct utp_task_req_desc {
|
||||
struct request_desc_header header;
|
||||
|
||||
/* DW 4-11 - Task request UPIU structure */
|
||||
struct utp_upiu_header req_header;
|
||||
__be32 input_param1;
|
||||
__be32 input_param2;
|
||||
__be32 input_param3;
|
||||
__be32 __reserved1[2];
|
||||
struct {
|
||||
struct utp_upiu_header req_header;
|
||||
__be32 input_param1;
|
||||
__be32 input_param2;
|
||||
__be32 input_param3;
|
||||
__be32 __reserved1[2];
|
||||
} upiu_req;
|
||||
|
||||
/* DW 12-19 - Task Management Response UPIU structure */
|
||||
struct utp_upiu_header rsp_header;
|
||||
__be32 output_param1;
|
||||
__be32 output_param2;
|
||||
__be32 __reserved2[3];
|
||||
struct {
|
||||
struct utp_upiu_header rsp_header;
|
||||
__be32 output_param1;
|
||||
__be32 output_param2;
|
||||
__be32 __reserved2[3];
|
||||
} upiu_rsp;
|
||||
};
|
||||
|
||||
#endif /* End of Header */
|
||||
|
||||
Reference in New Issue
Block a user