diff options
author | Reinette Chatre <reinette.chatre@intel.com> | 2007-12-19 01:01:02 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2007-12-19 21:31:01 -0500 |
commit | 412e9e7800360ec93b6ba319b30666f6bfc721bd (patch) | |
tree | 03f8c45a68c123f8a290c567f07f12d500472ea5 | |
parent | b24d22b1d12c436a86282347868785207cff8a88 (diff) |
ipw2200: prevent alloc of unspecified size on stack
if log_len is larger than 4K then we are killing the stack.
allocate on heap instead and limit size to what practically can
be used (PAGE_SIZE)
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 54f44e5473c0..38ce8ee8d6f9 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -1233,9 +1233,19 @@ static ssize_t show_event_log(struct device *d, | |||
1233 | { | 1233 | { |
1234 | struct ipw_priv *priv = dev_get_drvdata(d); | 1234 | struct ipw_priv *priv = dev_get_drvdata(d); |
1235 | u32 log_len = ipw_get_event_log_len(priv); | 1235 | u32 log_len = ipw_get_event_log_len(priv); |
1236 | struct ipw_event log[log_len]; | 1236 | u32 log_size; |
1237 | struct ipw_event *log; | ||
1237 | u32 len = 0, i; | 1238 | u32 len = 0, i; |
1238 | 1239 | ||
1240 | /* not using min() because of its strict type checking */ | ||
1241 | log_size = PAGE_SIZE / sizeof(*log) > log_len ? | ||
1242 | sizeof(*log) * log_len : PAGE_SIZE; | ||
1243 | log = kzalloc(log_size, GFP_KERNEL); | ||
1244 | if (!log) { | ||
1245 | IPW_ERROR("Unable to allocate memory for log\n"); | ||
1246 | return 0; | ||
1247 | } | ||
1248 | log_len = log_size / sizeof(*log); | ||
1239 | ipw_capture_event_log(priv, log_len, log); | 1249 | ipw_capture_event_log(priv, log_len, log); |
1240 | 1250 | ||
1241 | len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len); | 1251 | len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len); |
@@ -1244,6 +1254,7 @@ static ssize_t show_event_log(struct device *d, | |||
1244 | "\n%08X%08X%08X", | 1254 | "\n%08X%08X%08X", |
1245 | log[i].time, log[i].event, log[i].data); | 1255 | log[i].time, log[i].event, log[i].data); |
1246 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); | 1256 | len += snprintf(buf + len, PAGE_SIZE - len, "\n"); |
1257 | kfree(log); | ||
1247 | return len; | 1258 | return len; |
1248 | } | 1259 | } |
1249 | 1260 | ||