[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20190923111458.dwmnyiy4nxvgogv2@pengutronix.de>
Date: Mon, 23 Sep 2019 13:14:58 +0200
From: Michael Grzeschik <mgr@...gutronix.de>
To: Uwe Kleine-König
<u.kleine-koenig@...gutronix.de>
Cc: "David S. Miller" <davem@...emloft.net>, netdev@...r.kernel.org,
Laura Abbott <labbott@...hat.com>, stable@...r.kernel.org
Subject: Re: [PATCH] arcnet: provide a buffer big enough to actually receive
packets
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@...r.kernel.org # v2.4.0+
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@...gutronix.de>
Acked-by: Michael Grzeschik <m.grzeschik@...gutronix.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 |
Download attachment "signature.asc" of type "application/pgp-signature" (834 bytes)
Powered by blists - more mailing lists