mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-03 09:01:42 -05:00
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>
This commit is contained in:
parent
e4659ffbf5
commit
e881934927
1 changed files with 22 additions and 6 deletions
|
|
@ -85,7 +85,8 @@ __attribute__ ((visibility("default"))) int
|
||||||
fcntl(int fd, int cmd, ...)
|
fcntl(int fd, int cmd, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
void *arg;
|
int arg;
|
||||||
|
int has_arg;
|
||||||
|
|
||||||
wrapped_calls_fcntl++;
|
wrapped_calls_fcntl++;
|
||||||
|
|
||||||
|
|
@ -93,12 +94,27 @@ fcntl(int fd, int cmd, ...)
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
switch (cmd) {
|
||||||
|
case F_DUPFD_CLOEXEC:
|
||||||
|
case F_DUPFD:
|
||||||
|
case F_SETFD:
|
||||||
va_start(ap, cmd);
|
va_start(ap, cmd);
|
||||||
arg = va_arg(ap, void*);
|
arg = va_arg(ap, int);
|
||||||
|
has_arg = 1;
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
break;
|
||||||
|
case F_GETFD:
|
||||||
|
has_arg = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fprintf(stderr, "Unexpected fctnl cmd %d\n", cmd);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_arg) {
|
||||||
return real_fcntl(fd, cmd, arg);
|
return real_fcntl(fd, cmd, arg);
|
||||||
|
}
|
||||||
|
return real_fcntl(fd, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__ ((visibility("default"))) ssize_t
|
__attribute__ ((visibility("default"))) ssize_t
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue