Skip to content

WSL: ftruncate does not truncate mmap'd files #902

@freeone3000

Description

@freeone3000

Please use the following bug reporting template to help produce actionable and reproducible issues:

  • A brief description
    ftruncate does not truncate mmap'd files while they are mmap'd.
  • Expected results
    file gets truncated to desired size in bytes, even when mmap'd; SIGBUS occurs if memory outside new file bounds is accessed. (This is the behavior on Ubuntu.)
  • Actual results (with terminal output if applicable)
    file does not get truncated
  • Your Windows build number
    14393
  • Steps / commands required to reproduce the error
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define FAIL exit(errno);

int main() {
    /* prepare test data */
    int buf_size = 8102;
    char* buf = malloc(buf_size);
    if(NULL == buf) {
            FAIL
    }
    memset(buf, '?', buf_size);
    int fd = open("test_buffer", O_RDWR | O_CREAT);
    if(fd < 0) {
            FAIL
    }

    /* run test */
    write(fd, buf, buf_size);
    char* mm = mmap(NULL, buf_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(MAP_FAILED == mm) {
            FAIL
    }
    memset(mm, '!', buf_size);
    int tres = ftruncate(fd, 16);
    if(0 != tres) { /* okay, trying again later */
            write(STDOUT_FILENO, "NOFIRST\n", 9);
            errno = 0;
    }
    int mures = munmap(mm, buf_size);
    if(0 != mures) {
            FAIL
    }
    tres = ftruncate(fd, 16);
    if(0 != tres) {
            write(STDOUT_FILENO, "FAIL BOTH\n", 11);
            exit(1);
    }

    write(STDOUT_FILENO, "SUCCESS\n", 9);
    close(fd);
}
  • Strace of the failing command
  `execve("./min_test.bin", ["./min_test.bin"], [/* 23 vars */]) = 0
  brk(0)                                  = 0x12ab000
  access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
  mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c97540000
  access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
  open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
  fstat(3, {st_mode=S_IFREG|0644, st_size=64852, ...}) = 0
  mmap(NULL, 64852, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7c97530000
  close(3)                                = 0
  access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
  open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
  read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P \2\0\0\0\0\0"..., 832) = 832
  fstat(3, {st_mode=S_IFREG|0755, st_size=1840928, ...}) = 0
  mmap(NULL, 3949248, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f7c96e30000
  mprotect(0x7f7c96fea000, 2097152, PROT_NONE) = 0
  mmap(0x7f7c971ea000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1ba000) = 0x7f7c971ea000
  mmap(0x7f7c971f0000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f7c971f0000
  close(3)                                = 0
  mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c97520000
  mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f7c97510000
  arch_prctl(ARCH_SET_FS, 0x7f7c97510740) = 0
  mprotect(0x7f7c971ea000, 16384, PROT_READ) = 0
  mprotect(0x600000, 4096, PROT_READ)     = 0
  mprotect(0x7f7c97422000, 4096, PROT_READ) = 0
  munmap(0x7f7c97530000, 64852)           = 0
  brk(0)                                  = 0x12ab000
  brk(0x12cd000)                          = 0x12cd000
  open("test_buffer", O_RDWR|O_CREAT, 0112547600) = 3
  write(3, "????????????????????????????????"..., 8102) = 8102
  mmap(NULL, 8102, PROT_READ|PROT_WRITE, MAP_SHARED, 3, 0) = 0x7f7c9754b000
  ftruncate(3, 16)                        = -1 EINVAL (Invalid argument)
  write(1, "NOFIRST\n\0", 9)              = 9
  munmap(0x7f7c9754b000, 8102)            = 0
  ftruncate(3, 16)                        = 0
  write(1, "SUCCESS\n\0", 9)              = 9
  close(3)                                = 0
  exit_group(0)                           = ?
  +++ exited with 0 +++
  • Required packages and commands to install
    apt-get -y install build-essential

See our contributing instructions for assistance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions