Skip to content

Commit

Permalink
fix(mmap): handle expanded files
Browse files Browse the repository at this point in the history
fix for not writing buffer contents from expanded files
beyond allocated memory

fixes #10527
  • Loading branch information
petersalomonsen committed Feb 21, 2020
1 parent b007756 commit 0e4bb32
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/library_memfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ mergeInto(LibraryManager.library, {
ptr = contents.byteOffset;
} else {
// Try to avoid unnecessary slices.
if (position > 0 || position + length < stream.node.usedBytes) {
if (position > 0 || position + length < contents.length) {
if (contents.subarray) {
contents = contents.subarray(position, position + length);
} else {
Expand Down
48 changes: 48 additions & 0 deletions tests/fs/test_mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,53 @@ int main() {
printf("/yolo/sharedoffset.txt content=%s %d\n", buffer + offset, offset);
fclose(fd);
}

/**
* MMAP to and expanded file
*
* When appending to a file, the buffer is expanded in chunks, and so the actual length
* of the file could be less than the buffer length.
*
* When using mmap for an expanded file, we have to make sure that content from the buffer
* is not written beyond the allocated memory area for the mmap operation.
*/
{
const char* path = "/yolo/expandedfile.txt";

int fd = open(path, O_RDWR | O_CREAT, (mode_t)0600);
assert(fd != -1);

size_t textsize = 33;

// multiple calls to write so that the file is expanded
for(int n=0;n<textsize;n++) {
assert(write(fd, "a", 1) != -1);
}

EM_ASM_({
const stream = FS.streams.find(stream => stream.path.indexOf('/yolo/expandedfile.txt')>=0);
assert(stream.node.usedBytes === $0,
'Used bytes on the expanded file (' + stream.node.usedBytes+ ') ' +
'should be 33'
);
assert(stream.node.contents.length > stream.node.usedBytes,
'Used bytes on the expanded file (' + stream.node.usedBytes+ ') ' +
'should be less than the length of the content buffer (' + stream.node.contents.length + ')'
);
stream.node.contents[stream.node.usedBytes] = 98; // 'b', we don't want to see this in the mmap area
}, textsize);

char *map;

map = (char*)mmap(NULL, textsize, PROT_READ, 0, fd, 0);

assert(map[textsize-1] == 'a');

// Assert that content from the expanded file buffer are not written beyond the maps allocated memory
assert(map[textsize] != 'b');

close(fd);
}

return 0;
}

0 comments on commit 0e4bb32

Please sign in to comment.