Date: Thu, 6 Aug 2015 16:50:38 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r286371 - head/sys/fs/devfs Message-ID: <201508061650.t76GocwN024195@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Thu Aug 6 16:50:37 2015 New Revision: 286371 URL: https://svnweb.freebsd.org/changeset/base/286371 Log: The changes that introduced fo_mmap() treated all character device mappings as if MAP_SHARED was always present since in general MAP_PRIVATE is not permitted for character devices. However, there is one exception in that MAP_PRIVATE mappings are permitted for /dev/zero. Only require a writable file descriptor (FWRITE) for shared, writable mappings of character devices. vm_mmap_cdev() will reject any private mappings for other devices. Reviewed by: kib Reported by: sbruno (broke qemu cross-builds), peter Differential Revision: https://reviews.freebsd.org/D3316 Modified: head/sys/fs/devfs/devfs_vnops.c Modified: head/sys/fs/devfs/devfs_vnops.c ============================================================================== --- head/sys/fs/devfs/devfs_vnops.c Thu Aug 6 16:14:29 2015 (r286370) +++ head/sys/fs/devfs/devfs_vnops.c Thu Aug 6 16:50:37 2015 (r286371) @@ -1774,13 +1774,24 @@ devfs_mmap_f(struct file *fp, vm_map_t m 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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201508061650.t76GocwN024195>