Skip to contentSkip to conversation

ath5k: avoid oops when ah_capabilities.cap_mode not set

PATCH In review John W. Linville 3 participants 6 messages Oct 17, 2007 – Nov 20, 2007 Networking drivers (wireless)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ath5k: avoid oops when ah_capabilities.cap_mode not set

ah_capabilities.cap_mode doesn't get set for some cards, causing the kernel to oops when these unknown/unsupported cards are inserted. Add some NULL checks to avoid this.

---
 drivers/net/wireless/ath5k/base.c |    3 +++
 drivers/net/wireless/ath5k/hw.c   |    4 ++++
 2 files changed, 7 insertions(+), 0 deletions(-)
drivers/net/wireless/ath5k/base.c +3 -0
index da72056..40f5ce6 100644
@@ -2007,6 +2007,9 @@ static int ath_getchannels(struct ieee80211_hw *hw)
 		}
 
 		hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
+		if (!hw_rates)
+			return -EINVAL;
+
 		mode->num_rates    = ath_copy_rates(mode->rates, hw_rates,
 			max_r);
 		mode->num_channels = ath_copy_channels(ah, mode->channels,
drivers/net/wireless/ath5k/hw.c +4 -0
index 504f642..7202e50 100644
@@ -670,6 +670,8 @@ int ath5k_hw_reset(struct ath_hw *hal, enum ieee80211_if_types op_mode,
 				/*Get rate table for this operation mode*/
 				rt = ath5k_hw_get_rate_table(hal,
 						MODE_IEEE80211B);
+				if (!rt)
+					return -EINVAL;
 
 				/*Write rate duration table*/
 				for (i = 0; i < rt->rate_count; i++) {
@@ -695,6 +697,8 @@ int ath5k_hw_reset(struct ath_hw *hal, enum ieee80211_if_types op_mode,
 				rt = ath5k_hw_get_rate_table(hal,
 				    channel->val & CHANNEL_TURBO ?
 				    MODE_ATHEROS_TURBO : MODE_ATHEROS_TURBOG);
+				if (!rt)
+					return -EINVAL;
 
 				/* Write rate duration table */
 				for (i = 0; i < rt->rate_count; i++)
Signature · 1 line
1.5.2.4
#2 lore raw
Quoted 9 lines · Luis R. Rodriguez
Quoted 5 lines · John W. Linville

ah_capabilities.cap_mode doesn't get set for some cards, causing the kernel to oops when these unknown/unsupported cards are inserted. Add some NULL checks to avoid this.

Actually, this hunk in ath5k_getchannels can't return -EINVAL immediately, since there are ath5k cards that do only MODE_IEEE80211A, which is searched last.

comments?

cheers,
Kyle

drivers/net/wireless/ath5k/base.c +2 -0
@@ -1041,6 +1041,8 @@
 		}
 
 		hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
+		if (!hw_rates)
+			continue;
 		mode->num_rates    = ath5k_copy_rates(mode->rates, hw_rates,
 			max_r);
 		mode->num_channels = ath5k_copy_channels(ah, mode->channels,
drivers/net/wireless/ath5k/hw.c +2 -0
@@ -536,6 +536,8 @@
 	/* Get rate table for the current operating mode */
 	rt = ath5k_hw_get_rate_table(ah,
 		driver_mode);
+	if (!rt)
+		return -EINVAL;
 
 	/* Write rate duration table */
 	for (i = 0; i < rt->rate_count; i++) {
#3 lore raw
In reply to Luis R. Rodriguez
Quoted 9 lines · Luis R. Rodriguez
Quoted 5 lines · John W. Linville

ah_capabilities.cap_mode doesn't get set for some cards, causing the kernel to oops when these unknown/unsupported cards are inserted. Add some NULL checks to avoid this.

has this been dropped on the floor? I spotted it while going through Fedora 7 kernel patches...

cheers,
Kyle

#4 lore raw
Quoted 7 lines · Kyle McMartin
Quoted 5 lines · Luis R. Rodriguez
Quoted 4 lines · John W. Linville

ah_capabilities.cap_mode doesn't get set for some cards, causing the kernel to oops when these unknown/unsupported cards are inserted. Add some NULL checks to avoid this.

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

has this been dropped on the floor? I spotted it while going through Fedora 7 kernel patches...

Nope, just the first hunk:

mcgrof@shelby:~/devel/wireless-2.6$ git-show
7364ee74beb763bbf3c450e5b5e189d3128a3164

commit 7364ee74beb763bbf3c450e5b5e189d3128a3164

Author: John W. Linville <[email protected]>
Date:   Tue Oct 23 13:41:37 2007 -0400

[PATCH] ath5k: undo overzealous hunk of "ath5k: avoid oops when..."

The first hunk of "ath5k: avoid oops when ah_capabilities.cap_mode not set" was ill-advised. It can cause its loop to abort prematurely.

(quoted diff) +0 -0

b/drivers/net/wireless/ath5k/base.c
index c38adab..e764fd3 100644

drivers/net/wireless/ath5k/base.c +0 -3
@@ -1991,9 +1991,6 @@ static int ath5k_getchannels(struct ieee80211_hw *hw)
                }
 
                hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
-               if (!hw_rates)
-                       return -EINVAL;
-
                mode->num_rates    = ath5k_copy_rates(mode->rates, hw_rates,
                        max_r);
                mode->num_channels = ath5k_copy_channels(ah, mode->channels,
#5 lore raw
Quoted 41 lines · Luis R. Rodriguez
Quoted 7 lines · Kyle McMartin
Quoted 5 lines · Luis R. Rodriguez
Quoted 4 lines · John W. Linville

ah_capabilities.cap_mode doesn't get set for some cards, causing the kernel to oops when these unknown/unsupported cards are inserted. Add some NULL checks to avoid this.

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

has this been dropped on the floor? I spotted it while going through Fedora 7 kernel patches...

Nope, just the first hunk:

mcgrof@shelby:~/devel/wireless-2.6$ git-show
7364ee74beb763bbf3c450e5b5e189d3128a3164

commit 7364ee74beb763bbf3c450e5b5e189d3128a3164

Author: John W. Linville <[email protected]>
Date:   Tue Oct 23 13:41:37 2007 -0400

[PATCH] ath5k: undo overzealous hunk of "ath5k: avoid oops when..."

The first hunk of "ath5k: avoid oops when ah_capabilities.cap_mode not set" was ill-advised. It can cause its loop to abort prematurely.

drivers/net/wireless/ath5k/base.c +0 -0
index c38adab..e764fd3 100644

drivers/net/wireless/ath5k/base.c static int ath5k_getchannels(struct ieee80211_hw *hw) · line 1996

Quoted 9 lines
drivers/net/wireless/ath5k/base.c +0 -3
@@ -1991,9 +1991,6 @@ static int ath5k_getchannels(struct ieee80211_hw *hw)
                }
 
                hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
-               if (!hw_rates)
-                       return -EINVAL;
-
                mode->num_rates    = ath5k_copy_rates(mode->rates, hw_rates,
                        max_r);
                mode->num_channels = ath5k_copy_channels(ah, mode->channels,

Also the

if (!rt)

are no longer necessary and not used as we are passing driver_mode on ath5k_hw_reset() now and that has a switch statement which catches any invalid mode. The whole rate duration stuff was moved out to ath5k_hw_write_rate_duration().

Luis