lkml.org 
[lkml]   [2017]   [Nov]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 013/138] arm64: Implement arch-specific pte_access_permitted()
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Catalin Marinas <catalin.marinas@arm.com>

    commit 6218f96c58dbf44a06aeaf767aab1f54fc397838 upstream.

    The generic pte_access_permitted() implementation only checks for
    pte_present() (together with the write permission where applicable).
    However, for both kernel ptes and PROT_NONE mappings pte_present() also
    returns true on arm64 even though such mappings are not user accessible.
    Additionally, arm64 now supports execute-only user permission
    (PROT_EXEC) which is implemented by clearing the PTE_USER bit.

    With this patch the arm64 implementation of pte_access_permitted()
    checks for the PTE_VALID and PTE_USER bits together with writable access
    if applicable.

    Reported-by: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
    Signed-off-by: Will Deacon <will.deacon@arm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    arch/arm64/include/asm/pgtable.h | 14 ++++++++++++++
    1 file changed, 14 insertions(+)

    --- a/arch/arm64/include/asm/pgtable.h
    +++ b/arch/arm64/include/asm/pgtable.h
    @@ -91,6 +91,8 @@ extern unsigned long empty_zero_page[PAG
    ((pte_val(pte) & (PTE_VALID | PTE_USER | PTE_UXN)) == (PTE_VALID | PTE_UXN))
    #define pte_valid_young(pte) \
    ((pte_val(pte) & (PTE_VALID | PTE_AF)) == (PTE_VALID | PTE_AF))
    +#define pte_valid_user(pte) \
    + ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))

    /*
    * Could the pte be present in the TLB? We must check mm_tlb_flush_pending
    @@ -100,6 +102,18 @@ extern unsigned long empty_zero_page[PAG
    #define pte_accessible(mm, pte) \
    (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid_young(pte))

    +/*
    + * p??_access_permitted() is true for valid user mappings (subject to the
    + * write permission check) other than user execute-only which do not have the
    + * PTE_USER bit set. PROT_NONE mappings do not have the PTE_VALID bit set.
    + */
    +#define pte_access_permitted(pte, write) \
    + (pte_valid_user(pte) && (!(write) || pte_write(pte)))
    +#define pmd_access_permitted(pmd, write) \
    + (pte_access_permitted(pmd_pte(pmd), (write)))
    +#define pud_access_permitted(pud, write) \
    + (pte_access_permitted(pud_pte(pud), (write)))
    +
    static inline pte_t clear_pte_bit(pte_t pte, pgprot_t prot)
    {
    pte_val(pte) &= ~pgprot_val(prot);

    \
     
     \ /
      Last update: 2017-11-28 13:07    [W:4.100 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site