aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-09-14 00:52:41 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-09-14 00:52:41 -0400
commit145ea6f10d42dac0a1e8a6dfb83b273c0acabf5b (patch)
treecac7179f0f523f2f20d9e9cbe1d100d19b6d7bc5
parent4624d6ea1b7fe83f1e36caf4537600414ca833f6 (diff)
parent831b624df1b420c8f9281ed1307a8db23afb72df (diff)
Merge tag 'pstore-v4.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull pstore fix from Kees Cook: "This fixes a 6 year old pstore bug that everyone just got lucky in avoiding, likely due only using page-aligned persistent ram regions: - Handle page-vs-byte offset handling between iomap and vmap (Bin Yang)" * tag 'pstore-v4.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: pstore: Fix incorrect persistent ram buffer mapping
-rw-r--r--fs/pstore/ram_core.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index 951a14edcf51..0792595ebcfb 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -429,7 +429,12 @@ static void *persistent_ram_vmap(phys_addr_t start, size_t size,
429 vaddr = vmap(pages, page_count, VM_MAP, prot); 429 vaddr = vmap(pages, page_count, VM_MAP, prot);
430 kfree(pages); 430 kfree(pages);
431 431
432 return vaddr; 432 /*
433 * Since vmap() uses page granularity, we must add the offset
434 * into the page here, to get the byte granularity address
435 * into the mapping to represent the actual "start" location.
436 */
437 return vaddr + offset_in_page(start);
433} 438}
434 439
435static void *persistent_ram_iomap(phys_addr_t start, size_t size, 440static void *persistent_ram_iomap(phys_addr_t start, size_t size,
@@ -448,6 +453,11 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size,
448 else 453 else
449 va = ioremap_wc(start, size); 454 va = ioremap_wc(start, size);
450 455
456 /*
457 * Since request_mem_region() and ioremap() are byte-granularity
458 * there is no need handle anything special like we do when the
459 * vmap() case in persistent_ram_vmap() above.
460 */
451 return va; 461 return va;
452} 462}
453 463
@@ -468,7 +478,7 @@ static int persistent_ram_buffer_map(phys_addr_t start, phys_addr_t size,
468 return -ENOMEM; 478 return -ENOMEM;
469 } 479 }
470 480
471 prz->buffer = prz->vaddr + offset_in_page(start); 481 prz->buffer = prz->vaddr;
472 prz->buffer_size = size - sizeof(struct persistent_ram_buffer); 482 prz->buffer_size = size - sizeof(struct persistent_ram_buffer);
473 483
474 return 0; 484 return 0;
@@ -515,7 +525,8 @@ void persistent_ram_free(struct persistent_ram_zone *prz)
515 525
516 if (prz->vaddr) { 526 if (prz->vaddr) {
517 if (pfn_valid(prz->paddr >> PAGE_SHIFT)) { 527 if (pfn_valid(prz->paddr >> PAGE_SHIFT)) {
518 vunmap(prz->vaddr); 528 /* We must vunmap() at page-granularity. */
529 vunmap(prz->vaddr - offset_in_page(prz->paddr));
519 } else { 530 } else {
520 iounmap(prz->vaddr); 531 iounmap(prz->vaddr);
521 release_mem_region(prz->paddr, prz->size); 532 release_mem_region(prz->paddr, prz->size);