提交 02a07046 编写于 作者: U Uwe Kleine-König 提交者: David S. Miller

arcnet: provide a buffer big enough to actually receive packets

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: NUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: NMichael Grzeschik <m.grzeschik@pengutronix.de>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 0edc3f70
......@@ -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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册