diff options
author | Rasesh Mody <rmody@brocade.com> | 2011-09-16 11:06:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-09-17 00:47:57 -0400 |
commit | b9fa1fbf98178c8bbda23ff1d3ed0731bb3c0bd1 (patch) | |
tree | 7562913799f3ec165d2e0befb43e7e5463dac7c2 /drivers | |
parent | 3fb9852f98ffb4cdd3bad6eb50b1a6d58cee1298 (diff) |
bna: Eliminate Small Race Condition Window in RX Path
Change details:
- In a continuous sequence of ifconfig up/down operations, there is a small
window of race between bnad_set_rx_mode() and bnad_cleanup_rx() while the
former tries to access rx_info->rx & the latter sets it to NULL. This race
could lead to bna_rx_mode_set() being called with a NULL (rx_info->rx)
pointer and a crash.
- Hold bnad->bna_lock while setting / unsetting rx_info->rx in bnad_setup_rx()
& bnad_cleanup_rx(), thereby eliminating the race described above.
Signed-off-by: Gurunatha Karaje <gkaraje@brocade.com>
Signed-off-by: Rasesh Mody <rmody@brocade.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/brocade/bna/bnad.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index 33ab1f81c1c2..abca1399fe51 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c | |||
@@ -1875,10 +1875,10 @@ bnad_cleanup_rx(struct bnad *bnad, u32 rx_id) | |||
1875 | 1875 | ||
1876 | spin_lock_irqsave(&bnad->bna_lock, flags); | 1876 | spin_lock_irqsave(&bnad->bna_lock, flags); |
1877 | bna_rx_destroy(rx_info->rx); | 1877 | bna_rx_destroy(rx_info->rx); |
1878 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
1879 | 1878 | ||
1880 | rx_info->rx = NULL; | 1879 | rx_info->rx = NULL; |
1881 | rx_info->rx_id = 0; | 1880 | rx_info->rx_id = 0; |
1881 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
1882 | 1882 | ||
1883 | bnad_rx_res_free(bnad, res_info); | 1883 | bnad_rx_res_free(bnad, res_info); |
1884 | } | 1884 | } |
@@ -1932,12 +1932,13 @@ bnad_setup_rx(struct bnad *bnad, u32 rx_id) | |||
1932 | spin_lock_irqsave(&bnad->bna_lock, flags); | 1932 | spin_lock_irqsave(&bnad->bna_lock, flags); |
1933 | rx = bna_rx_create(&bnad->bna, bnad, rx_config, &rx_cbfn, res_info, | 1933 | rx = bna_rx_create(&bnad->bna, bnad, rx_config, &rx_cbfn, res_info, |
1934 | rx_info); | 1934 | rx_info); |
1935 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
1936 | if (!rx) { | 1935 | if (!rx) { |
1937 | err = -ENOMEM; | 1936 | err = -ENOMEM; |
1937 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
1938 | goto err_return; | 1938 | goto err_return; |
1939 | } | 1939 | } |
1940 | rx_info->rx = rx; | 1940 | rx_info->rx = rx; |
1941 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | ||
1941 | 1942 | ||
1942 | /* | 1943 | /* |
1943 | * Init NAPI, so that state is set to NAPI_STATE_SCHED, | 1944 | * Init NAPI, so that state is set to NAPI_STATE_SCHED, |