[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <58c12dc4-87e2-5c91-5744-27777acfa631@embeddedor.com>
Date: Thu, 3 Aug 2023 07:08:13 -0600
From: "Gustavo A. R. Silva" <gustavo@...eddedor.com>
To: Jakub Kicinski <kuba@...nel.org>, davem@...emloft.net
Cc: netdev@...r.kernel.org, edumazet@...gle.com, pabeni@...hat.com,
michael.chan@...adcom.com
Subject: Re: [PATCH net-next 1/2] eth: bnxt: fix one of the W=1 warnings about
fortified memcpy()
On 7/27/23 13:07, Jakub Kicinski wrote:
> Fix a W=1 warning with gcc 13.1:
>
> In function ‘fortify_memcpy_chk’,
> inlined from ‘bnxt_hwrm_queue_cos2bw_cfg’ at drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c:133:3:
> include/linux/fortify-string.h:592:25: warning: call to ‘__read_overflow2_field’ declared with attribute warning: detected read beyond size of field (2nd parameter); maybe use struct_group()? [-Wattribute-warning]
> 592 | __read_overflow2_field(q_size_field, size);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> The field group is already defined and starts at queue_id:
>
> struct bnxt_cos2bw_cfg {
> u8 pad[3];
> struct_group_attr(cfg, __packed,
> u8 queue_id;
> __le32 min_bw;
>
> Signed-off-by: Jakub Kicinski <kuba@...nel.org>
> ---
> CC: michael.chan@...adcom.com
>
> Michael, the other warning looks more.. interesting.
> The code does:
>
> data = &resp->queue_id0 + offsetof(struct bnxt_cos2bw_cfg, queue_id);
>
> which translates to: data = &resp->queue_id0 + 3, but the HWRM struct
> says:
>
> struct hwrm_queue_cos2bw_qcfg_output {
> __le16 error_code;
> __le16 req_type;
> __le16 seq_id;
> __le16 resp_len;
> u8 queue_id0;
> u8 unused_0;
> __le16 unused_1;
> __le32 queue_id0_min_bw;
>
> So queue_id0 is in the wrong place?
> Why not just move it in the spec?
> Simplest fix for the warning would be to assign the 6 fields by value.
> But to get the value of queue_id we'd need to read unused_1 AFACT? :o
> Could you please fix this somehow? Doing W=1 builds on bnxt is painful.
It seems I just ran into the same issue you're talking about here. See:
In function 'fortify_memcpy_chk',
inlined from 'bnxt_hwrm_queue_cos2bw_qcfg' at drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c:165:3:
include/linux/fortify-string.h:592:25: warning: call to '__read_overflow2_field' declared with attribute warning: detected read beyond size of field (2nd
parameter); maybe use struct_group()? [-Wattribute-warning]
592 | __read_overflow2_field(q_size_field, size);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here is a potential fix for that:
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
index 31f85f3e2364..e2390d73b3f0 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
@@ -144,7 +144,7 @@ static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets)
struct hwrm_queue_cos2bw_qcfg_output *resp;
struct hwrm_queue_cos2bw_qcfg_input *req;
struct bnxt_cos2bw_cfg cos2bw;
- void *data;
+ struct bnxt_cos2bw_cfg *data;
int rc, i;
rc = hwrm_req_init(bp, req, HWRM_QUEUE_COS2BW_QCFG);
@@ -158,11 +158,11 @@ static int bnxt_hwrm_queue_cos2bw_qcfg(struct bnxt *bp, struct ieee_ets *ets)
return rc;
}
- data = &resp->queue_id0 + offsetof(struct bnxt_cos2bw_cfg, queue_id);
+ data = (struct bnxt_cos2bw_cfg *)&resp->queue_id0;
for (i = 0; i < bp->max_tc; i++, data += sizeof(cos2bw.cfg)) {
int tc;
- memcpy(&cos2bw.cfg, data, sizeof(cos2bw.cfg));
+ memcpy(&cos2bw.cfg, &data->cfg, sizeof(cos2bw.cfg));
if (i == 0)
cos2bw.queue_id = resp->queue_id0;
Also, 0-day guys just reported[1] to me a -Wstringop-overflow in a similar piece of code
in the same file. See:
drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c:133:17: warning: writing 12 bytes into a region of size 1 [-Wstringop-overflow=]
And I think this is a potential solution for that:
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
index 31f85f3e2364..01e0ac246e11 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
@@ -98,7 +98,7 @@ static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt *bp, struct ieee_ets *ets,
{
struct hwrm_queue_cos2bw_cfg_input *req;
struct bnxt_cos2bw_cfg cos2bw;
- void *data;
+ struct bnxt_cos2bw_cfg *data;
int rc, i;
rc = hwrm_req_init(bp, req, HWRM_QUEUE_COS2BW_CFG);
@@ -129,8 +129,10 @@ static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt *bp, struct ieee_ets *ets,
cpu_to_le32((ets->tc_tx_bw[i] * 100) |
BW_VALUE_UNIT_PERCENT1_100);
}
- data = &req->unused_0 + qidx * (sizeof(cos2bw) - 4);
- memcpy(data, &cos2bw.cfg, sizeof(cos2bw) - 4);
+ data = (struct bnxt_cos2bw_cfg *)(&req->unused_0 + qidx *
+ sizeof(cos2bw.cfg) -
+ offsetof(struct bnxt_cos2bw_cfg, cfg));
+ memcpy(&data->cfg, &cos2bw.cfg, sizeof(cos2bw.cfg));
if (qidx == 0) {
req->queue_id0 = cos2bw.queue_id;
req->unused_0 = 0;
If you agree with these changes I can send them as proper patches.
Thanks
--
Gustavo
[1] https://lore.kernel.org/lkml/202308031558.MhRIyeiu-lkp@intel.com/
> ---
> drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
> index caab3d626a2a..31f85f3e2364 100644
> --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
> +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
> @@ -130,7 +130,7 @@ static int bnxt_hwrm_queue_cos2bw_cfg(struct bnxt *bp, struct ieee_ets *ets,
> BW_VALUE_UNIT_PERCENT1_100);
> }
> data = &req->unused_0 + qidx * (sizeof(cos2bw) - 4);
> - memcpy(data, &cos2bw.queue_id, sizeof(cos2bw) - 4);
> + memcpy(data, &cos2bw.cfg, sizeof(cos2bw) - 4);
> if (qidx == 0) {
> req->queue_id0 = cos2bw.queue_id;
> req->unused_0 = 0;
Powered by blists - more mailing lists