mac80211: pid, fix memory corruption

pid doesn't count with some band having more bitrates than the one
associated the first time.
Fix that by counting the maximal available bitrate count and allocate
big enough space.

Secondly, fix touching uninitialized memory which causes panics.
Index sucked from this random memory points to the hell.
The fix is to sort the rates on each band change.

Signed-off-by: Jiri Slaby <jirislaby@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Jiri Slaby 2009-05-04 18:10:28 +02:00 committed by John W. Linville
parent 8e53217527
commit 6909268dc9

View File

@ -317,57 +317,17 @@ rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
struct rc_pid_sta_info *spinfo = priv_sta;
struct rc_pid_info *pinfo = priv;
struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
struct sta_info *si;
int i, j, tmp;
bool s;
/* TODO: This routine should consider using RSSI from previous packets
* as we need to have IEEE 802.1X auth succeed immediately after assoc..
* Until that method is implemented, we will use the lowest supported
* rate as a workaround. */
spinfo->txrate_idx = rate_lowest_index(sband, sta);
/* HACK */
si = container_of(sta, struct sta_info, sta);
si->fail_avg = 0;
}
static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
struct dentry *debugfsdir)
{
struct rc_pid_info *pinfo;
struct rc_pid_rateinfo *rinfo;
struct ieee80211_supported_band *sband;
int i, j, tmp;
bool s;
#ifdef CONFIG_MAC80211_DEBUGFS
struct rc_pid_debugfs_entries *de;
#endif
sband = hw->wiphy->bands[hw->conf.channel->band];
pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
if (!pinfo)
return NULL;
/* We can safely assume that sband won't change unless we get
* reinitialized. */
rinfo = kmalloc(sizeof(*rinfo) * sband->n_bitrates, GFP_ATOMIC);
if (!rinfo) {
kfree(pinfo);
return NULL;
}
pinfo->target = RC_PID_TARGET_PF;
pinfo->sampling_period = RC_PID_INTERVAL;
pinfo->coeff_p = RC_PID_COEFF_P;
pinfo->coeff_i = RC_PID_COEFF_I;
pinfo->coeff_d = RC_PID_COEFF_D;
pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
pinfo->norm_offset = RC_PID_NORM_OFFSET;
pinfo->rinfo = rinfo;
pinfo->oldrate = 0;
/* Sort the rates. This is optimized for the most common case (i.e.
* almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
* mapping too. */
@ -395,6 +355,51 @@ static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
break;
}
spinfo->txrate_idx = rate_lowest_index(sband, sta);
/* HACK */
si = container_of(sta, struct sta_info, sta);
si->fail_avg = 0;
}
static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
struct dentry *debugfsdir)
{
struct rc_pid_info *pinfo;
struct rc_pid_rateinfo *rinfo;
struct ieee80211_supported_band *sband;
int i, max_rates = 0;
#ifdef CONFIG_MAC80211_DEBUGFS
struct rc_pid_debugfs_entries *de;
#endif
pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
if (!pinfo)
return NULL;
for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
sband = hw->wiphy->bands[i];
if (sband->n_bitrates > max_rates)
max_rates = sband->n_bitrates;
}
rinfo = kmalloc(sizeof(*rinfo) * max_rates, GFP_ATOMIC);
if (!rinfo) {
kfree(pinfo);
return NULL;
}
pinfo->target = RC_PID_TARGET_PF;
pinfo->sampling_period = RC_PID_INTERVAL;
pinfo->coeff_p = RC_PID_COEFF_P;
pinfo->coeff_i = RC_PID_COEFF_I;
pinfo->coeff_d = RC_PID_COEFF_D;
pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
pinfo->norm_offset = RC_PID_NORM_OFFSET;
pinfo->rinfo = rinfo;
pinfo->oldrate = 0;
#ifdef CONFIG_MAC80211_DEBUGFS
de = &pinfo->dentries;
de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,