Index: sys/fs/devfs/devfs_vnops.c =================================================================== --- sys/fs/devfs/devfs_vnops.c +++ sys/fs/devfs/devfs_vnops.c @@ -1774,13 +1774,24 @@ return (EACCES); /* - * Character devices always share mappings, so - * require a writable fd for writable mappings. + * If we are sharing potential changes via MAP_SHARED and we + * are trying to get write permission although we opened it + * without asking for it, bail out. + * + * Note that most character devices always share mappings. + * The one exception is that D_MMAP_ANON devices + * (i.e. /dev/zero) permit private writable mappings. + * + * Rely on vm_mmap_cdev() to fail invalid MAP_PRIVATE requests + * as well as updating maxprot to permit writing for + * D_MMAP_ANON devices rather than doing that here. */ - if ((fp->f_flag & FWRITE) != 0) - maxprot |= VM_PROT_WRITE; - else if ((prot & VM_PROT_WRITE) != 0) - return (EACCES); + if ((flags & MAP_SHARED) != 0) { + if ((fp->f_flag & FWRITE) != 0) + maxprot |= VM_PROT_WRITE; + else if ((prot & VM_PROT_WRITE) != 0) + return (EACCES); + } maxprot &= cap_maxprot; fpop = td->td_fpop;