Skip to content

Commit 8aeb7b1

Browse files
RISC-V: Make mmap() with PROT_WRITE imply PROT_READ
Commit 2139619 ("riscv: mmap with PROT_WRITE but no PROT_READ is invalid") made mmap() reject mappings with only PROT_WRITE set in an attempt to fix an observed inconsistency in behavior when attempting to read from a PROT_WRITE-only mapping. The root cause of this behavior was actually that while RISC-V's protection_map maps VM_WRITE to readable PTE permissions (since write-only PTEs are considered reserved by the privileged spec), the page fault handler considered loads from VM_WRITE-only VMAs illegal accesses. Fix the underlying cause by handling faults in VM_WRITE-only VMAs (patch 1) and then re-enable use of mmap(PROT_WRITE) (patch 2), making RISC-V's behavior consistent with all other architectures that don't support write-only PTEs. * remotes/palmer/riscv-wonly: riscv: Allow PROT_WRITE-only mmap() riscv: Make VM_WRITE imply VM_READ Link: https://lore.kernel.org/r/[email protected]/ Signed-off-by: Palmer Dabbelt <[email protected]>
2 parents c45fc91 + 9e2e604 commit 8aeb7b1

File tree

2 files changed

+2
-4
lines changed

2 files changed

+2
-4
lines changed

arch/riscv/kernel/sys_riscv.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ static long riscv_sys_mmap(unsigned long addr, unsigned long len,
1818
if (unlikely(offset & (~PAGE_MASK >> page_shift_offset)))
1919
return -EINVAL;
2020

21-
if (unlikely((prot & PROT_WRITE) && !(prot & PROT_READ)))
22-
return -EINVAL;
23-
2421
return ksys_mmap_pgoff(addr, len, prot, flags, fd,
2522
offset >> (PAGE_SHIFT - page_shift_offset));
2623
}

arch/riscv/mm/fault.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma)
184184
}
185185
break;
186186
case EXC_LOAD_PAGE_FAULT:
187-
if (!(vma->vm_flags & VM_READ)) {
187+
/* Write implies read */
188+
if (!(vma->vm_flags & (VM_READ | VM_WRITE))) {
188189
return true;
189190
}
190191
break;

0 commit comments

Comments
 (0)