kern/150260: mmap fails with EPERM (not documented) if read-only shared memory is mmapped with MAP_PRIVATE & PROT_WRITE

Ion Gaztañaga igaztanaga at gmail.com
Fri Sep 3 22:00:14 UTC 2010


>Number:         150260
>Category:       kern
>Synopsis:       mmap fails with EPERM (not documented) if read-only shared memory is mmapped with MAP_PRIVATE & PROT_WRITE
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Sep 03 22:00:13 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Ion Gaztañaga
>Release:        8.0-RELEASE-p2
>Organization:
>Environment:
FreeBSD pcbsd-4080 8.0-RELEASE-p2 FreeBSD 8.0-RELEASE-p2 #4: Thu Jan  7 09:20:42 PST 2010     root at build8x32.pcbsd.org:/usr/obj/usr/pcbsd-build80/fbsd-source/8.0-src/sys/PCBSD  i386
>Description:
mmap allows copy on write file/shared memory mapping via MAP_PRIVATE and only requires a read-only file descriptor. This works with files but not with shared memory objects (mmap returns EPERM).
>How-To-Repeat:
Execute the attached c program
>Fix:


Patch attached with submission follows:

#include <sys/types.h>
#include <sys/mman.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main()
{
   shm_unlink("/myshm");
   int fd = shm_open("/myshm", O_CREAT | O_RDWR, 0644);
   if(fd >= 0){
      if(ftruncate(fd, 1000) < 0){
         printf("Error truncating");
	 close(fd);
      }
      else{
         close(fd);
         fd = shm_open("/myshm", O_RDONLY/*O_RDWR*/, 0644);
         if(fd >= 0){
            void *addr = mmap(0, 1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
            if (MAP_FAILED == addr){
               printf("mmap failed, errno: %s", strerror(errno));
            }
            else{
               printf("mmap OK");
               munmap(addr, 1000);
            }
            close(fd);
         }
         else{	    
            printf("Error opening shmem");
         }
      }
   }
   else{
      printf("Error creating shmem");
   }
   shm_unlink("/myshm");   
   return 0;
}





>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list