]> Zhao Yanbai Git Server - minix.git/commitdiff
mmap: accept non-PROT_WRITE MAP_SHARED mappings
authorBen Gras <ben@minix3.org>
Mon, 17 Mar 2014 14:53:28 +0000 (15:53 +0100)
committerLionel Sambuc <lionel@minix3.org>
Mon, 28 Jul 2014 15:05:20 +0000 (17:05 +0200)
Currently we don't accept writable file mmap()s, as there is no
system in place to guarantee dirty buffers would make it back to
disk. But we can actually accept MAP_SHARED for PROT_READ mappings,
meaning the ranges aren't writable at all (and no private copy is
made as with MAP_PRIVATE), as it turns out a fairly large class of
usage.

. fail writable MAP_SHARED mappings at runtime
. reduces some minix-specific patches
. lets binutils gold build on minix without further patching

Change-Id: If2896c0a555328ac5b324afa706063fc6d86519e

common/lib/libprop/prop_object.c
lib/libc/cdb/cdbr.c
lib/libc/nls/catopen.c
libexec/ftpd/ftpd.c
libexec/ld.elf_so/map_object.c
libexec/ld.elf_so/paths.c
servers/vm/mmap.c
sys/sys/mman.h
test/test74.c
usr.bin/msgc/msg_sys.def
usr.bin/xinstall/xinstall.c

index 12e0403553d9201e591dbd757a07551d1fd757ea..7a79e1934224cd882f6fa03ddcacf745a26acda9 100644 (file)
@@ -942,13 +942,9 @@ _prop_object_internalize_map_file(const char *fname)
        if ((sb.st_size & pgmask) == 0)
                need_guard = true;
 
-#ifndef __minix
        mf->poimf_xml = mmap(NULL, need_guard ? mf->poimf_mapsize + pgsize
                                              : mf->poimf_mapsize,
                            PROT_READ, MAP_FILE|MAP_SHARED, fd, (off_t)0);
-#else
-       mf->poimf_xml = MAP_FAILED;
-#endif
        (void) close(fd);
        if (mf->poimf_xml == MAP_FAILED) {
                _PROP_FREE(mf, M_TEMP);
index 0fe919625495763301fec69429571b30eaae950f..2cc534db63ca2729b8c5638209dd32cee767670d 100644 (file)
@@ -57,10 +57,6 @@ __RCSID("$NetBSD: cdbr.c,v 1.4 2012/09/27 00:37:43 joerg Exp $");
 #include <string.h>
 #include <unistd.h>
 
-#if defined(__minix) && !defined(MAP_SHARED)
-#define MAP_SHARED MAP_PRIVATE /* LSC: We lose some memory, but it's OK as this is RO. */
-#endif /* defined(__minix) && !defined(MAP_SHARED) */
-
 #ifdef __weak_alias
 __weak_alias(cdbr_close,_cdbr_close)
 __weak_alias(cdbr_find,_cdbr_find)
index eb81b1aecc15e7e2e5059c8eb5046d1b1b86fea4..b32c2479fa55d3402f41c55c1a88e3ef35758d9f 100644 (file)
@@ -61,10 +61,6 @@ __RCSID("$NetBSD: catopen.c,v 1.32 2013/08/19 08:03:34 joerg Exp $");
 #define NLS_DEFAULT_PATH "/usr/share/nls/%L/%N.cat:/usr/share/nls/%N/%L"
 #define NLS_DEFAULT_LANG "C"
 
-#if defined(__minix) && !defined(MAP_SHARED)
-#define MAP_SHARED MAP_PRIVATE /* LSC: We lose some memory, but it's OK as this is RO. */
-#endif /* defined(__minix) && !defined(MAP_SHARED) */
-
 __weak_alias(catopen, _catopen)
 __weak_alias(catopen_l, _catopen_l)
 
index 179b7dd7950001b62a63c57ab57c50d38ae02e73..d230004bf56989fa645985ae7c12f16100cb153e 100644 (file)
@@ -2232,7 +2232,6 @@ send_data_with_mmap(int filefd, int netfd, const struct stat *st, int isdata)
                (void)gettimeofday(&then, NULL);
        } else
                bufrem = winsize;
-#if !defined(__minix)
        while (1) {
                mapsize = MIN(filesize - off, winsize);
                if (mapsize == 0)
@@ -2244,10 +2243,14 @@ send_data_with_mmap(int filefd, int netfd, const struct stat *st, int isdata)
                                goto try_read;
                        return (SS_FILE_ERROR);
                }
