Commit bb480242 authored by Mintz, Yuval's avatar Mintz, Yuval Committed by David S. Miller

qed: Prevent stack corruption on MFW interaction

Driver uses a union for copying data to & from management firmware
when interacting with it.
Problem is that the function always copies sizeof(union) while commit
2edbff8d ("qed: Learn resources from management firmware") is casting
a union elements which is of smaller size [24-byte instead of 88-bytes].

Also, the union contains some inappropriate elements which increase its
size [should have been 32-bytes]. While this shouldn't corrupt other
PF messages to the MFW [as management firmware enforces permissions so
that each PF is allowed to write only to its own mailbox] we fix this
here as well.

Fixes: 2edbff8d ("qed: Learn resources from management firmware")
Signed-off-by: default avatarYuval Mintz <Yuval.Mintz@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b12ab9b1
...@@ -8581,7 +8581,6 @@ union drv_union_data { ...@@ -8581,7 +8581,6 @@ union drv_union_data {
struct drv_version_stc drv_version; struct drv_version_stc drv_version;
struct lan_stats_stc lan_stats; struct lan_stats_stc lan_stats;
u64 reserved_stats[11];
struct ocbb_data_stc ocbb_info; struct ocbb_data_stc ocbb_info;
struct temperature_status_stc temp_info; struct temperature_status_stc temp_info;
struct resource_info resource; struct resource_info resource;
......
...@@ -1697,19 +1697,27 @@ int qed_mcp_get_resc_info(struct qed_hwfn *p_hwfn, ...@@ -1697,19 +1697,27 @@ int qed_mcp_get_resc_info(struct qed_hwfn *p_hwfn,
u32 *p_mcp_resp, u32 *p_mcp_param) u32 *p_mcp_resp, u32 *p_mcp_param)
{ {
struct qed_mcp_mb_params mb_params; struct qed_mcp_mb_params mb_params;
union drv_union_data *p_union_data; union drv_union_data union_data;
int rc; int rc;
memset(&mb_params, 0, sizeof(mb_params)); memset(&mb_params, 0, sizeof(mb_params));
memset(&union_data, 0, sizeof(union_data));
mb_params.cmd = DRV_MSG_GET_RESOURCE_ALLOC_MSG; mb_params.cmd = DRV_MSG_GET_RESOURCE_ALLOC_MSG;
mb_params.param = QED_RESC_ALLOC_VERSION; mb_params.param = QED_RESC_ALLOC_VERSION;
p_union_data = (union drv_union_data *)p_resc_info;
mb_params.p_data_src = p_union_data; /* Need to have a sufficient large struct, as the cmd_and_union
mb_params.p_data_dst = p_union_data; * is going to do memcpy from and to it.
*/
memcpy(&union_data.resource, p_resc_info, sizeof(*p_resc_info));
mb_params.p_data_src = &union_data;
mb_params.p_data_dst = &union_data;
rc = qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params); rc = qed_mcp_cmd_and_union(p_hwfn, p_ptt, &mb_params);
if (rc) if (rc)
return rc; return rc;
/* Copy the data back */
memcpy(p_resc_info, &union_data.resource, sizeof(*p_resc_info));
*p_mcp_resp = mb_params.mcp_resp; *p_mcp_resp = mb_params.mcp_resp;
*p_mcp_param = mb_params.mcp_param; *p_mcp_param = mb_params.mcp_param;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment