diff --git a/src/common/processing.h b/src/common/processing.h index 51164b0e9..08d8c64bf 100644 --- a/src/common/processing.h +++ b/src/common/processing.h @@ -6,5 +6,6 @@ #include "util/FFstrbuf.h" const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]); +const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const argv[]); #endif diff --git a/src/common/processing_linux.c b/src/common/processing_linux.c index b9bf20c1b..082891131 100644 --- a/src/common/processing_linux.c +++ b/src/common/processing_linux.c @@ -47,3 +47,45 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) return NULL; } + +const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const argv[]) +{ + int pipes[2]; + + if(pipe(pipes) == -1) + return "pipe() failed"; + + pid_t childPid = fork(); + if(childPid == -1) + return "fork() failed"; + + //Child + if(childPid == 0) + { + dup2(pipes[1], STDERR_FILENO); + close(pipes[0]); + close(pipes[1]); + close(STDOUT_FILENO); + execvp(argv[0], argv); + exit(901); + } + + //Parent + close(pipes[1]); + + int FF_AUTO_CLOSE_FD childPipeFd = pipes[0]; + int status = -1; + if(waitpid(childPid, &status, 0) < 0) + return "waitpid(childPid, &status, 0) failed"; + + if (!WIFEXITED(status)) + return "WIFEXITED(status) == false"; + + if(WEXITSTATUS(status) == 901) + return "WEXITSTATUS(status) == 901 ( execvp failed )"; + + if(!ffAppendFDBuffer(childPipeFd, buffer)) + return "ffAppendFDBuffer(childPipeFd, buffer) failed"; + + return NULL; +} diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index 580a29146..a7de09e8e 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -11,18 +11,18 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) .bInheritHandle = TRUE, }; - HANDLE hChildStdoutRead, hChildStdoutWrite; - if (!CreatePipe(&hChildStdoutRead, &hChildStdoutWrite, &saAttr, 0)) + HANDLE hChildPipeRead, hChildPipeWrite; + if (!CreatePipe(&hChildPipeRead, &hChildPipeWrite, &saAttr, 0)) return "CreatePipe() failed"; - if (!SetHandleInformation(hChildStdoutRead, HANDLE_FLAG_INHERIT, 0)) - return "SetHandleInformation(hChildStdoutRead) failed"; + if (!SetHandleInformation(hChildPipeRead, HANDLE_FLAG_INHERIT, 0)) + return "SetHandleInformation(hChildPipeRead) failed"; PROCESS_INFORMATION piProcInfo = {0}; STARTUPINFOA siStartInfo = { .cb = sizeof(siStartInfo), .dwFlags = STARTF_USESTDHANDLES, - .hStdOutput = hChildStdoutWrite, + .hStdOutput = hChildPipeWrite, }; BOOL success; @@ -49,18 +49,80 @@ const char* ffProcessAppendStdOut(FFstrbuf* buffer, char* const argv[]) ); } - CloseHandle(hChildStdoutWrite); + CloseHandle(hChildPipeWrite); if(!success) { - CloseHandle(hChildStdoutRead); + CloseHandle(hChildPipeRead); return "CreateProcessA() failed"; } char str[1024]; DWORD nRead; - while(ReadFile(hChildStdoutRead, str, sizeof(str), &nRead, NULL) && nRead > 0) + while(ReadFile(hChildPipeRead, str, sizeof(str), &nRead, NULL) && nRead > 0) ffStrbufAppendNS(buffer, nRead, str); - CloseHandle(hChildStdoutRead); + CloseHandle(hChildPipeRead); + return NULL; +} + +const char* ffProcessAppendStdErr(FFstrbuf* buffer, char* const argv[]) +{ + SECURITY_ATTRIBUTES saAttr = { + .nLength = sizeof(SECURITY_ATTRIBUTES), + .lpSecurityDescriptor = NULL, + .bInheritHandle = TRUE, + }; + + HANDLE hChildPipeRead, hChildPipeWrite; + if (!CreatePipe(&hChildPipeRead, &hChildPipeWrite, &saAttr, 0)) + return "CreatePipe() failed"; + + if (!SetHandleInformation(hChildPipeRead, HANDLE_FLAG_INHERIT, 0)) + return "SetHandleInformation(hChildPipeRead) failed"; + + PROCESS_INFORMATION piProcInfo = {0}; + STARTUPINFOA siStartInfo = { + .cb = sizeof(siStartInfo), + .dwFlags = STARTF_USESTDHANDLES, + .hStdError = hChildPipeWrite, + }; + + BOOL success; + + { + FF_STRBUF_AUTO_DESTROY cmdline = ffStrbufCreateF("\"%s\"", argv[0]); + for(char* const* parg = &argv[1]; *parg; ++parg) + { + ffStrbufAppendC(&cmdline, ' '); + ffStrbufAppendS(&cmdline, *parg); + } + + success = CreateProcessA( + NULL, // application name + cmdline.chars, // command line + NULL, // process security attributes + NULL, // primary thread security attributes + TRUE, // handles are inherited + 0, // creation flags + NULL, // use parent's environment + NULL, // use parent's current directory + &siStartInfo, // STARTUPINFO pointer + &piProcInfo // receives PROCESS_INFORMATION + ); + } + + CloseHandle(hChildPipeWrite); + if(!success) + { + CloseHandle(hChildPipeRead); + return "CreateProcessA() failed"; + } + + char str[1024]; + DWORD nRead; + while(ReadFile(hChildPipeRead, str, sizeof(str), &nRead, NULL) && nRead > 0) + ffStrbufAppendNS(buffer, nRead, str); + + CloseHandle(hChildPipeRead); return NULL; } diff --git a/src/detection/lm/lm_linux.c b/src/detection/lm/lm_linux.c index c85fc5bf9..0ce9cd8b0 100644 --- a/src/detection/lm/lm_linux.c +++ b/src/detection/lm/lm_linux.c @@ -95,7 +95,7 @@ static const char* getXfwmVersion(FFstrbuf* version) static const char* getLightdmVersion(FFstrbuf* version) { - const char* error = ffProcessAppendStdOut(version, (char* const[]) { + const char* error = ffProcessAppendStdErr(version, (char* const[]) { "lightdm", "--version", NULL