I was wondering if there is a way to capture (in other words observe) vDSO calls like gettimeofday
in strace
.
Also, is there a way to execute a binary without loading linux-vdso.so.1
(a flag or env variable)?
And lastly, what if I write a program that delete the linux-vdso.so.1
address from the auxiliary vector and then execve
my program? Has anyone ever tried that?
You can capture calls to system calls which have been implemented via the vDSO by using ltrace
instead of strace
. This is because calls to system calls implemented via the vDSO work differently than "normal" system calls and the method strace
uses to trace system calls does not work with vDSO-implemented system calls. To learn more about how strace
works, check out this blog post I wrote about strace. And, to learn more about how ltrace
works, check out this other blog post I wrote about ltrace.
No, it is not possible to execute a binary without loading linux-vdso.so.1
. At least, not on my version of libc on Ubuntu precise. It is certainly possible that newer versions of libc/eglibc/etc have added this as a feature but it seems very unlikely. See the next answer for why.
If you delete the address from the auxillary vector, your binary will probably crash. libc has a piece of code which will first attempt to walk the vDSO ELF object, and if this fails, will fall back to a hardcoded vsyscall address. The only way it will avoid this is if you've compiled glibc with the vDSO disabled.
There is another workaround, though, if you really, really don't want to use the vDSO. You can try using glibc's syscall
function and pass in the syscall number for gettimeofday
. This will force glibc to call gettimeofday
via the kernel instead of the vDSO.
I've included a sample program below illustrating this. You can read more about how system calls work by reading my syscall blog post.
#include <sys/time.h>
#include <stdio.h>
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
int
main(int argc, char *argv[]) {
struct timeval tv;
syscall(SYS_gettimeofday, &tv);
return 0;
}
Compile with gcc -o test test.c
and strace with strace -ttTf ./test 2>&1 | grep gettimeofday
:
09:57:32.651876 gettimeofday({1467305852, 651888}, {420, 140735905220705}) = 0 <0.000006>