stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] arcnet: provide a buffer big enough to actually receive packets
@ 2019-09-20 14:08 Uwe Kleine-König
  2019-09-23 11:14 ` Michael Grzeschik
  2019-09-24 14:49 ` David Miller
  0 siblings, 2 replies; 3+ messages in thread
From: Uwe Kleine-König @ 2019-09-20 14:08 UTC (permalink / raw)
  To: Michael Grzeschik, David S. Miller; +Cc: netdev, Laura Abbott, stable

struct archdr is only big enough to hold the header of various types of
arcnet packets. So to provide enough space to hold the data read from
hardware provide a buffer large enough to hold a packet with maximal
size.

The problem was noticed by the stack protector which makes the kernel
oops.

Cc: stable@vger.kernel.org # v2.4.0+
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
Hello,

the problem exists in v2.4.0 already, I didn't look further to identify
the offending commit.

Best regards
Uwe
---
 drivers/net/arcnet/arcnet.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 0efef7aa5b89..2b8cf58e4de0 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -1063,31 +1063,34 @@ EXPORT_SYMBOL(arcnet_interrupt);
 static void arcnet_rx(struct net_device *dev, int bufnum)
 {
 	struct arcnet_local *lp = netdev_priv(dev);
-	struct archdr pkt;
+	union {
+		struct archdr pkt;
+		char buf[512];
+	} rxdata;
 	struct arc_rfc1201 *soft;
 	int length, ofs;
 
-	soft = &pkt.soft.rfc1201;
+	soft = &rxdata.pkt.soft.rfc1201;
 
-	lp->hw.copy_from_card(dev, bufnum, 0, &pkt, ARC_HDR_SIZE);
-	if (pkt.hard.offset[0]) {
-		ofs = pkt.hard.offset[0];
+	lp->hw.copy_from_card(dev, bufnum, 0, &rxdata.pkt, ARC_HDR_SIZE);
+	if (rxdata.pkt.hard.offset[0]) {
+		ofs = rxdata.pkt.hard.offset[0];
 		length = 256 - ofs;
 	} else {
-		ofs = pkt.hard.offset[1];
+		ofs = rxdata.pkt.hard.offset[1];
 		length = 512 - ofs;
 	}
 
 	/* get the full header, if possible */
-	if (sizeof(pkt.soft) <= length) {
-		lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(pkt.soft));
+	if (sizeof(rxdata.pkt.soft) <= length) {
+		lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(rxdata.pkt.soft));
 	} else {
-		memset(&pkt.soft, 0, sizeof(pkt.soft));
+		memset(&rxdata.pkt.soft, 0, sizeof(rxdata.pkt.soft));
 		lp->hw.copy_from_card(dev, bufnum, ofs, soft, length);
 	}
 
 	arc_printk(D_DURING, dev, "Buffer #%d: received packet from %02Xh to %02Xh (%d+4 bytes)\n",
-		   bufnum, pkt.hard.source, pkt.hard.dest, length);
+		   bufnum, rxdata.pkt.hard.source, rxdata.pkt.hard.dest, length);
 
 	dev->stats.rx_packets++;
 	dev->stats.rx_bytes += length + ARC_HDR_SIZE;
@@ -1096,13 +1099,13 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
 	if (arc_proto_map[soft->proto]->is_ip) {
 		if (BUGLVL(D_PROTO)) {
 			struct ArcProto
-			*oldp = arc_proto_map[lp->default_proto[pkt.hard.source]],
+			*oldp = arc_proto_map[lp->default_proto[rxdata.pkt.hard.source]],
 			*newp = arc_proto_map[soft->proto];
 
 			if (oldp != newp) {
 				arc_printk(D_PROTO, dev,
 					   "got protocol %02Xh; encap for host %02Xh is now '%c' (was '%c')\n",
-					   soft->proto, pkt.hard.source,
+					   soft->proto, rxdata.pkt.hard.source,
 					   newp->suffix, oldp->suffix);
 			}
 		}
@@ -1111,10 +1114,10 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
 		lp->default_proto[0] = soft->proto;
 
 		/* in striking contrast, the following isn't a hack. */
-		lp->default_proto[pkt.hard.source] = soft->proto;
+		lp->default_proto[rxdata.pkt.hard.source] = soft->proto;
 	}
 	/* call the protocol-specific receiver. */
-	arc_proto_map[soft->proto]->rx(dev, bufnum, &pkt, length);
+	arc_proto_map[soft->proto]->rx(dev, bufnum, &rxdata.pkt, length);
 }
 
 static void null_rx(struct net_device *dev, int bufnum,
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] arcnet: provide a buffer big enough to actually receive packets
  2019-09-20 14:08 [PATCH] arcnet: provide a buffer big enough to actually receive packets Uwe Kleine-König
