Skip to content

Instantly share code, notes, and snippets.

@dvdhrm
Created March 20, 2014 10:56
Show Gist options
  • Select an option

  • Save dvdhrm/9661331 to your computer and use it in GitHub Desktop.

Select an option

Save dvdhrm/9661331 to your computer and use it in GitHub Desktop.
#define _GNU_SOURCE
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char **argv)
{
char *args[64];
struct stat st;
sigset_t set;
char path[128];
void *map;
size_t size;
int sig, fd_exe, fd_map, fd;
pid_t pid;
ssize_t res;
/*
* If called with arguments, we just act as a sleeping process that
* waits for any signal to arrive.
*/
if (argc > 1) {
printf("dummy waiter init\n");
/* dummy waiter; SIGTERM terminates us anyway */
sigemptyset(&set);
sigaddset(&set, SIGTERM);
sigwait(&set, &sig);
printf("dummy waiter exit\n");
exit(0);
}
fd_exe = open("/proc/self/exe", O_RDONLY);
if (fd_exe < 0) {
printf("open(/proc/self/exe) failed: %m\n");
abort();
}
if (fstat(fd_exe, &st) < 0) {
printf("fstat(fd_exe) failed: %m\n");
abort();
}
/* page-align */
size = (st.st_size + 4095ULL) & ~4095ULL;
map = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (map == MAP_FAILED) {
printf("mmap(MAP_ANON) failed: %m\n");
abort();
}
res = read(fd_exe, map, st.st_size);
if (res != st.st_size) {
if (res < 0)
printf("read(fd_exe) failed: %m\n");
else
printf("read(fd_exe) was truncated to %zu\n",
(size_t)res);
abort();
}
sprintf(path, "/proc/self/map_files/%lx-%lx",
(unsigned long)map,
(unsigned long)map + size);
fd_map = open(path, O_RDONLY);
if (fd_map < 0) {
printf("open(%s) failed: %m\n", path);
abort();
}
pid = fork();
if (pid < 0) {
printf("fork() failed: %m\n");
abort();
} else if (!pid) {
args[0] = argv[0];
args[1] = "dummy";
args[2] = NULL;
execve(path, args, NULL);
printf("execve() failed: %m\n");
abort();
}
/* sleep 100ms to make sure the execve() really worked */
usleep(100 * 1000ULL);
sprintf(path, "/proc/self/fd/%d", fd_map);
fd = open(path, O_RDWR);
if (fd < 0) {
printf("open(%s) failed: %m\n", path);
abort();
}
munmap(map, size);
close(fd_exe);
close(fd);
close(fd_map);
printf("exiting\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment