lkml.org 
[lkml]   [2019]   [Oct]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.3 001/344] arcnet: provide a buffer big enough to actually receive packets
    Date
    From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

    [ Upstream commit 108639aac35eb57f1d0e8333f5fc8c7ff68df938 ]

    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.

    Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
    Acked-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/arcnet/arcnet.c | 31 +++++++++++++++++--------------
    1 file changed, 17 insertions(+), 14 deletions(-)

    --- 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
    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
    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,

    \
     
     \ /
      Last update: 2019-10-03 18:38    [W:2.929 / U:0.636 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site