diff options
author | Al Cooper <alcooperx@gmail.com> | 2013-02-05 09:08:10 -0500 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2013-02-13 07:49:42 -0500 |
commit | 221b1bd3d409b14e8764d8f40994b71ae6887d18 (patch) | |
tree | 6e2088095b662831e8851e77725b5e9d156e382e /drivers/mtd/tests | |
parent | eb82038f97f93c5f0ff274fb98a9fff741dc2f5e (diff) |
mtd: mtd_torturetest can cause stack overflows
mtd_torturetest uses the module parm "ebcnt" to control the size of a
stack based array of int's. When "ebcnt" is large, Ex: 1000, it
causes stack overflows on systems with small kernel stacks. The fix
is to move the array from the stack to kmalloc memory.
Signed-off-by: Al Cooper <alcooperx@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd/tests')
-rw-r--r-- | drivers/mtd/tests/mtd_torturetest.c | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c index c4cde1e9eddb..3a9f6a6a79f9 100644 --- a/drivers/mtd/tests/mtd_torturetest.c +++ b/drivers/mtd/tests/mtd_torturetest.c | |||
@@ -208,7 +208,7 @@ static inline int write_pattern(int ebnum, void *buf) | |||
208 | static int __init tort_init(void) | 208 | static int __init tort_init(void) |
209 | { | 209 | { |
210 | int err = 0, i, infinite = !cycles_count; | 210 | int err = 0, i, infinite = !cycles_count; |
211 | int bad_ebs[ebcnt]; | 211 | int *bad_ebs; |
212 | 212 | ||
213 | printk(KERN_INFO "\n"); | 213 | printk(KERN_INFO "\n"); |
214 | printk(KERN_INFO "=================================================\n"); | 214 | printk(KERN_INFO "=================================================\n"); |
@@ -250,28 +250,24 @@ static int __init tort_init(void) | |||
250 | 250 | ||
251 | err = -ENOMEM; | 251 | err = -ENOMEM; |
252 | patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL); | 252 | patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL); |
253 | if (!patt_5A5) { | 253 | if (!patt_5A5) |
254 | pr_err("error: cannot allocate memory\n"); | ||
255 | goto out_mtd; | 254 | goto out_mtd; |
256 | } | ||
257 | 255 | ||
258 | patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL); | 256 | patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL); |
259 | if (!patt_A5A) { | 257 | if (!patt_A5A) |
260 | pr_err("error: cannot allocate memory\n"); | ||
261 | goto out_patt_5A5; | 258 | goto out_patt_5A5; |
262 | } | ||
263 | 259 | ||
264 | patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL); | 260 | patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL); |
265 | if (!patt_FF) { | 261 | if (!patt_FF) |
266 | pr_err("error: cannot allocate memory\n"); | ||
267 | goto out_patt_A5A; | 262 | goto out_patt_A5A; |
268 | } | ||
269 | 263 | ||
270 | check_buf = kmalloc(mtd->erasesize, GFP_KERNEL); | 264 | check_buf = kmalloc(mtd->erasesize, GFP_KERNEL); |
271 | if (!check_buf) { | 265 | if (!check_buf) |
272 | pr_err("error: cannot allocate memory\n"); | ||
273 | goto out_patt_FF; | 266 | goto out_patt_FF; |
274 | } | 267 | |
268 | bad_ebs = kcalloc(ebcnt, sizeof(*bad_ebs), GFP_KERNEL); | ||
269 | if (!bad_ebs) | ||
270 | goto out_check_buf; | ||
275 | 271 | ||
276 | err = 0; | 272 | err = 0; |
277 | 273 | ||
@@ -290,7 +286,6 @@ static int __init tort_init(void) | |||
290 | /* | 286 | /* |
291 | * Check if there is a bad eraseblock among those we are going to test. | 287 | * Check if there is a bad eraseblock among those we are going to test. |
292 | */ | 288 | */ |
293 | memset(&bad_ebs[0], 0, sizeof(int) * ebcnt); | ||
294 | if (mtd_can_have_bb(mtd)) { | 289 | if (mtd_can_have_bb(mtd)) { |
295 | for (i = eb; i < eb + ebcnt; i++) { | 290 | for (i = eb; i < eb + ebcnt; i++) { |
296 | err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize); | 291 | err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize); |
@@ -394,6 +389,8 @@ out: | |||
394 | 389 | ||
395 | pr_info("finished after %u erase cycles\n", | 390 | pr_info("finished after %u erase cycles\n", |
396 | erase_cycles); | 391 | erase_cycles); |
392 | kfree(bad_ebs); | ||
393 | out_check_buf: | ||
397 | kfree(check_buf); | 394 | kfree(check_buf); |
398 | out_patt_FF: | 395 | out_patt_FF: |
399 | kfree(patt_FF); | 396 | kfree(patt_FF); |