mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-23 09:42:19 +03:00
nvethernet: Harden while loops
Issue: Unsigned int variable in loop condition can be stuck forever if variable becomes uint_max-1 for unknown reason Fix: Add acceptable range condition check for loops Bug 2715343 Change-Id: I0c29d77fd3c2c7e03e3ff3492acea00b94e3319e Signed-off-by: Mahesh Patil <maheshp@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/2244699 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
Revanth Kumar Uppala
parent
fa8c188668
commit
5176ea0aa5
@@ -1653,7 +1653,7 @@ static int ether_tx_swcx_alloc(struct device *dev,
|
|||||||
/* Map the linear buffers from the skb first.
|
/* Map the linear buffers from the skb first.
|
||||||
* For TSO only upto TCP header is filled in first desc.
|
* For TSO only upto TCP header is filled in first desc.
|
||||||
*/
|
*/
|
||||||
while (len) {
|
while (valid_tx_len(len)) {
|
||||||
tx_swcx = tx_ring->tx_swcx + cur_tx_idx;
|
tx_swcx = tx_ring->tx_swcx + cur_tx_idx;
|
||||||
if (unlikely(tx_swcx->len)) {
|
if (unlikely(tx_swcx->len)) {
|
||||||
goto desc_not_free;
|
goto desc_not_free;
|
||||||
@@ -1685,7 +1685,7 @@ static int ether_tx_swcx_alloc(struct device *dev,
|
|||||||
*/
|
*/
|
||||||
if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) {
|
if ((tx_pkt_cx->flags & OSI_PKT_CX_TSO) == OSI_PKT_CX_TSO) {
|
||||||
len = skb_headlen(skb) - tx_pkt_cx->total_hdrlen;
|
len = skb_headlen(skb) - tx_pkt_cx->total_hdrlen;
|
||||||
while (len) {
|
while (valid_tx_len(len)) {
|
||||||
tx_swcx = tx_ring->tx_swcx + cur_tx_idx;
|
tx_swcx = tx_ring->tx_swcx + cur_tx_idx;
|
||||||
|
|
||||||
if (unlikely(tx_swcx->len)) {
|
if (unlikely(tx_swcx->len)) {
|
||||||
@@ -1719,7 +1719,7 @@ static int ether_tx_swcx_alloc(struct device *dev,
|
|||||||
offset = 0;
|
offset = 0;
|
||||||
frag = &skb_shinfo(skb)->frags[i];
|
frag = &skb_shinfo(skb)->frags[i];
|
||||||
len = skb_frag_size(frag);
|
len = skb_frag_size(frag);
|
||||||
while (len) {
|
while (valid_tx_len(len)) {
|
||||||
tx_swcx = tx_ring->tx_swcx + cur_tx_idx;
|
tx_swcx = tx_ring->tx_swcx + cur_tx_idx;
|
||||||
if (unlikely(tx_swcx->len)) {
|
if (unlikely(tx_swcx->len)) {
|
||||||
goto desc_not_free;
|
goto desc_not_free;
|
||||||
@@ -1759,7 +1759,7 @@ desc_not_free:
|
|||||||
|
|
||||||
dma_map_failed:
|
dma_map_failed:
|
||||||
/* Failed to fill current desc. Rollback previous desc's */
|
/* Failed to fill current desc. Rollback previous desc's */
|
||||||
while (cnt) {
|
while (cnt > 0) {
|
||||||
DECR_TX_DESC_INDEX(cur_tx_idx, 1U);
|
DECR_TX_DESC_INDEX(cur_tx_idx, 1U);
|
||||||
tx_swcx = tx_ring->tx_swcx + cur_tx_idx;
|
tx_swcx = tx_ring->tx_swcx + cur_tx_idx;
|
||||||
if (tx_swcx->buf_phy_addr) {
|
if (tx_swcx->buf_phy_addr) {
|
||||||
|
|||||||
@@ -121,10 +121,34 @@
|
|||||||
#define ETHER_DEFAULT_PLATFORM_MTU 1500U
|
#define ETHER_DEFAULT_PLATFORM_MTU 1500U
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maximum buffer length per DMA descriptor (4KB).
|
* @brief Maximum buffer length per DMA descriptor (16KB).
|
||||||
*/
|
*/
|
||||||
#define ETHER_TX_MAX_BUFF_SIZE 0x3FFF
|
#define ETHER_TX_MAX_BUFF_SIZE 0x3FFF
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Maximum skb frame(GSO/TSO) size (64KB)
|
||||||
|
*/
|
||||||
|
#define ETHER_TX_MAX_FRAME_SIZE GSO_MAX_SIZE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if Tx data buffer length is within bounds.
|
||||||
|
*
|
||||||
|
* Algorithm: Check the data length if it is valid.
|
||||||
|
*
|
||||||
|
* @param[in] length: Tx data buffer length to check
|
||||||
|
*
|
||||||
|
* @retval true if length is valid
|
||||||
|
* @retval false otherwise
|
||||||
|
*/
|
||||||
|
static inline bool valid_tx_len(unsigned int length)
|
||||||
|
{
|
||||||
|
if (length > 0U && length <= ETHER_TX_MAX_FRAME_SIZE) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Descriptors required for maximum contiguous TSO/GSO packet
|
/* Descriptors required for maximum contiguous TSO/GSO packet
|
||||||
* one extra descriptor if there is linear buffer payload
|
* one extra descriptor if there is linear buffer payload
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -190,7 +190,8 @@ static void ether_realloc_rx_skb(struct ether_priv_data *pdata,
|
|||||||
unsigned int local_refill_idx = rx_ring->refill_idx;
|
unsigned int local_refill_idx = rx_ring->refill_idx;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
while (local_refill_idx != rx_ring->cur_rx_idx) {
|
while (local_refill_idx != rx_ring->cur_rx_idx &&
|
||||||
|
local_refill_idx < RX_DESC_CNT) {
|
||||||
rx_swcx = rx_ring->rx_swcx + local_refill_idx;
|
rx_swcx = rx_ring->rx_swcx + local_refill_idx;
|
||||||
rx_desc = rx_ring->rx_desc + local_refill_idx;
|
rx_desc = rx_ring->rx_desc + local_refill_idx;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user