[PATCH] fcoe: avoid memset across pointer boundaries

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <hare@xxxxxxxx>
---
 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




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux