aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Mason <jon.mason@exar.com>2010-12-10 10:40:01 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-11 14:46:36 -0500
commit1853e2e15dc95ff3430530941b5856581251ef70 (patch)
tree0ae74601e624a49ebab41de725e2793fbfddb564
parent9835fd7321a67feba6432e63bf2cba43f5a56bd9 (diff)
s2io: rx_ring_sz bounds checking
modparm rx_ring_sz can be set to be greater than the maximum allowable number of blocks. This results in an array overrun when probing the driver, and causes memory corruption. Also, the MAX_RX_DESC_1 multiply the max number of rings by max number of blocker per ring by 127, but the driver does the same calculation with 127+1. This results in the possibility of the value being set being larger than the maximum allowable value. Finally, clean-up the s2io_ethtool_gringparam code to be more intuitive. Signed-off-by: Jon Mason <jon.mason@exar.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/s2io.c40
-rw-r--r--drivers/net/s2io.h5
2 files changed, 26 insertions, 19 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 0f4219cb0be2..a6d3eaf44863 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -5568,30 +5568,27 @@ static void s2io_ethtool_gringparam(struct net_device *dev,
5568 struct s2io_nic *sp = netdev_priv(dev); 5568 struct s2io_nic *sp = netdev_priv(dev);
5569 int i, tx_desc_count = 0, rx_desc_count = 0; 5569 int i, tx_desc_count = 0, rx_desc_count = 0;
5570 5570
5571 if (sp->rxd_mode == RXD_MODE_1) 5571 if (sp->rxd_mode == RXD_MODE_1) {
5572 ering->rx_max_pending = MAX_RX_DESC_1; 5572 ering->rx_max_pending = MAX_RX_DESC_1;
5573 else if (sp->rxd_mode == RXD_MODE_3B) 5573 ering->rx_jumbo_max_pending = MAX_RX_DESC_1;
5574 } else {
5574 ering->rx_max_pending = MAX_RX_DESC_2; 5575 ering->rx_max_pending = MAX_RX_DESC_2;
5576 ering->rx_jumbo_max_pending = MAX_RX_DESC_2;
5577 }
5575 5578
5579 ering->rx_mini_max_pending = 0;
5576 ering->tx_max_pending = MAX_TX_DESC; 5580 ering->tx_max_pending = MAX_TX_DESC;
5577 for (i = 0 ; i < sp->config.tx_fifo_num ; i++)
5578 tx_desc_count += sp->config.tx_cfg[i].fifo_len;
5579 5581
5580 DBG_PRINT(INFO_DBG, "max txds: %d\n", sp->config.max_txds); 5582 for (i = 0; i < sp->config.rx_ring_num; i++)
5581 ering->tx_pending = tx_desc_count;
5582 rx_desc_count = 0;
5583 for (i = 0 ; i < sp->config.rx_ring_num ; i++)
5584 rx_desc_count += sp->config.rx_cfg[i].num_rxd; 5583 rx_desc_count += sp->config.rx_cfg[i].num_rxd;
5585
5586 ering->rx_pending = rx_desc_count; 5584 ering->rx_pending = rx_desc_count;
5587
5588 ering->rx_mini_max_pending = 0;
5589 ering->rx_mini_pending = 0;
5590 if (sp->rxd_mode == RXD_MODE_1)
5591 ering->rx_jumbo_max_pending = MAX_RX_DESC_1;
5592 else if (sp->rxd_mode == RXD_MODE_3B)
5593 ering->rx_jumbo_max_pending = MAX_RX_DESC_2;
5594 ering->rx_jumbo_pending = rx_desc_count; 5585 ering->rx_jumbo_pending = rx_desc_count;
5586 ering->rx_mini_pending = 0;
5587
5588 for (i = 0; i < sp->config.tx_fifo_num; i++)
5589 tx_desc_count += sp->config.tx_cfg[i].fifo_len;
5590 ering->tx_pending = tx_desc_count;
5591 DBG_PRINT(INFO_DBG, "max txds: %d\n", sp->config.max_txds);
5595} 5592}
5596 5593
5597/** 5594/**
@@ -7692,6 +7689,8 @@ static void s2io_init_pci(struct s2io_nic *sp)
7692static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, 7689static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
7693 u8 *dev_multiq) 7690 u8 *dev_multiq)
7694{ 7691{
7692 int i;
7693
7695 if ((tx_fifo_num > MAX_TX_FIFOS) || (tx_fifo_num < 1)) { 7694 if ((tx_fifo_num > MAX_TX_FIFOS) || (tx_fifo_num < 1)) {
7696 DBG_PRINT(ERR_DBG, "Requested number of tx fifos " 7695 DBG_PRINT(ERR_DBG, "Requested number of tx fifos "
7697 "(%d) not supported\n", tx_fifo_num); 7696 "(%d) not supported\n", tx_fifo_num);
@@ -7750,6 +7749,15 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type,
7750 DBG_PRINT(ERR_DBG, "Defaulting to 1-buffer mode\n"); 7749 DBG_PRINT(ERR_DBG, "Defaulting to 1-buffer mode\n");
7751 rx_ring_mode = 1; 7750 rx_ring_mode = 1;
7752 } 7751 }
7752
7753 for (i = 0; i < MAX_RX_RINGS; i++)
7754 if (rx_ring_sz[i] > MAX_RX_BLOCKS_PER_RING) {
7755 DBG_PRINT(ERR_DBG, "Requested rx ring size not "
7756 "supported\nDefaulting to %d\n",
7757 MAX_RX_BLOCKS_PER_RING);
7758 rx_ring_sz[i] = MAX_RX_BLOCKS_PER_RING;
7759 }
7760
7753 return SUCCESS; 7761 return SUCCESS;
7754} 7762}
7755 7763
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 00b8614efe48..1671443b3c0e 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -355,9 +355,8 @@ struct stat_block {
355#define FIFO_OTHER_MAX_NUM 1 355#define FIFO_OTHER_MAX_NUM 1
356 356
357 357
358#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 ) 358#define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 128)
359#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) 359#define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 86)
360#define MAX_RX_DESC_3 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
361#define MAX_TX_DESC (MAX_AVAILABLE_TXDS) 360#define MAX_TX_DESC (MAX_AVAILABLE_TXDS)
362 361
363/* FIFO mappings for all possible number of fifos configured */ 362/* FIFO mappings for all possible number of fifos configured */