+#ifndef __minix
                (void) madvise(win, mapsize, MADV_SEQUENTIAL);
+#endif
                error = write_data(netfd, win, mapsize, &bufrem, &then,
                    isdata);
+#ifndef __minix
                (void) madvise(win, mapsize, MADV_DONTNEED);
+#endif
                munmap(win, mapsize);
                if (urgflag && handleoobcmd())
                        return (SS_ABORTED);
@@ -2257,7 +2260,6 @@ send_data_with_mmap(int filefd, int netfd, const struct stat *st, int isdata)
        }
        return (SS_SUCCESS);
 
-#endif /* !defined(__minix) */
  try_read:
        return (send_data_with_read(filefd, netfd, st, isdata));
 }
index 7beafee0698a0c94fa8e54cde53bc168f1f165cb..ae178ea8664652023bdaa44a7a4a2435e7171c25 100644 (file)
@@ -52,10 +52,6 @@ __RCSID("$NetBSD: map_object.c,v 1.52 2013/08/03 13:17:05 skrll Exp $");
 #if defined(__minix)
 #define MINIXVERBOSE 0
 
-#ifndef MAP_SHARED
-#define MAP_SHARED MAP_PRIVATE /* minix: MAP_SHARED should be MAP_PRIVATE */
-#endif
-
 #if MINIXVERBOSE
 #include <stdio.h>
 #endif
index d763cfc5dd328489444016e0882ed3073a1628d3..6f5c57ec9cd497bf08213815871456b39d29ac21 100644 (file)
@@ -61,15 +61,13 @@ __RCSID("$NetBSD: paths.c,v 1.41 2013/05/06 08:02:20 skrll Exp $");
 static Search_Path *_rtld_find_path(Search_Path *, const char *, size_t);
 static Search_Path **_rtld_append_path(Search_Path **, Search_Path **,
     const char *, const char *, const char *);
-#if !defined(__minix)
 static void _rtld_process_mapping(Library_Xform **, const char *,
     const char *);
-#endif /* !defined(__minix) */
 static char *exstrdup(const char *, const char *);
-#if !defined(__minix)
 static const char *getstr(const char **, const char *, const char *);
 static const char *getcstr(const char **, const char *, const char *);
 static const char *getword(const char **, const char *, const char *);
+#if !defined(__minix)
 static int matchstr(const char *, const char *, const char *);
 #endif /* !defined(__minix) */
 
@@ -90,7 +88,6 @@ exstrdup(const char *bp, const char *ep)
        return (cp);
 }
 
-#if !defined(__minix)
 /*
  * Like strsep(), but takes end of string and doesn't put any NUL.  To
  * detect empty string, compare `*p' and return value.
@@ -149,6 +146,7 @@ getword(const char **p, const char *ep, const char *delim)
        return (getstr(p, ep, delim));
 }
 
+#if !defined(__minix)
 /*
  * Match `bp' against NUL terminated string pointed by `p'.
  */
@@ -234,7 +232,6 @@ _rtld_add_paths(const char *execname, Search_Path **path_p, const char *pathstr)
        }
 }
 
