Relax restrictions on private mappings of POSIX shm objects.
When creating a private mapping of a POSIX shared memory object, VM_PROT_WRITE should always be included in maxprot regardless of permissions on the underlying FD. Otherwise it is possible to open a shm object read-only, map it with MAP_PRIVATE and PROT_WRITE, and violate the invariant in vm_map_insert() that (prot & maxprot) == prot. Reported by: syzkaller Reviewed by: kevans, kib MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D24398
This commit is contained in:
parent
605c4cda2f
commit
c7841c6b8e
@ -1136,23 +1136,28 @@ shm_mmap(struct file *fp, vm_map_t map, vm_offset_t *addr, vm_size_t objsize,
|
||||
|
||||
/*
|
||||
* If FWRITE's set, we can allow VM_PROT_WRITE unless it's a shared
|
||||
* mapping with a write seal applied.
|
||||
* mapping with a write seal applied. Private mappings are always
|
||||
* writeable.
|
||||
*/
|
||||
if ((fp->f_flag & FWRITE) != 0 && ((flags & MAP_SHARED) == 0 ||
|
||||
(shmfd->shm_seals & F_SEAL_WRITE) == 0))
|
||||
if ((flags & MAP_SHARED) == 0) {
|
||||
cap_maxprot |= VM_PROT_WRITE;
|
||||
maxprot |= VM_PROT_WRITE;
|
||||
writecnt = false;
|
||||
} else {
|
||||
if ((fp->f_flag & FWRITE) != 0 &&
|
||||
(shmfd->shm_seals & F_SEAL_WRITE) == 0)
|
||||
maxprot |= VM_PROT_WRITE;
|
||||
writecnt = (prot & VM_PROT_WRITE) != 0;
|
||||
if (writecnt && (shmfd->shm_seals & F_SEAL_WRITE) != 0) {
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
writecnt = (flags & MAP_SHARED) != 0 && (prot & VM_PROT_WRITE) != 0;
|
||||
|
||||
if (writecnt && (shmfd->shm_seals & F_SEAL_WRITE) != 0) {
|
||||
error = EPERM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Don't permit shared writable mappings on read-only descriptors. */
|
||||
if (writecnt && (maxprot & VM_PROT_WRITE) == 0) {
|
||||
error = EACCES;
|
||||
goto out;
|
||||
/* Don't permit shared writable mappings on read-only descriptors. */
|
||||
if (writecnt && (maxprot & VM_PROT_WRITE) == 0) {
|
||||
error = EACCES;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
maxprot &= cap_maxprot;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user