Created
February 25, 2020 14:40
-
-
Save fenrig/d505d47aa0b4f28ce0ea134ddd7e1650 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <signal.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <fcntl.h> | |
#include <sys/wait.h> | |
#include <sys/prctl.h> | |
#include <unistd.h> | |
#include <sys/time.h> | |
#include <sys/resource.h> | |
#include <errno.h> | |
#include <stdbool.h> | |
#include <poll.h> | |
#include <sys/signalfd.h> | |
#include <string.h> | |
static int sig_fd = -1; | |
static sigset_t mask; | |
static int syssig_enable(const int sigid, const bool enable){ | |
if(enable) { | |
sigaddset(&mask, sigid); | |
} else { | |
sigdelset(&mask, sigid); | |
} | |
sig_fd = signalfd(sig_fd, &mask, SFD_CLOEXEC); | |
return 0; | |
} | |
static int syssig_read(void){ | |
ssize_t res = 0; | |
struct signalfd_siginfo si; | |
res = read(sig_fd, &si, sizeof(si)); | |
printf("res: %d | si.ssi_signo: %s\n", res, strsignal(si.ssi_signo)); | |
return 0; | |
} | |
static void close_fds(void) { | |
struct rlimit limit; | |
int max_files = 1024; | |
int ret = getrlimit(RLIMIT_NOFILE, &limit); | |
if(ret == 0) { | |
max_files = limit.rlim_cur; | |
} | |
for(int i = 3; i < max_files; i++) { | |
close(i); | |
} | |
} | |
static void exec_child(char **argv){ | |
int fd_null = -1; | |
sigset_t sig_set; | |
prctl(PR_SET_PDEATHSIG, SIGKILL); | |
fd_null = open("/dev/null", O_RDWR); | |
for(int i = 0; i < 3; i++) { | |
dup2(fd_null, i); | |
} | |
close_fds(); | |
pthread_sigmask(SIG_SETMASK, NULL, &sig_set); | |
pthread_sigmask(SIG_UNBLOCK, &sig_set, NULL); | |
execvp(argv[0], argv); | |
exit(EXIT_FAILURE); | |
} | |
static void catch_sigchld(int signo){ | |
int saved_errno = errno; | |
int status; | |
pid_t pid; | |
pid = waitpid((pid_t)(-1), &status, WNOHANG); | |
printf("pid: %d | errno: %d\n", pid, saved_errno); | |
errno = saved_errno; | |
} | |
static void catch_signal_empty(int signo){ | |
printf("signo: %d\n", signo); | |
} | |
static int subproces(char **argv){ | |
int err; | |
sigset_t ss, saved_ss; | |
if(argv == NULL){ | |
return -1; | |
} | |
// block all signals | |
sigfillset(&ss); | |
//sigemptyset(&ss); | |
//sigaddset(&ss, SIGCHLD); | |
sigprocmask(SIG_SETMASK, &ss, &saved_ss); | |
pid_t pid = fork(); | |
if( pid ){ | |
// restore signals | |
sigprocmask(SIG_SETMASK, &saved_ss, NULL); | |
printf("launched: pid = %d\n", pid); | |
return 0; | |
} | |
close(sig_fd); | |
exec_child(argv); | |
// unreachable code | |
return -1; | |
} | |
static int poc_poll(void){ | |
int err; | |
struct pollfd pollfd; | |
pollfd.fd = sig_fd; | |
pollfd.events = POLLIN; | |
err = poll(&pollfd, 1, -1); | |
printf("poll released: %d\n", err); | |
if(err){ | |
syssig_read(); | |
catch_sigchld(0); | |
} | |
return err; | |
} | |
int main(void){ | |
int err; | |
char *cmd_sleep_2[] = { "sleep", "2", NULL}; | |
char *runc_help[] = {"runc", "--help", NULL}; | |
if (signal(SIGCHLD, catch_signal_empty) == SIG_ERR) { | |
printf("An error occurred while setting a signal handler.\n", stderr); | |
return EXIT_FAILURE; | |
} | |
sigemptyset(&mask); | |
sig_fd = signalfd(sig_fd, &mask, SFD_CLOEXEC); | |
syssig_enable(SIGCHLD, true); | |
/* | |
if (signal(SIGCHLD, catch_sigchld) == SIG_ERR) { | |
printf("An error occurred while setting a signal handler.\n", stderr); | |
return EXIT_FAILURE; | |
} | |
*/ | |
err = subproces(cmd_sleep_2); | |
printf("sleep 2: err = %d\n", err); | |
err = subproces(runc_help); | |
printf("runc help: err = %d\n", err); | |
while(true){ | |
poc_poll(); | |
} | |
/* | |
while(1) | |
sleep(60); | |
*/ | |
return 1; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
poc_main: main.c | |
gcc -o poc_main main.c -lpthread |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment