Are changes made to mmap MAP_PRIVATE visible to the current process?
The mmap mapage tells us that whether changes in memory made to a MAP_PRIVATE
-memory-mapped file are visible to the process mapping the file is unspecified (they will not be written to the mapped file nor will they be visible to other processes mapping the same file).
However, we can verify if changes are actually visible on any given system / kernel version using this test program:
#include <string>
#include <iostream>
#include <fstream>
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <sys/stat.h>
using namespace std;
int main() {
string filename = "deleteme.txt";
// Create file
ofstream fout(filename.c_str());
fout << "ABCD";
fout.close();
// Create & open underlying file
int fd = open(filename.c_str(), O_RDONLY);
assert(fd != -1);
// mmap with MAP_PRIVATE and allow writes to the mmapped pages
char* mmappedData = (char*)mmap(NULL, 4, PROT_WRITE, MAP_PRIVATE | MAP_POPULATE, fd, 0);
assert(mmappedData != MAP_FAILED);
// Insert data into the MAP_PRIVATE area
mmappedData[0] = 0;
mmappedData[1] = 1;
mmappedData[2] = 2;
mmappedData[3] = 3;
// Overwrite once more
mmappedData[0] = 3;
mmappedData[1] = 2;
mmappedData[2] = 1;
mmappedData[3] = 0;
// Check data
if(mmappedData[0] == 3 &&
mmappedData[1] == 2 &&
mmappedData[2] == 1 &&
mmappedData[3] == 0) {
cout << "Congrats, MAP_PRIVATE changes are reflected in memory!" << endl;
} else {
cout << "Nope, MAP_PRIVATE changes are NOT reflected in memory!" << endl;
}
}
Download, compile and run using:
wget https://techoverflow.net/scripts/mmap-private-check.cpp && g++ -o mmap-private-check mmap-private-check.cpp && ./mmap-private-check
This will either print
Congrats, MAP_PRIVATE changes are reflected in memory!
(I only got this result for every Linux system I tested on, e.g. on Ubuntu 18.04) or
Nope, MAP_PRIVATE changes are NOT reflected in memory!
Note that this program only tests the visibility of the changes directly after writing the data. In principle, the Kernel is allowed to just discard your changes at any later point in time. So note that you are living on the edge here, doing changes to MAP_PRIVATE
memory is not inherently safe but in practice it often works very well.