diff options
| author | Anton Vorontsov <anton.vorontsov@linaro.org> | 2012-06-18 22:15:52 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-06-20 19:15:22 -0400 |
| commit | beeb94321a7a6d493b4a06ff0cd771f09f41c35e (patch) | |
| tree | ae276de7228bf62512d5a9ce3b65c76017a6def0 /fs/pstore | |
| parent | 90b58d96907e0a45555429c0d3a79c85cea4b9fc (diff) | |
pstore/ram_core: Proper checking for post_init errors (e.g. improper ECC size)
We will implement variable-sized ECC buffers soon, so post_init routine
might fail much more likely, so we'd better check for its errors.
To make error handling simple, modify persistent_ram_free() to it be safe
at all times.
Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Acked-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/pstore')
| -rw-r--r-- | fs/pstore/ram_core.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c index 26531856daf8..f62ebf2dfed7 100644 --- a/fs/pstore/ram_core.c +++ b/fs/pstore/ram_core.c | |||
| @@ -427,11 +427,17 @@ static int __devinit persistent_ram_post_init(struct persistent_ram_zone *prz, | |||
| 427 | 427 | ||
| 428 | void persistent_ram_free(struct persistent_ram_zone *prz) | 428 | void persistent_ram_free(struct persistent_ram_zone *prz) |
| 429 | { | 429 | { |
| 430 | if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { | 430 | if (!prz) |
| 431 | vunmap(prz->vaddr); | 431 | return; |
| 432 | } else { | 432 | |
| 433 | iounmap(prz->vaddr); | 433 | if (prz->vaddr) { |
| 434 | release_mem_region(prz->paddr, prz->size); | 434 | if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { |
| 435 | vunmap(prz->vaddr); | ||
| 436 | } else { | ||
| 437 | iounmap(prz->vaddr); | ||
| 438 | release_mem_region(prz->paddr, prz->size); | ||
| 439 | } | ||
| 440 | prz->vaddr = NULL; | ||
| 435 | } | 441 | } |
| 436 | persistent_ram_free_old(prz); | 442 | persistent_ram_free_old(prz); |
| 437 | kfree(prz); | 443 | kfree(prz); |
| @@ -454,10 +460,12 @@ struct persistent_ram_zone * __devinit persistent_ram_new(phys_addr_t start, | |||
| 454 | if (ret) | 460 | if (ret) |
| 455 | goto err; | 461 | goto err; |
| 456 | 462 | ||
| 457 | persistent_ram_post_init(prz, ecc); | 463 | ret = persistent_ram_post_init(prz, ecc); |
| 464 | if (ret) | ||
| 465 | goto err; | ||
| 458 | 466 | ||
| 459 | return prz; | 467 | return prz; |
| 460 | err: | 468 | err: |
| 461 | kfree(prz); | 469 | persistent_ram_free(prz); |
| 462 | return ERR_PTR(ret); | 470 | return ERR_PTR(ret); |
| 463 | } | 471 | } |
