提交 6c606fa3 编写于 作者: T Timo Teräs 提交者: David S. Miller

via-velocity: unconditionally drop frames with bad l2 length

By default the driver allowed incorrect frames to be received. What is
worse the code does not handle very short frames correctly. The FCS
length is unconditionally subtracted, and the underflow can cause
skb_put to be called with large number after implicit cast to unsigned.
And indeed, an skb_over_panic() was observed with via-velocity.

This removes the module parameter as it does not work in it's
current state, and should be implemented via NETIF_F_RXALL if needed.
Suggested-by: NFrancois Romieu <romieu@fr.zoreil.com>
Signed-off-by: NTimo Teräs <timo.teras@iki.fi>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 f1a454a3
......@@ -345,13 +345,6 @@ VELOCITY_PARAM(flow_control, "Enable flow control ability");
*/
VELOCITY_PARAM(speed_duplex, "Setting the speed and duplex mode");
#define VAL_PKT_LEN_DEF 0
/* ValPktLen[] is used for setting the checksum offload ability of NIC.
0: Receive frame with invalid layer 2 length (Default)
1: Drop frame with invalid layer 2 length
*/
VELOCITY_PARAM(ValPktLen, "Receiving or Drop invalid 802.3 frame");
#define WOL_OPT_DEF 0
#define WOL_OPT_MIN 0
#define WOL_OPT_MAX 7
......@@ -494,7 +487,6 @@ static void velocity_get_options(struct velocity_opt *opts, int index,
velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
velocity_set_bool_opt(&opts->flags, ValPktLen[index], VAL_PKT_LEN_DEF, VELOCITY_FLAGS_VAL_PKT_LEN, "ValPktLen", devname);
velocity_set_int_opt((int *) &opts->spd_dpx, speed_duplex[index], MED_LNK_MIN, MED_LNK_MAX, MED_LNK_DEF, "Media link mode", devname);
velocity_set_int_opt(&opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname);
opts->numrx = (opts->numrx & ~3);
......@@ -2055,7 +2047,8 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff;
struct sk_buff *skb;
if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
if (unlikely(rd->rdesc0.RSR & (RSR_STP | RSR_EDP | RSR_RL))) {
if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP))
VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame spans multiple RDs.\n", vptr->netdev->name);
stats->rx_length_errors++;
return -EINVAL;
......@@ -2069,17 +2062,6 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
dma_sync_single_for_cpu(vptr->dev, rd_info->skb_dma,
vptr->rx.buf_sz, DMA_FROM_DEVICE);
/*
* Drop frame not meeting IEEE 802.3
*/
if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
if (rd->rdesc0.RSR & RSR_RL) {
stats->rx_length_errors++;
return -EINVAL;
}
}
velocity_rx_csum(rd, skb);
if (velocity_rx_copy(&skb, pkt_len, vptr) < 0) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册