Skip to content

Commit

Permalink
Handle case where a file is mapped both private and shared and is wri…
Browse files Browse the repository at this point in the history
…tten to
  • Loading branch information
rocallahan committed Apr 30, 2019
1 parent a729a4a commit 5ade76d
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Expand Up @@ -775,7 +775,6 @@ set(BASIC_TESTS
mmap_short_file
mmap_tmpfs
mmap_write_complex
mmap_write_private
mmap_zero_size_fd
modify_ldt
mount_ns_exec
Expand Down Expand Up @@ -1077,6 +1076,7 @@ set(TESTS_WITH_PROGRAM
mmap_replace_most_mappings
mmap_shared_prot
mmap_write
mmap_write_private
mprotect_growsdown
mprotect_syscallbuf_overflow
mutex_pi_stress
Expand Down
10 changes: 9 additions & 1 deletion src/MmappedFileMonitor.cc
Expand Up @@ -58,6 +58,15 @@ void MmappedFileMonitor::did_write(Task* t, const std::vector<Range>& ranges,
if (km.device() != device_ || km.inode() != inode_) {
continue;
}
// If the mapping is MAP_PRIVATE then this write is dangerous
// because it's unpredictable what will be seen in the mapping.
// However, it could be OK if the application doesn't read from
// this part of the mapping. Just optimistically assume this mapping
// is not affected.
if (!(km.flags() & MAP_SHARED)) {
LOG(warn) << "MAP_PRIVATE mapping affected by write";
continue;
}
}

// We're discovering a mapping we care about
Expand All @@ -67,7 +76,6 @@ void MmappedFileMonitor::did_write(Task* t, const std::vector<Range>& ranges,
}

// stat matches.
ASSERT(t, km.flags() & MAP_SHARED);
uint64_t mapping_offset = km.file_offset_bytes();
int64_t local_offset = realized_offset;
for (auto r : ranges) {
Expand Down
14 changes: 14 additions & 0 deletions src/test/mmap_write_private.c
Expand Up @@ -5,6 +5,9 @@
int main(void) {
int fd = open("output", O_RDWR | O_CREAT, 0777);
int fd2;
int fd3;
ssize_t ret;
char* p2;
char* p = (char*)mmap(NULL, 10, PROT_READ,
MAP_PRIVATE, fd, 0);
test_assert(p != MAP_FAILED);
Expand All @@ -15,6 +18,17 @@ int main(void) {
fd2 = open("output", O_RDWR, 0777);
test_assert(fd2 >= 0);

p2 = (char*)mmap(NULL, 10, PROT_READ, MAP_SHARED, fd, 0);
test_assert(p2 != MAP_FAILED);

/* Test what happens if the file is mapped private AND shared and
we write to it */
fd3 = open("output", O_RDWR, 0777);
test_assert(fd3 >= 0);

ret = write(fd3, "x", 1);
test_assert(ret == 1);

atomic_puts("EXIT-SUCCESS");
return 0;
}
2 changes: 2 additions & 0 deletions src/test/mmap_write_private.run
@@ -0,0 +1,2 @@
source `dirname $0`/util.sh
RR_COPY_ALL_FILES=1 compare_test EXIT-SUCCESS

0 comments on commit 5ade76d

Please sign in to comment.