@ 2019-09-23 11:14 ` Michael Grzeschik
  2019-09-24 14:49 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: Michael Grzeschik @ 2019-09-23 11:14 UTC (permalink / raw)
  To: Uwe Kleine-König; +Cc: David S. Miller, netdev, Laura Abbott, stable

[-- Attachment #1: Type: text/plain, Size: 4214 bytes --]

On Fri, Sep 20, 2019 at 04:08:21PM +0200, Uwe Kleine-König wrote:
> struct archdr is only big enough to hold the header of various types of
> arcnet packets. So to provide enough space to hold the data read from
> hardware provide a buffer large enough to hold a packet with maximal
> size.
> 
> The problem was noticed by the stack protector which makes the kernel
> oops.
> 
> Cc: stable@vger.kernel.org # v2.4.0+
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

Acked-by: Michael Grzeschik <m.grzeschik@pengutronix.de>

> ---
> Hello,
> 
> the problem exists in v2.4.0 already, I didn't look further to identify
> the offending commit.
> 
> Best regards
> Uwe
> ---
>  drivers/net/arcnet/arcnet.c | 31 +++++++++++++++++--------------
>  1 file changed, 17 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
> index 0efef7aa5b89..2b8cf58e4de0 100644
> --- a/drivers/net/arcnet/arcnet.c
> +++ b/drivers/net/arcnet/arcnet.c
> @@ -1063,31 +1063,34 @@ EXPORT_SYMBOL(arcnet_interrupt);
>  static void arcnet_rx(struct net_device *dev, int bufnum)
>  {
>  	struct arcnet_local *lp = netdev_priv(dev);
> -	struct archdr pkt;
> +	union {
> +		struct archdr pkt;
> +		char buf[512];
> +	} rxdata;
>  	struct arc_rfc1201 *soft;
>  	int length, ofs;
>  
> -	soft = &pkt.soft.rfc1201;
> +	soft = &rxdata.pkt.soft.rfc1201;
>  
> -	lp->hw.copy_from_card(dev, bufnum, 0, &pkt, ARC_HDR_SIZE);
> -	if (pkt.hard.offset[0]) {
> -		ofs = pkt.hard.offset[0];
> +	lp->hw.copy_from_card(dev, bufnum, 0, &rxdata.pkt, ARC_HDR_SIZE);
> +	if (rxdata.pkt.hard.offset[0]) {
> +		ofs = rxdata.pkt.hard.offset[0];
>  		length = 256 - ofs;
>  	} else {
> -		ofs = pkt.hard.offset[1];
> +		ofs = rxdata.pkt.hard.offset[1];
>  		length = 512 - ofs;
>  	}
>  
>  	/* get the full header, if possible */
> -	if (sizeof(pkt.soft) <= length) {
> -		lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(pkt.soft));
> +	if (sizeof(rxdata.pkt.soft) <= length) {
> +		lp->hw.copy_from_card(dev, bufnum, ofs, soft, sizeof(rxdata.pkt.soft));
>  	} else {
> -		memset(&pkt.soft, 0, sizeof(pkt.soft));
> +		memset(&rxdata.pkt.soft, 0, sizeof(rxdata.pkt.soft));
>  		lp->hw.copy_from_card(dev, bufnum, ofs, soft, length);
>  	}
>  
>  	arc_printk(D_DURING, dev, "Buffer #%d: received packet from %02Xh to %02Xh (%d+4 bytes)\n",
> -		   bufnum, pkt.hard.source, pkt.hard.dest, length);
> +		   bufnum, rxdata.pkt.hard.source, rxdata.pkt.hard.dest, length);
>  
>  	dev->stats.rx_packets++;
>  	dev->stats.rx_bytes += length + ARC_HDR_SIZE;
> @@ -1096,13 +1099,13 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
>  	if (arc_proto_map[soft->proto]->is_ip) {
>  		if (BUGLVL(D_PROTO)) {
>  			struct ArcProto
> -			*oldp = arc_proto_map[lp->default_proto[pkt.hard.source]],
> +			*oldp = arc_proto_map[lp->default_proto[rxdata.pkt.hard.source]],
>  			*newp = arc_proto_map[soft->proto];
>  
>  			if (oldp != newp) {
>  				arc_printk(D_PROTO, dev,
>  					   "got protocol %02Xh; encap for host %02Xh is now '%c' (was '%c')\n",
> -					   soft->proto, pkt.hard.source,
> +					   soft->proto, rxdata.pkt.hard.source,
>  					   newp->suffix, oldp->suffix);
>  			}
>  		}
> @@ -1111,10 +1114,10 @@ static void arcnet_rx(struct net_device *dev, int bufnum)
>  		lp->default_proto[0] = soft->proto;
>  
>  		/* in striking contrast, the following isn't a hack. */
> -		lp->default_proto[pkt.hard.source] = soft->proto;
> +		lp->default_proto[rxdata.pkt.hard.source] = soft->proto;
>  	}
>  	/* call the protocol-specific receiver. */
> -	arc_proto_map[soft->proto]->rx(dev, bufnum, &pkt, length);
> +	arc_proto_map[soft->proto]->rx(dev, bufnum, &rxdata.pkt, length);
>  }
>  
>  static void null_rx(struct net_device *dev, int bufnum,
> -- 
> 2.23.0
> 
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] arcnet: provide a buffer big enough to actually receive packets
  2019-09-20 14:08 [PATCH] arcnet: provide a buffer big enough to actually receive packets Uwe Kleine-König
  2019-09-23 11:14 ` Michael Grzeschik
@ 2019-09-24 14:49 ` David Miller
  1 sibling, 0 replies; 3+ messages in thread
From: David Miller @ 2019-09-24 14:49 UTC (permalink / raw)
  To: u.kleine-koenig; +Cc: m.grzeschik, netdev, labbott, stable

From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Date: Fri, 20 Sep 2019 16:08:21 +0200

> struct archdr is only big enough to hold the header of various types of
> arcnet packets. So to provide enough space to hold the data read from
> hardware provide a buffer large enough to hold a packet with maximal
> size.
> 
> The problem was noticed by the stack protector which makes the kernel
> oops.
> 
> Cc: stable@vger.kernel.org # v2.4.0+

Do not CC: stable for networking patches, I take care of it.

> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

Applied and queued up for -stable.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-09-24 14:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-20 14:08 [PATCH] arcnet: provide a buffer big enough to actually receive packets Uwe Kleine-König
2019-09-23 11:14 ` Michael Grzeschik
2019-09-24 14:49 ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).