powerpc: Fail remap_4k_pfn() if PFN doesn't fit inside PTE
PATCH 1/1 powerpc: Fail remap_4k_pfn() if PFN doesn't fit inside PTE
remap_4k_pfn() silently truncates upper bits of input 4K PFN if it cannot be contained in PTE. This leads invalid memory mapping and could result in a system crash when the memory is accessed. This patch fails remap_4k_pfn() and returns -EINVAL if the input 4K PFN cannot be contained in PTE.
Used a helper inline function in the failure case so that the remap_4k_pfn() macro can still be used in expression contexts.
--- arch/powerpc/include/asm/pte-hash64-64k.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
arch/powerpc/include/asm/pte-hash64-64k.h +9 -2
@@ -74,8 +74,15 @@#define pte_pagesize_index (mm, addr, pte) \ (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K) +static inline int bad_4k_pfn (void ) +{ +WARN_ON (1 ); +return -EINVAL ; +} +#define remap_4k_pfn (vma, addr, pfn, prot) \ - remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ - __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)) + ((pfn >= (1UL << (64 - PTE_RPN_SHIFT))) ? bad_4k_pfn() : \ + remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ + __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)))#endif /* __ASSEMBLY__ */
Signature · 1 line
2.0.1
Hi Madhusudanan,
Quoted 13 lines · On Wed, 09 Jul 2014 21:38:31 +0530 Madhusudanan Kandasamy…
arch/powerpc/include/asm/pte-hash64-64k.h +4
-0@@ -74,8 +74,15 @@#define pte_pagesize_index (mm, addr, pte) \ (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K) +static inline int bad_4k_pfn (void ) +{ +WARN_ON (1 ); +return -EINVAL ;
arch/powerpc/include/asm/pte-hash64-64k.h line 88
Quoted 10 lines
arch/powerpc/include/asm/pte-hash64-64k.h +5
-2+} +#define remap_4k_pfn (vma, addr, pfn, prot) \ - remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ - __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)) + ((pfn >= (1UL << (64 - PTE_RPN_SHIFT))) ? bad_4k_pfn() : \ + remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ + __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)))#endif /* __ASSEMBLY__ */
WARN_ON() returns the value it is passed, so no helper is needed:
#define remap_4k_pfn(vma, addr, pfn, prot) \
- remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
- __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN))
+ WARN_ON(((pfn >= (1UL << (64 - PTE_RPN_SHIFT)))) ? -EINVAL : \
+ remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \
+ __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)))
Signature · 2 lines
Cheers, Stephen Rothwell [email protected]
Hi Stephen,
Thanks for the suggestion, I'll send a new patch.
Quoted 36 lines · Stephen Rothwell
Hi Madhusudanan,
Quoted 13 lines · On Wed, 09 Jul 2014 21:38:31 +0530 Madhusudanan Kandasamy…
arch/powerpc/include/asm/pte-hash64-64k.h +4
-0@@ -74,8 +74,15 @@#define pte_pagesize_index (mm, addr, pte) \ (((pte) & _PAGE_COMBO)? MMU_PAGE_4K: MMU_PAGE_64K) +static inline int bad_4k_pfn (void ) +{ +WARN_ON (1 ); +return -EINVAL ;arch/powerpc/include/asm/pte-hash64-64k.h line 88
Quoted 10 lines
arch/powerpc/include/asm/pte-hash64-64k.h +5
-2+} +#define remap_4k_pfn (vma, addr, pfn, prot) \ - remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ - __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)) + ((pfn >= (1UL << (64 - PTE_RPN_SHIFT))) ? bad_4k_pfn() : \ + remap_pfn_range((vma), (addr), (pfn), PAGE_SIZE, \ + __pgprot(pgprot_val((prot)) | _PAGE_4K_PFN)))#endif /* __ASSEMBLY__ */
WARN_ON()returns the value it is passed, so no helper is needed:#define
remap_4k_pfn(vma, addr, pfn, prot)\arch/powerpc/include/asm/pte-hash64-64k.h +3
-2-remap_pfn_range ((vma), (addr), (pfn),PAGE_SIZE , \ -__pgprot (pgprot_val ((prot)) | _PAGE_4K_PFN)) +WARN_ON (((pfn >= (1UL << (64 -PTE_RPN_SHIFT )))) ? -EINVAL : \ +remap_pfn_range ((vma), (addr), (pfn),PAGE_SIZE , \ +__pgprot (pgprot_val ((prot)) | _PAGE_4K_PFN)))