Re: [PATCH] arcnet: provide a buffer big enough to actually receive packets

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

 



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@xxxxxxxxxxxxxxx # v2.4.0+
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>

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

> ---
> 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: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux