@@ -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;
}
@@ -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;
/*
@@ -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;
}
@@ -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__*/
@@ -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);
}
@@ -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;
}
@@ -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
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@yandex.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(-)