aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorAlex Richardson <Alexander.Richardson@cl.cam.ac.uk>2021-03-18 10:45:50 +0000
committerSimon Ser <contact@emersion.fr>2021-04-15 07:34:53 +0000
commite88193492771f6d3c9f6d9d7b9b2b21b1a04e92d (patch)
tree07fb2ca42ea1cb0bd23e733c8bf5d15e58e56eaf /tests
parentmeson: Only require expat when building wayland-scanner (diff)
downloadwayland-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.c28
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