|
Message-Id: <1566563895-2081-1-git-send-email-levonshe@yandex.com> Date: Fri, 23 Aug 2019 08:38:15 -0400 From: Lev Olshvang <levonshe@...dex.com> To: kernel-hardening@...ts.openwall.com Subject: [RFC] security hardening: block write to read_only pages of a target process. Target process is not a current process. It is a foreign process in the terminogy of page fault handler. Typically debuggers, such as gdb, write to read-only code [text] sections of target process. This patch introduce kernel hardening configuration option. When enabled, it will stop attacks modifying code or jump tables. Onky Code of arch_vma_access_permitted() function was extended to check foreign vma vm_flags. New logic denies to accept page fault caused by page protection violation. Separatly applied for x86,powerpc and unicore32 arch_vma_access_permitted() function is not referenced in unicore32 and um architectures and seems to be obsolete,IMHO. Tested on x86_64 and ARM(QEMU) with dd command which writes to /proc/PID/mem in r--p or r--xp of vma area addresses range dd reports IO failure when tries to write to adress taken from from /proc/PID/maps (PLT or code section) Signed-off-by: Lev Olshvang <levonshe@...dex.com> --- arch/powerpc/include/asm/mmu_context.h | 7 +++++++ arch/powerpc/mm/book3s64/pkeys.c | 6 ++++++ arch/um/include/asm/mmu_context.h | 6 ++++++ arch/unicore32/include/asm/mmu_context.h | 8 +++++++- arch/x86/include/asm/mmu_context.h | 10 +++++++++- include/asm-generic/mm_hooks.h | 6 ++++++ security/Kconfig | 11 +++++++++++ 7 files changed, 52 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/include/asm/mmu_context.h b/arch/powerpc/include/asm/mmu_context.h index 58efca9..db37c61 100644 --- a/arch/powerpc/include/asm/mmu_context.h +++ b/arch/powerpc/include/asm/mmu_context.h @@ -251,6 +251,13 @@ void arch_dup_pkeys(struct mm_struct *oldmm, struct mm_struct *mm); static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write, bool execute, bool foreign) { +#ifdef CONFIG_PROTECT_READONLY_USER_MEMORY + if (write && foreign && (!(vma->vm_flags & VM_WRITE))) { + /* Forbid write to PROT_READ pages of foreign process */ + return false; + } +#endif + /* by default, allow everything */ return true; } diff --git a/arch/powerpc/mm/book3s64/pkeys.c b/arch/powerpc/mm/book3s64/pkeys.c index ae7fca4..b70fdfd 100644 --- a/arch/powerpc/mm/book3s64/pkeys.c +++ b/arch/powerpc/mm/book3s64/pkeys.c @@ -406,6 +406,12 @@ static inline bool vma_is_foreign(struct vm_area_struct *vma) bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write, bool execute, bool foreign) { +#ifdef CONFIG_PROTECT_READONLY_USER_MEMORY + if (write && foreign && (!(vma->vm_flags & VM_WRITE))) { + /* Forbid write to PROT_READ pages of foreign process */ + return false; + } +#endif if (static_branch_likely(&pkey_disabled)) return true; /* diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index 00cefd3..2c56ce9 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h @@ -33,6 +33,12 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write, bool execute, bool foreign) { +#ifdef CONFIG_PROTECT_READONLY_USER_MEMORY + if (write && foreign && (!(vma->vm_flags & VM_WRITE))) { + /* Forbid write to PROT_READ pages of foreign process */ + return false; + } +#endif /* by default, allow everything */ return true; } diff --git a/arch/unicore32/include/asm/mmu_context.h b/arch/unicore32/include/asm/mmu_context.h index 247a07a..730997c 100644 --- a/arch/unicore32/include/asm/mmu_context.h +++ b/arch/unicore32/include/asm/mmu_context.h @@ -97,7 +97,13 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write, bool execute, bool foreign) { +#ifdef CONFIG_PROTECT_READONLY_USER_MEMORY + if (write && foreign && (!(vma->vm_flags & VM_WRITE))) { + /* Forbid write to PROT_READ pages of foreign process */ + return false; + } +#endif /* by default, allow everything */ return true; } -#endif +#endif /*__UNICORE_MMU_CONTEXT_H__*/ diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 9024236..77b2801 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h @@ -329,12 +329,20 @@ static inline bool vma_is_foreign(struct vm_area_struct *vma) static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write, bool execute, bool foreign) { - /* pkeys never affect instruction fetches */ + +#ifdef CONFIG_PROTECT_READONLY_USER_MEMORY + if (write && foreign && (!(vma->vm_flags & VM_WRITE))) { + /* Forbid write to PROT_READ pages of foreign process */ + return false; + } +#endif + /* Don't check PKRU since pkeys never affect instruction fetches */ if (execute) return true; /* allow access if the VMA is not one from this process */ if (foreign || vma_is_foreign(vma)) return true; + return __pkru_allows_pkey(vma_pkey(vma), write); } diff --git a/include/asm-generic/mm_hooks.h b/include/asm-generic/mm_hooks.h index 6736ed2..31dae5a 100644 --- a/include/asm-generic/mm_hooks.h +++ b/include/asm-generic/mm_hooks.h @@ -30,6 +30,12 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, bool write, bool execute, bool foreign) { +#ifdef CONFIG_PROTECT_READONLY_USER_MEMORY + if (write && foreign && (!(vma->vm_flags & VM_WRITE))) { + /* Forbid write to PROT_READ pages of foreign process */ + return false; + } +#endif /* by default, allow everything */ return true; } diff --git a/security/Kconfig b/security/Kconfig index 0d65594..03ff948 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -143,6 +143,17 @@ config LSM_MMAP_MIN_ADDR this low address space will need the permission specific to the systems running LSM. +config PROTECT_READONLY_USER_MEMORY + bool "protect read only process memory" + depends on !(CONFIG_CROSS_MEMORY_ATTACH) + help + Protects read only memory of process code and PLT table from possible attack + through /proc/PID/mem. + Forbid writes to READ ONLY user pages of foreign process + Mostly advised for embedded and production system. + Disables process_vm_writev() syscall used in MP computing. + + config HAVE_HARDENED_USERCOPY_ALLOCATOR bool help -- 2.7.4
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.