Skip to content

Commit 73b81e2

Browse files
Fix mmap on over-allocated files (#10526)
Fix for files with buffers larger than the file size where contents were written beyond memory allocated for the map. fixes #10527
1 parent 4bd0bc3 commit 73b81e2

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/library_memfs.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ mergeInto(LibraryManager.library, {
367367
ptr = contents.byteOffset;
368368
} else {
369369
// Try to avoid unnecessary slices.
370-
if (position > 0 || position + length < stream.node.usedBytes) {
370+
if (position > 0 || position + length < contents.length) {
371371
if (contents.subarray) {
372372
contents = contents.subarray(position, position + length);
373373
} else {

tests/fs/test_mmap.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,5 +176,49 @@ int main() {
176176
printf("/yolo/sharedoffset.txt content=%s %d\n", buffer + offset, offset);
177177
fclose(fd);
178178
}
179+
180+
/**
181+
* MMAP to an 'over-allocated' file
182+
*
183+
* When appending to a file, the buffer size is increased in chunks, and so the actual length
184+
* of the file could be less than the buffer size.
185+
*
186+
* When using mmap for an over-allocated file, we have to make sure that content from the buffer
187+
* is not written beyond the allocated memory area for the mmap operation.
188+
*/
189+
{
190+
int fd = open("/yolo/overallocatedfile.txt", O_RDWR | O_CREAT, (mode_t)0600);
191+
assert(fd != -1);
192+
193+
const size_t textsize = 33;
194+
195+
// multiple calls to write so that the file will be over-allocated
196+
for (int n = 0; n < textsize; n++) {
197+
assert(write(fd, "a", 1) != -1);
198+
}
199+
200+
EM_ASM_({
201+
const stream = FS.streams.find(stream => stream.path.indexOf('/yolo/overallocatedfile.txt')>=0);
202+
assert(stream.node.usedBytes === $0,
203+
'Used bytes on the over-allocated file (' + stream.node.usedBytes+ ') ' +
204+
'should be 33'
205+
);
206+
assert(stream.node.contents.length > stream.node.usedBytes,
207+
'Used bytes on the over-allocated file (' + stream.node.usedBytes+ ') ' +
208+
'should be less than the length of the content buffer (' + stream.node.contents.length + ')'
209+
);
210+
stream.node.contents[stream.node.usedBytes] = 98; // 'b', we don't want to see this in the mmap area
211+
}, textsize);
212+
213+
char *map = (char*)mmap(NULL, textsize, PROT_READ, 0, fd, 0);
214+
215+
assert(map[textsize-1] == 'a');
216+
217+
// Assert that content from the over-allocated file buffer is not written beyond the allocated memory for the map
218+
assert(map[textsize] != 'b');
219+
220+
close(fd);
221+
}
222+
179223
return 0;
180224
}

0 commit comments

Comments
 (0)