diff --git a/src/libgit2/indexer.c b/src/libgit2/indexer.c index f1c7e437c61..6b726a694b8 100644 --- a/src/libgit2/indexer.c +++ b/src/libgit2/indexer.c @@ -97,7 +97,7 @@ static int parse_header(struct git_pack_header *hdr, struct git_pack_file *pack) int error; git_map map; - if ((error = p_mmap(&map, sizeof(*hdr), GIT_PROT_READ, GIT_MAP_SHARED, pack->mwf.fd, 0)) < 0) + if ((error = p_mmap(&map, sizeof(*hdr), GIT_PROT_READ, GIT_MAP_PRIVATE, pack->mwf.fd, 0)) < 0) return error; memcpy(hdr, map.data, sizeof(*hdr)); diff --git a/src/util/futils.c b/src/util/futils.c index 25c3a1be180..00877f4d933 100644 --- a/src/util/futils.c +++ b/src/util/futils.c @@ -359,7 +359,7 @@ int git_futils_mv_withpath(const char *from, const char *to, const mode_t dirmod int git_futils_mmap_ro(git_map *out, git_file fd, off64_t begin, size_t len) { - return p_mmap(out, len, GIT_PROT_READ, GIT_MAP_SHARED, fd, begin); + return p_mmap(out, len, GIT_PROT_READ, GIT_MAP_PRIVATE, fd, begin); } int git_futils_mmap_ro_file(git_map *out, const char *path) diff --git a/tests/util/futils.c b/tests/util/futils.c index 993b14d9b03..f15d066c24f 100644 --- a/tests/util/futils.c +++ b/tests/util/futils.c @@ -1,6 +1,10 @@ #include "clar_libgit2.h" #include "futils.h" +#if !defined(GIT_WIN32) && !defined(NO_MMAP) +#include +#endif + /* Fixture setup and teardown */ void test_futils__initialize(void) { @@ -37,6 +41,30 @@ void test_futils__writebuffer(void) git_str_dispose(&append); } +void test_futils__mmap_ro_uses_map_private(void) +{ +#if defined(GIT_WIN32) || defined(NO_MMAP) + cl_skip(); +#else + const char content[] = "mapped data"; + const char *path = "futils/mmap-file"; + git_map map = { 0 }; + git_file fd; + + cl_git_mkfile(path, content); + cl_assert((fd = p_open(path, O_RDWR)) >= 0); + cl_git_pass(git_futils_mmap_ro(&map, fd, 0, sizeof(content) - 1)); + + /* A private mapping must not propagate changes back to the file. */ + cl_must_pass(mprotect(map.data, map.len, PROT_READ | PROT_WRITE)); + ((char *)map.data)[0] = 'M'; + cl_assert_equal_file(content, sizeof(content) - 1, path); + + git_futils_mmap_free(&map); + p_close(fd); +#endif +} + void test_futils__write_hidden_file(void) { #ifndef GIT_WIN32