Gcc-9 complains for a memset across pointer boundaries, which happens as the code tries to allocate a flexible array on the stack. Turns out we cannot do this without relying on gcc-isms, so this patch converts the stack allocation in proper kzalloc() calls.
Signed-off-by: Hannes Reinecke <h...@suse.com> --- drivers/scsi/fcoe/fcoe_ctlr.c | 50 +++++++++++++++++++++++++------------------ include/scsi/libfc.h | 1 + 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 0d7770d07405..3b9db5093c3e 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -2005,7 +2005,7 @@ EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac); */ static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata) { - return (struct fcoe_rport *)(rdata + 1); + return (struct fcoe_rport *)(&rdata->rpriv); } /** @@ -2284,7 +2284,6 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, u32 dtype; u8 sub; - memset(rdata, 0, sizeof(*rdata) + sizeof(*frport)); frport = fcoe_ctlr_rport(rdata); fiph = (struct fip_header *)skb->data; @@ -2738,10 +2737,7 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) { struct fip_header *fiph; enum fip_vn2vn_subcode sub; - struct { - struct fc_rport_priv rdata; - struct fcoe_rport frport; - } buf; + struct fc_rport_priv *rdata; int rc, vlan_id = 0; fiph = (struct fip_header *)skb->data; @@ -2757,28 +2753,35 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) goto drop; } - rc = fcoe_ctlr_vn_parse(fip, skb, &buf.rdata); + rdata = kzalloc(sizeof(*rdata) + sizeof(struct fcoe_rport), GFP_KERNEL); + if (!rdata) { + LIBFCOE_FIP_DBG(fip, "vn_recv rdata alloc error\n"); + rc = -EAGAIN; + goto drop; + } + + rc = fcoe_ctlr_vn_parse(fip, skb, rdata); if (rc) { LIBFCOE_FIP_DBG(fip, "vn_recv vn_parse error %d\n", rc); - goto drop; + goto free; } mutex_lock(&fip->ctlr_mutex); switch (sub) { case FIP_SC_VN_PROBE_REQ: - fcoe_ctlr_vn_probe_req(fip, &buf.rdata); + fcoe_ctlr_vn_probe_req(fip, rdata); break; case FIP_SC_VN_PROBE_REP: - fcoe_ctlr_vn_probe_reply(fip, &buf.rdata); + fcoe_ctlr_vn_probe_reply(fip, rdata); break; case FIP_SC_VN_CLAIM_NOTIFY: - fcoe_ctlr_vn_claim_notify(fip, &buf.rdata); + fcoe_ctlr_vn_claim_notify(fip, rdata); break; case FIP_SC_VN_CLAIM_REP: - fcoe_ctlr_vn_claim_resp(fip, &buf.rdata); + fcoe_ctlr_vn_claim_resp(fip, rdata); break; case FIP_SC_VN_BEACON: - fcoe_ctlr_vn_beacon(fip, &buf.rdata); + fcoe_ctlr_vn_beacon(fip, rdata); break; default: LIBFCOE_FIP_DBG(fip, "vn_recv unknown subcode %d\n", sub); @@ -2786,6 +2789,8 @@ static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) break; } mutex_unlock(&fip->ctlr_mutex); +free: + kfree(rdata); drop: kfree_skb(skb); return rc; @@ -2982,24 +2987,27 @@ static int fcoe_ctlr_vlan_recv(struct fcoe_ctlr *fip, struct sk_buff *skb) { struct fip_header *fiph; enum fip_vlan_subcode sub; - struct { - struct fc_rport_priv rdata; - struct fcoe_rport frport; - } buf; + struct fc_rport_priv *rdata; int rc; + rdata = kzalloc(sizeof(*rdata) + sizeof(struct fcoe_rport), GFP_KERNEL); + if (!rdata) { + LIBFCOE_FIP_DBG(fip, "vlan_recv rdata alloc error\n"); + goto drop; + } fiph = (struct fip_header *)skb->data; sub = fiph->fip_subcode; - rc = fcoe_ctlr_vlan_parse(fip, skb, &buf.rdata); + rc = fcoe_ctlr_vlan_parse(fip, skb, rdata); if (rc) { LIBFCOE_FIP_DBG(fip, "vlan_recv vlan_parse error %d\n", rc); - goto drop; + goto free; } mutex_lock(&fip->ctlr_mutex); if (sub == FIP_SC_VL_REQ) - fcoe_ctlr_vlan_disc_reply(fip, &buf.rdata); + fcoe_ctlr_vlan_disc_reply(fip, rdata); mutex_unlock(&fip->ctlr_mutex); - +free: + kfree(rdata); drop: kfree_skb(skb); return rc; diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h index 13dd2eebc20e..8c9db4f531ce 100644 --- a/include/scsi/libfc.h +++ b/include/scsi/libfc.h @@ -212,6 +212,7 @@ struct fc_rport_priv { struct rcu_head rcu; u16 sp_features; u8 spp_type; + char rpriv[]; }; /** -- 2.16.4