Skip to content

Instantly share code, notes, and snippets.

@machinaut
Created April 26, 2017 06:09
Show Gist options
  • Save machinaut/a08b581c921775263cf0e20ccc974cbd to your computer and use it in GitHub Desktop.
Save machinaut/a08b581c921775263cf0e20ccc974cbd to your computer and use it in GitHub Desktop.
drop vdso
#include <elf.h>
#include <linux/auxvec.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <time.h>
void drop_vdso(char *envp[]) {
Elf64_auxv_t *auxv, *ehdr, *last;
while(*envp++ != NULL); // skip the environment vars
for (auxv = (Elf64_auxv_t*)envp; auxv->a_type != AT_NULL; auxv++) {
if (auxv->a_type == AT_SYSINFO_EHDR) {
ehdr = auxv;
} else {
last = auxv;
}
}
*ehdr = *last; // replace the EHDR with the last non-ehdr entry
last->a_type = AT_NULL; // drop the last one off the bottom
}
__attribute__ ((constructor))
void init(int argc, char *argv[], char *envp[]) {
drop_vdso(envp);
}
@maxbla
Copy link

maxbla commented Oct 24, 2020

Do you know what libc and kernel this last worked on? It doesn't work for me now on Linux 5.9, glibc 2.32.

@machinaut
Copy link
Author

Oh lol are you running against mainline? I dont have any distro thats on 5.9 yet but I can try to just build and run one in qemu and see what happens.

@machinaut
Copy link
Author

Okay I haven't made an initramfs in many years, and at this point I don't even have a trusted toolchain to do OS bringup stuff.

If you share the error I'd be happy to look at it or try to diagnose.

Also if you want to video chat pair debug I'm down to spend a half hour on this :P. I'm in pacific coast US time if that works.

@machinaut
Copy link
Author

This worked at the time in docker running on the AWS linux image IIRC, but I didn't write down what the image was or the kernel version, to answer the direct question.

@maxbla
Copy link

maxbla commented Oct 25, 2020

Oh lol are you running against mainline?

Pretty much. It's arch, which AFAIK is a slightly patched mainline.

if you want to video chat pair debug

That sounds fun, but I think I figured it out (see below). I'm in PST too.

If you share the error

no error, it just doesn't appear to drop vdso

I figured it out. I didn't realize the importance of __attribute__((constructor)) and was just calling drop_vdso as the first line in main(), which simply doesn't drop vdso. Then, I was getting segfaults because I added __attribute__((constructor)), and ended up calling drop_vdso twice *facepalm*. That was all in a C project I whipped up to test your exact code, but I'm trying to remove vdso in Rust, which doesn't have any __attribute__((constructor))-like mechanisms to run code before main (or before glibc finds vdso). Luckily, it seems I can use a dlopen trick to overwrite the symbols from vdso. Unfortunately this trick fails when compiled with statically-linked musl because it doesn't support dlopen. I'd rather musl works, so I'm still in search of a better trick. Musl doesn't use vdso!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment