diff options
| author | Alex Richardson <Alexander.Richardson@cl.cam.ac.uk> | 2021-03-18 10:45:50 +0000 |
|---|---|---|
| committer | Simon Ser <contact@emersion.fr> | 2021-04-15 07:34:53 +0000 |
| commit | e88193492771f6d3c9f6d9d7b9b2b21b1a04e92d (patch) | |
| tree | 07fb2ca42ea1cb0bd23e733c8bf5d15e58e56eaf /tests | |
| parent | meson: Only require expat when building wayland-scanner (diff) | |
| download | wayland-e88193492771f6d3c9f6d9d7b9b2b21b1a04e92d.tar wayland-e88193492771f6d3c9f6d9d7b9b2b21b1a04e92d.tar.gz wayland-e88193492771f6d3c9f6d9d7b9b2b21b1a04e92d.tar.bz2 wayland-e88193492771f6d3c9f6d9d7b9b2b21b1a04e92d.tar.lz wayland-e88193492771f6d3c9f6d9d7b9b2b21b1a04e92d.tar.xz wayland-e88193492771f6d3c9f6d9d7b9b2b21b1a04e92d.tar.zst wayland-e88193492771f6d3c9f6d9d7b9b2b21b1a04e92d.zip | |
os-wrappers-test.c: Correctly forward arguments to fcntl
We can't just unconditionally read the optional arguments (and also read
it as a void* despite actually being an int).
While this happens to work on most architectures because the first few
variadic arguments are passed in registers, this is non-portable and
causes a crash on architectures that set bounds on variadic function
arguments (for example CHERI-enabled architectures). It could also cause
problems on big-endian architectures that pass variadic arguments on the
stack rather than in registers.
For CHERI-MIPS, reading sizeof(void*) causes a read of 16 bytes from the
bounded varargs capability. This always crashes since even calls with the
optional argument only have 4 bytes available.
Signed-off-by: Alex Richardson <Alexander.Richardson@cl.cam.ac.uk>
Reviewed-by: Simon Ser <contact@emersion.fr>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/os-wrappers-test.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/tests/os-wrappers-test.c b/tests/os-wrappers-test.c index 102622c..4d5de31 100644 --- a/tests/os-wrappers-test.c +++ b/tests/os-wrappers-test.c @@ -85,7 +85,8 @@ __attribute__ ((visibility("default"))) int fcntl(int fd, int cmd, ...) { va_list ap; - void *arg; + int arg; + int has_arg; wrapped_calls_fcntl++; @@ -93,12 +94,27 @@ fcntl(int fd, int cmd, ...) errno = EINVAL; return -1; } + switch (cmd) { + case F_DUPFD_CLOEXEC: + case F_DUPFD: + case F_SETFD: + va_start(ap, cmd); + arg = va_arg(ap, int); + has_arg = 1; + va_end(ap); + break; + case F_GETFD: + has_arg = 0; + break; + default: + fprintf(stderr, "Unexpected fctnl cmd %d\n", cmd); + abort(); + } - va_start(ap, cmd); - arg = va_arg(ap, void*); - va_end(ap); - - return real_fcntl(fd, cmd, arg); + if (has_arg) { + return real_fcntl(fd, cmd, arg); + } + return real_fcntl(fd, cmd); } __attribute__ ((visibility("default"))) ssize_t |
