From 8dc669699e9b363d13289bdc6c057448ef056c0e Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Tue, 7 Jul 2020 17:05:47 -0700 Subject: [PATCH] Added mitigation for signal handling with vfork --- meshcore/agentcore.c | 9 ++++++++- microstack/ILibParsers.c | 17 ++++++++++++++--- microstack/ILibParsers.h | 7 +++++++ microstack/ILibProcessPipe.c | 14 +++++++++++++- 4 files changed, 42 insertions(+), 5 deletions(-) diff --git a/meshcore/agentcore.c b/meshcore/agentcore.c index c0f855e..79396d7 100644 --- a/meshcore/agentcore.c +++ b/meshcore/agentcore.c @@ -436,18 +436,24 @@ int MeshAgent_Helper_CommandLine(char **commands, char **result, int *resultLen) ignore_result(pipe(inputPipe)); ignore_result(pipe(outputPipe)); + sigset_t set; + ILibVForkPrepareSignals_Parent_Init(&set); pid = vfork(); + if (pid < 0) { // error; close(inputPipe[0]); close(inputPipe[1]); close(outputPipe[0]); close(outputPipe[1]); + ILibVForkPrepareSignals_Parent_Finished(&set); return(-1); } if (pid == 0) { // child + ILibVForkPrepareSignals_Child(); + close(inputPipe[1]); // Close Write End of StdIn close(outputPipe[0]); // Close Read End of StdOut dup2(inputPipe[0], STDIN_FILENO); @@ -457,12 +463,13 @@ int MeshAgent_Helper_CommandLine(char **commands, char **result, int *resultLen) close(outputPipe[1]); execv("/bin/sh", (char*[]) {"sh", NULL}); - exit(1); + _exit(1); } // parent close(inputPipe[0]); // Close Read End of StdIn close(outputPipe[1]); // Close Write End of StdOut + ILibVForkPrepareSignals_Parent_Finished(&set); for (int i = 0; commands[i] != NULL; ++i) { diff --git a/microstack/ILibParsers.c b/microstack/ILibParsers.c index 117a67b..850e668 100644 --- a/microstack/ILibParsers.c +++ b/microstack/ILibParsers.c @@ -2612,22 +2612,27 @@ void ILib_POSIX_CrashHandler(int code) if (pipe(fd) == 0) { + sigset_t set; + ILibVForkPrepareSignals_Parent_Init(&set); + pid = vfork(); if (pid == 0) { + ILibVForkPrepareSignals_Child(); + dup2(fd[1], STDOUT_FILENO); close(fd[1]); ((char**)ILib_POSIX_CrashParamBuffer)[1] = ptr; execv("/usr/bin/addr2line", (char**)ILib_POSIX_CrashParamBuffer); if (write(STDOUT_FILENO, "??:0", 4)) {} - exit(0); + _exit(0); } + ILibVForkPrepareSignals_Parent_Finished(&set); if (pid > 0) { char tmp[8192]; int len; - len = read(fd[0], tmp, 8192); if (len > 0 && tmp[0] != '?') { @@ -2728,16 +2733,22 @@ void ILibChain_DebugOffset(char *buffer, int bufferLen, uint64_t addrOffset) if (pipe(fd) == 0) { + sigset_t set; + ILibVForkPrepareSignals_Parent_Init(&set); + pid = vfork(); if (pid == 0) { + ILibVForkPrepareSignals_Child(); + dup2(fd[1], STDOUT_FILENO); close(fd[1]); execv("/usr/bin/addr2line", (char**)ILib_POSIX_CrashParamBuffer); if (write(STDOUT_FILENO, "??:0", 4)) {} - exit(0); + _exit(0); } + ILibVForkPrepareSignals_Parent_Finished(&set); if (pid > 0) { char tmp[8192]; diff --git a/microstack/ILibParsers.h b/microstack/ILibParsers.h index 43408b7..ffa3903 100644 --- a/microstack/ILibParsers.h +++ b/microstack/ILibParsers.h @@ -972,6 +972,13 @@ int ILibIsRunningOnChainThread(void* chain); \brief Chaining Methods \{ */ +#ifdef _POSIX + #define _ILibVForkPrepareSignals_clear(sact) memset(sact, 0, sizeof(struct sigaction)); sigemptyset(&((sact)->sa_mask)); (sact)->sa_handler = SIG_DFL; + #define ILibVForkPrepareSignals_Parent_Init(sigset) sigfillset(sigset);sigprocmask(SIG_BLOCK,sigset,NULL); + #define ILibVForkPrepareSignals_Parent_Finished(sigset) sigfillset(sigset);sigprocmask(SIG_UNBLOCK,sigset,NULL); + #define ILibVForkPrepareSignals_Child() {struct sigaction act;for(int signum=1;signum<32;++signum){_ILibVForkPrepareSignals_clear(&act);ignore_result(sigaction(signum,&act, NULL));}} +#endif + typedef void(*ILibChain_SignalHandler)(void *chain, int signum, void *user); ILibExportMethod void *ILibCreateChain(); void *ILibCreateChainEx(int extraMemorySize); diff --git a/microstack/ILibProcessPipe.c b/microstack/ILibProcessPipe.c index 87cf359..15043ce 100644 --- a/microstack/ILibProcessPipe.c +++ b/microstack/ILibProcessPipe.c @@ -638,6 +638,9 @@ ILibProcessPipe_Process ILibProcessPipe_Manager_SpawnProcessEx4(ILibProcessPipe_ if (userToken != NULL) { CloseHandle(userToken); userToken = NULL; } #else int UID = (int)(uint64_t)(ILibPtrCAST)sid; + sigset_t sset; + sigset_t *set = NULL; + if (spawnType == ILibProcessPipe_SpawnTypes_TERM) { int pipe; @@ -713,6 +716,8 @@ ILibProcessPipe_Process ILibProcessPipe_Manager_SpawnProcessEx4(ILibProcessPipe_ #ifdef __APPLE__ if (needSetSid == 0) { + set = &sset; + ILibVForkPrepareSignals_Parent_Init(set); pid = vfork(); } else @@ -720,11 +725,14 @@ ILibProcessPipe_Process ILibProcessPipe_Manager_SpawnProcessEx4(ILibProcessPipe_ pid = fork(); } #else + set = &sset; + ILibVForkPrepareSignals_Parent_Init(set); pid = vfork(); #endif } if (pid < 0) { + if (set != NULL) { ILibVForkPrepareSignals_Parent_Finished(set); } if (spawnType != ILibProcessPipe_SpawnTypes_DETACHED) { ILibProcessPipe_FreePipe(retVal->stdErr); @@ -736,6 +744,10 @@ ILibProcessPipe_Process ILibProcessPipe_Manager_SpawnProcessEx4(ILibProcessPipe_ } if (pid == 0) { + if (set != NULL) + { + ILibVForkPrepareSignals_Child(); + } if (spawnType != ILibProcessPipe_SpawnTypes_DETACHED && spawnType != ILibProcessPipe_SpawnTypes_TERM) { close(retVal->stdErr->mPipe_ReadEnd); //close read end of stderr pipe @@ -785,7 +797,7 @@ ILibProcessPipe_Process ILibProcessPipe_Manager_SpawnProcessEx4(ILibProcessPipe_ execv(target, parameters); _exit(1); } - + if (set != NULL) { ILibVForkPrepareSignals_Parent_Finished(set); } if (spawnType != ILibProcessPipe_SpawnTypes_TERM && spawnType != ILibProcessPipe_SpawnTypes_DETACHED) { close(retVal->stdIn->mPipe_ReadEnd); retVal->stdIn->mPipe_ReadEnd = -1;