/* spawnvp by file system codepage */ int fsyscp_spawnvp (int mode, const char *command, const char* const *argv) { int ret; wchar_t *commandw, **argvw, **pw; int i; const char* const *p; assert(command && argv); for (i = 0, p = argv; *p; p++) i++; argvw = xcalloc (i + 3, sizeof (wchar_t *)); commandw = get_wstring_from_fsyscp(command, commandw=NULL); p = argv; pw = argvw; while (*p) { *pw = get_wstring_from_fsyscp(*p, *pw=NULL); p++; pw++; } *pw = NULL; ret = _wspawnvp (mode, (const wchar_t *)commandw, (const wchar_t* const*) argvw); if(commandw) free(commandw); if (argvw) { pw = argvw; while (*pw) { free (*pw); pw++; } free (argvw); } return ret; }
void CWE78_OS_Command_Injection__wchar_t_environment_w32_spawnvp_41_goodG2BSink(wchar_t * data) { { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } }
/* goodG2B uses the GoodSource with the BadSink */ void goodG2BSink(map<int, wchar_t *> dataMap) { wchar_t * data = dataMap[2]; { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } }
static void goodG2B2() { wchar_t * data; wchar_t dataBuffer[100] = L""; data = dataBuffer; CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_22_goodG2B2Global = 1; /* true */ data = CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_22_goodG2B2Source(data); { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } }
static void goodG2B1() { wchar_t * data; wchar_t dataBuffer[100] = L""; data = dataBuffer; goodG2B1Static = 0; /* false */ data = goodG2B1Source(data); { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } }
/* goodG2B2() - use goodsource and badsink by reversing the blocks in the if statement */ static void goodG2B2() { wchar_t * data; wchar_t dataBuffer[100] = L""; data = dataBuffer; if(STATIC_CONST_FIVE==5) { /* FIX: Append a fixed string to data (not user / external input) */ wcscat(data, L"*.*"); } { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } }
void CWE78_OS_Command_Injection__wchar_t_console_w32_spawnvp_16_bad() { wchar_t * data; wchar_t dataBuffer[100] = L""; data = dataBuffer; while(1) { { /* Read input from the console */ size_t dataLen = wcslen(data); /* if there is room in data, read into it from the console */ if (100-dataLen > 1) { /* POTENTIAL FLAW: Read data from the console */ if (fgetws(data+dataLen, (int)(100-dataLen), stdin) != NULL) { /* The next few lines remove the carriage return from the string that is * inserted by fgetws() */ dataLen = wcslen(data); if (dataLen > 0 && data[dataLen-1] == L'\n') { data[dataLen-1] = L'\0'; } } else { printLine("fgetws() failed"); /* Restore NUL terminator if fgetws fails */ data[dataLen] = L'\0'; } } } break; } { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } }
/* goodG2B() uses the GoodSource with the BadSink */ static void goodG2B() { wchar_t * data; CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_34_unionType myUnion; wchar_t dataBuffer[100] = L""; data = dataBuffer; /* FIX: Append a fixed string to data (not user / external input) */ wcscat(data, L"*.*"); myUnion.unionFirst = data; { wchar_t * data = myUnion.unionSecond; { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } } }
void bad() { wchar_t * data; wchar_t * &dataRef = data; wchar_t dataBuffer[100] = L""; data = dataBuffer; { /* Read input from a file */ size_t dataLen = wcslen(data); FILE * pFile; /* if there is room in data, attempt to read the input from a file */ if (100-dataLen > 1) { pFile = fopen(FILENAME, "r"); if (pFile != NULL) { /* POTENTIAL FLAW: Read data from a file */ if (fgetws(data+dataLen, (int)(100-dataLen), pFile) == NULL) { printLine("fgetws() failed"); /* Restore NUL terminator if fgetws fails */ data[dataLen] = L'\0'; } fclose(pFile); } } } { wchar_t * data = dataRef; { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } } }
/* goodG2B1() - use goodsource and badsink by changing the 5==5 to 5!=5 */ static void goodG2B1() { wchar_t * data; wchar_t dataBuffer[100] = L""; data = dataBuffer; if(5!=5) { /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */ printLine("Benign, fixed string"); } else { /* FIX: Append a fixed string to data (not user / external input) */ wcscat(data, L"*.*"); } { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } }
/* Runs command in a background and redirects its stdout and stderr streams to * file streams which are set. Returns (pid_t)0 or (pid_t)-1 on error. */ static pid_t background_and_capture_internal(char cmd[], int user_sh, FILE **out, FILE **err, int out_pipe[2], int err_pipe[2]) { wchar_t *args[4]; char cwd[PATH_MAX]; int code; wchar_t *final_wide_cmd; wchar_t *wide_sh = NULL; if(_dup2(out_pipe[1], _fileno(stdout)) != 0) return (pid_t)-1; if(_dup2(err_pipe[1], _fileno(stderr)) != 0) return (pid_t)-1; cwd[0] = '\0'; if(get_cwd(cwd, sizeof(cwd)) != NULL) { if(is_unc_path(cwd)) { (void)chdir(get_tmpdir()); } } final_wide_cmd = to_wide(cmd); wide_sh = to_wide(user_sh ? cfg.shell : "cmd"); if(!user_sh || curr_stats.shell_type == ST_CMD) { args[0] = wide_sh; args[1] = L"/C"; args[2] = final_wide_cmd; args[3] = NULL; } else { args[0] = wide_sh; args[1] = L"-c"; args[2] = final_wide_cmd; args[3] = NULL; } code = _wspawnvp(P_NOWAIT, args[0], (const wchar_t **)args); free(wide_sh); free(final_wide_cmd); if(is_unc_path(cwd)) { (void)chdir(cwd); } if(code == 0) { return (pid_t)-1; } if((*out = _fdopen(out_pipe[0], "r")) == NULL) return (pid_t)-1; if((*err = _fdopen(err_pipe[0], "r")) == NULL) { fclose(*out); return (pid_t)-1; } return 0; }
void CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_34_bad() { wchar_t * data; CWE78_OS_Command_Injection__wchar_t_connect_socket_w32_spawnvp_34_unionType myUnion; wchar_t dataBuffer[100] = L""; data = dataBuffer; { #ifdef _WIN32 WSADATA wsaData; int wsaDataInit = 0; #endif int recvResult; struct sockaddr_in service; wchar_t *replace; SOCKET connectSocket = INVALID_SOCKET; size_t dataLen = wcslen(data); do { #ifdef _WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { break; } wsaDataInit = 1; #endif /* POTENTIAL FLAW: Read data using a connect socket */ connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (connectSocket == INVALID_SOCKET) { break; } memset(&service, 0, sizeof(service)); service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr(IP_ADDRESS); service.sin_port = htons(TCP_PORT); if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) { break; } /* Abort on error or the connection was closed, make sure to recv one * less char than is in the recv_buf in order to append a terminator */ /* Abort on error or the connection was closed */ recvResult = recv(connectSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); if (recvResult == SOCKET_ERROR || recvResult == 0) { break; } /* Append null terminator */ data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; /* Eliminate CRLF */ replace = wcschr(data, L'\r'); if (replace) { *replace = L'\0'; } replace = wcschr(data, L'\n'); if (replace) { *replace = L'\0'; } } while (0); if (connectSocket != INVALID_SOCKET) { CLOSE_SOCKET(connectSocket); } #ifdef _WIN32 if (wsaDataInit) { WSACleanup(); } #endif } myUnion.unionFirst = data; { wchar_t * data = myUnion.unionSecond; { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } } }
int run( const std::string &what, const std::vector<std::string> &argv, const std::string &std_input) { #ifdef _WIN32 // we don't support stdin on Windows assert(std_input.empty()); // unicode version of the arguments std::vector<std::wstring> wargv; wargv.resize(argv.size()); for(std::size_t i=0; i<argv.size(); i++) wargv[i]=widen(argv[i]); const wchar_t **_argv=new const wchar_t * [argv.size()+1]; for(std::size_t i=0; i<wargv.size(); i++) _argv[i]=wargv[i].c_str(); _argv[argv.size()]=NULL; // warning: the arguments may still need escaping std::wstring wide_what=widen(what); int status=(int)_wspawnvp(_P_WAIT, wide_what.c_str(), _argv); delete[] _argv; return status; #else int stdin_fd=STDIN_FILENO; if(!std_input.empty()) { stdin_fd=open(std_input.c_str(), O_RDONLY); if(stdin_fd==-1) { perror("Failed to open stdin copy"); return 1; } } // temporarily suspend all signals sigset_t new_mask, old_mask; sigemptyset(&new_mask); sigprocmask(SIG_SETMASK, &new_mask, &old_mask); /* now create new process */ pid_t childpid = fork(); if(childpid>=0) /* fork succeeded */ { if(childpid==0) /* fork() returns 0 to the child process */ { // resume signals remove_signal_catcher(); sigprocmask(SIG_SETMASK, &old_mask, NULL); char **_argv=new char * [argv.size()+1]; for(std::size_t i=0; i<argv.size(); i++) _argv[i]=strdup(argv[i].c_str()); _argv[argv.size()]=NULL; if(stdin_fd!=STDIN_FILENO) dup2(stdin_fd, STDIN_FILENO); execvp(what.c_str(), _argv); /* usually no return */ return 1; } else /* fork() returns new pid to the parent process */ { // resume signals sigprocmask(SIG_SETMASK, &old_mask, NULL); int status; /* parent process: child's exit status */ while(waitpid(childpid, &status, 0)==-1) /* wait for child to exit, and store its status */ if(errno==EINTR) continue; // try again else { perror("Waiting for child process failed"); if(stdin_fd!=STDIN_FILENO) close(stdin_fd); return 1; } if(stdin_fd!=STDIN_FILENO) close(stdin_fd); return WEXITSTATUS(status); } } else /* fork returns -1 on failure */ { // resume signals sigprocmask(SIG_SETMASK, &old_mask, NULL); if(stdin_fd!=STDIN_FILENO) close(stdin_fd); return 1; } #endif }
void CWE78_OS_Command_Injection__wchar_t_listen_socket_w32_spawnvp_05_bad() { wchar_t * data; wchar_t dataBuffer[100] = L""; data = dataBuffer; if(staticTrue) { { #ifdef _WIN32 WSADATA wsaData; int wsaDataInit = 0; #endif int recvResult; struct sockaddr_in service; wchar_t *replace; SOCKET listenSocket = INVALID_SOCKET; SOCKET acceptSocket = INVALID_SOCKET; size_t dataLen = wcslen(data); do { #ifdef _WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { break; } wsaDataInit = 1; #endif /* POTENTIAL FLAW: Read data using a listen socket */ listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listenSocket == INVALID_SOCKET) { break; } memset(&service, 0, sizeof(service)); service.sin_family = AF_INET; service.sin_addr.s_addr = INADDR_ANY; service.sin_port = htons(TCP_PORT); if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) { break; } if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) { break; } acceptSocket = accept(listenSocket, NULL, NULL); if (acceptSocket == SOCKET_ERROR) { break; } /* Abort on error or the connection was closed */ recvResult = recv(acceptSocket, (char *)(data + dataLen), sizeof(wchar_t) * (100 - dataLen - 1), 0); if (recvResult == SOCKET_ERROR || recvResult == 0) { break; } /* Append null terminator */ data[dataLen + recvResult / sizeof(wchar_t)] = L'\0'; /* Eliminate CRLF */ replace = wcschr(data, L'\r'); if (replace) { *replace = L'\0'; } replace = wcschr(data, L'\n'); if (replace) { *replace = L'\0'; } } while (0); if (listenSocket != INVALID_SOCKET) { CLOSE_SOCKET(listenSocket); } if (acceptSocket != INVALID_SOCKET) { CLOSE_SOCKET(acceptSocket); } #ifdef _WIN32 if (wsaDataInit) { WSACleanup(); } #endif } } { wchar_t *args[] = {COMMAND_INT_PATH, COMMAND_ARG1, COMMAND_ARG2, COMMAND_ARG3, NULL}; /* wspawnvp - searches for the location of the command among * the directories specified by the PATH environment variable */ /* POTENTIAL FLAW: Execute command without validating input possibly leading to command injection */ _wspawnvp(_P_WAIT, COMMAND_INT, args); } }