-#if !defined(__minix)
 /*
  * Process library mappings of the form:
  *     <library_name>  <machdep_variable> <value,...:library_name,...> ...
@@ -340,17 +337,11 @@ cleanup:
                xfree(hwptr->name);
        xfree(hwptr);
 }
-#endif /* !defined(__minix) */
 
 void
 _rtld_process_hints(const char *execname, Search_Path **path_p,
     Library_Xform **lib_p, const char *fname)
 {
-
-#if defined(__minix)
-       /* Minix doesn't support MAP_SHARED. */
-       return;
-#else
        int fd;
        char *buf, small[128];
        const char *b, *ep, *ptr;
@@ -421,7 +412,6 @@ _rtld_process_hints(const char *execname, Search_Path **path_p,
 
        if (buf != small)
                (void)munmap(buf, sz);
-#endif /* defined(__minix) */
 }
 
 #if !defined(__minix)
index 62c0f432bfffeb8143fbdb532245afd425b47e09..405e5fc791cb94599fc79242a874849b2556fce5 100644 (file)
@@ -256,9 +256,10 @@ int do_mmap(message *m)
                /* File mapping might be disabled */
                if(!enable_filemap) return ENXIO;
 
-               /* files get private copies of pages on writes. */
-               if(!(m->VMM_FLAGS & MAP_PRIVATE)) {
-                       printf("VM: mmap file must MAP_PRIVATE\n");
+               /* For files, we only can't accept writable MAP_SHARED
+                * mappings.
+                */
+               if((m->VMM_FLAGS & MAP_SHARED) && (m->VMM_PROT & PROT_WRITE)) {
                        return ENXIO;
                }
 
index 19df99d08d00f48460f19a517be33cfa6f0afad6..91e3fa02fb40ba2a08a354292bba87c9247ddae5 100644 (file)
@@ -68,9 +68,7 @@ typedef       __off_t         off_t;          /* file offset */
  * Flags contain sharing type and options.
  * Sharing types; choose one.
  */
-#if !defined(__minix)
 #define        MAP_SHARED      0x0001  /* share changes */
-#endif /* !defined(__minix) */
 #define        MAP_PRIVATE     0x0002  /* changes are private */
 
 #ifdef _KERNEL
index 7d2d23fb2c0fa890c78444efa1f3dc9995815634..252a2dfbd555199219fbc438997b699c11e462d7 100644 (file)
@@ -403,6 +403,16 @@ void basic_regression(void)
        fd2 = open("../testsh2", O_RDONLY);
        if(fd1 < 0 || fd2 < 0) { e(2); }
 
+       /* just check that we can't mmap() a file writable */
+       if(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FILE, fd1, 0) != MAP_FAILED) {
+               e(1);
+       }
+
+       /* check that we can mmap() a file MAP_SHARED readonly */
+       if(mmap(NULL, PAGE_SIZE, PROT_READ, MAP_SHARED | MAP_FILE, fd1, 0) == MAP_FAILED) {
+               e(1);
+       }
+
        /* clear cache of files before mmap so pages won't be present already */
        if(fcntl(fd1, F_FLUSH_FS_CACHE) < 0) { e(1); }
        if(fcntl(fd2, F_FLUSH_FS_CACHE) < 0) { e(1); }
index bc19d260f7153f6d53c7d9727c6ccdd9a70145c5..1b1ba4e400801d318ddc298827d2e190b5dca132 100644 (file)
@@ -104,11 +104,7 @@ msg_file(const char *file)
        if (fd == -1)
                return -1;
        msgmapsz = lseek(fd, 0, SEEK_END);
-#ifdef __minix
-       msgmap = mmap(0, msgmapsz, PROT_READ, MAP_PRIVATE, fd, 0);
-#else /* ! __minix */
        msgmap = mmap(0, msgmapsz, PROT_READ, MAP_SHARED, fd, 0);
-#endif /* ! __minix */
        close(fd);
        if (msgmap == MAP_FAILED)
                return -1;
index 73f96897eea89b0eb22b181f136d41a6c4a7c40d..83acd42ac55690918aeec4d3ecb90512df95d80d 100644 (file)
@@ -819,9 +819,7 @@ copy(int from_fd, char *from_name, int to_fd, char *to_name, off_t size)
 {
        ssize_t nr, nw;
        int     serrno;
-#if !defined(__minix)
        u_char  *p;
-#endif /* !defined(__minix) */
        u_char  buf[MAXBSIZE];
        MD5_CTX         ctxMD5;
        RMD160_CTX      ctxRMD160;
@@ -868,15 +866,12 @@ copy(int from_fd, char *from_name, int to_fd, char *to_name, off_t size)
                 */
 
                if (size <= 8 * 1048576) {
-#if defined(__minix)
-                       goto mmap_failed;
-#else
                        if ((p = mmap(NULL, (size_t)size, PROT_READ,
                            MAP_FILE|MAP_SHARED, from_fd, (off_t)0))
                            == MAP_FAILED) {
                                goto mmap_failed;
                        }
-#if defined(MADV_SEQUENTIAL) && !defined(__APPLE__)
+#if defined(MADV_SEQUENTIAL) && !defined(__APPLE__) && !defined(__minix)
                        if (madvise(p, (size_t)size, MADV_SEQUENTIAL) == -1
                            && errno != EOPNOTSUPP)
                                warnx("madvise: %s", strerror(errno));
@@ -911,7 +906,6 @@ copy(int from_fd, char *from_name, int to_fd, char *to_name, off_t size)
                                break;
                        }
                        (void)munmap(p, size);
-#endif /* defined(__minix) */
                } else {
  mmap_failed:
                        while ((nr = read(from_fd, buf, sizeof(buf))) > 0) {