From: Joel Rosdahl Date: Wed, 28 Jan 2015 22:15:01 +0000 (+0100) Subject: Various fixes in WIN32-specific code X-Git-Tag: v3.2.2~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=50ede96f411448eb86f07ad61dac8f542bb60b0c;p=thirdparty%2Fccache.git Various fixes in WIN32-specific code * Avoid potential buffer overflow in add_exe_ext_if_no_to_fullpath. * Avoid using zero-padding strncpy function. * Removed superfluous newline characters from log messages. * For consistency, moved variable declarations to the top of the scope to please older compilers. * For consistency, used C89-style comments to please older compilers. * Fixed source code formatting. --- diff --git a/ccache.c b/ccache.c index c05c5c212..0b6643beb 100644 --- a/ccache.c +++ b/ccache.c @@ -2,7 +2,7 @@ * ccache -- a fast C/C++ compiler cache * * Copyright (C) 2002-2007 Andrew Tridgell - * Copyright (C) 2009-2014 Joel Rosdahl + * Copyright (C) 2009-2015 Joel Rosdahl * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -804,7 +804,7 @@ to_cache(struct args *args) tmp_stderr2 = format("%s.2", tmp_stderr); if (x_rename(tmp_stderr, tmp_stderr2)) { cc_log("Failed to rename %s to %s: %s", tmp_stderr, tmp_stderr2, - strerror(errno)); + strerror(errno)); failed(); } fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY); @@ -970,7 +970,6 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash) char *path_stdout, *path_stderr; int status, path_stderr_fd; struct file_hash *result; - int path_stdout_fd = -1; /* ~/hello.c -> tmp.hello.123.i limit the basename to 10 @@ -998,6 +997,7 @@ get_object_name_from_cpp(struct args *args, struct mdfour *hash) status = 0; } else { /* Run cpp on the input file to obtain the .i. */ + int path_stdout_fd; path_stdout = format("%s/%s.stdout", temp_dir(), input_base); path_stdout_fd = create_tmp_fd(&path_stdout); add_pending_tmp_file(path_stdout); @@ -1131,8 +1131,6 @@ compiler_is_gcc(struct args *args) return is; } - - /* * Update a hash sum with information common for the direct and preprocessor * modes. @@ -1142,6 +1140,11 @@ calculate_common_hash(struct args *args, struct mdfour *hash) { struct stat st; char *p; + const char *full_path = args->argv[0]; +#ifdef _WIN32 + const char* ext; + char full_path_win_ext[MAX_PATH + 1] = {0}; +#endif hash_string(hash, HASH_PREFIX); @@ -1152,14 +1155,13 @@ calculate_common_hash(struct args *args, struct mdfour *hash) hash_delimiter(hash, "ext"); hash_string(hash, conf->cpp_extension); - const char* full_path = args->argv[0]; #ifdef _WIN32 - const char* ext = strrchr(args->argv[0], '.'); - char full_path_win_ext[MAX_PATH + 1] = {0}; + ext = strrchr(args->argv[0], '.'); add_exe_ext_if_no_to_fullpath(full_path_win_ext, MAX_PATH, ext, - args->argv[0]); + args->argv[0]); full_path = full_path_win_ext; #endif + if (stat(full_path, &st) != 0) { cc_log("Couldn't stat compiler %s: %s", args->argv[0], strerror(errno)); stats_update(STATS_COMPILER); diff --git a/ccache.h b/ccache.h index 174e58221..9d35a553e 100644 --- a/ccache.h +++ b/ccache.h @@ -253,7 +253,7 @@ char *win32getshell(char *path); int win32execute(char *path, char **argv, int doreturn, int fd_stdout, int fd_stderr); void add_exe_ext_if_no_to_fullpath(char *full_path_win_ext, size_t max_size, - const char* ext, char* path); + const char *ext, const char *path); # ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0501 # endif diff --git a/execute.c b/execute.c index f4430497e..94d605dc6 100644 --- a/execute.c +++ b/execute.c @@ -118,14 +118,14 @@ win32getshell(char *path) } void add_exe_ext_if_no_to_fullpath(char *full_path_win_ext, size_t max_size, - const char* ext, char* path) { - strncat(full_path_win_ext, path, max_size); - if (!ext - || (!str_eq(".exe", ext) - && !str_eq(".bat", ext) - && !str_eq(".EXE", ext) - && !str_eq(".BAT", ext))) { - strncat(full_path_win_ext, ".exe", max_size); + const char *ext, const char *path) { + if (!ext || (!str_eq(".exe", ext) + && !str_eq(".bat", ext) + && !str_eq(".EXE", ext) + && !str_eq(".BAT", ext))) { + snprintf(full_path_win_ext, max_size, "%s.exe", path); + } else { + snprintf(full_path_win_ext, max_size, "%s", path); } } @@ -151,34 +151,31 @@ win32execute(char *path, char **argv, int doreturn, if (fd_stdout != -1) { si.hStdOutput = (HANDLE)_get_osfhandle(fd_stdout); si.hStdError = (HANDLE)_get_osfhandle(fd_stderr); - si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.dwFlags = STARTF_USESTDHANDLES; if (si.hStdOutput == INVALID_HANDLE_VALUE - || si.hStdError == INVALID_HANDLE_VALUE) { + || si.hStdError == INVALID_HANDLE_VALUE) { return -1; } } else { /* redirect subprocess stdout, stderr into current process */ si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); si.hStdError = GetStdHandle(STD_ERROR_HANDLE); - si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); si.dwFlags = STARTF_USESTDHANDLES; if (si.hStdOutput == INVALID_HANDLE_VALUE - || si.hStdError == INVALID_HANDLE_VALUE) { + || si.hStdError == INVALID_HANDLE_VALUE) { return -1; } } args = win32argvtos(sh, argv); - const char* ext = strrchr(path, '.'); - char full_path_win_ext[MAX_PATH] = { 0 }; + const char *ext = strrchr(path, '.'); + char full_path_win_ext[MAX_PATH] = {0}; add_exe_ext_if_no_to_fullpath(full_path_win_ext, MAX_PATH, ext, path); ret = CreateProcess(full_path_win_ext, args, NULL, NULL, 1, 0, NULL, NULL, - &si, &pi); - if (fd_stdout != -1) - { + &si, &pi); + if (fd_stdout != -1) { close(fd_stdout); close(fd_stderr); } @@ -189,23 +186,23 @@ win32execute(char *path, char **argv, int doreturn, DWORD dw = GetLastError(); FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, - 0, NULL); + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, + 0, NULL); lpDisplayBuf = - (LPVOID) LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR) lpMsgBuf) - + lstrlen((LPCTSTR) __FILE__) + 200) - * sizeof(TCHAR)); + (LPVOID) LocalAlloc(LMEM_ZEROINIT, + (lstrlen((LPCTSTR) lpMsgBuf) + + lstrlen((LPCTSTR) __FILE__) + 200) + * sizeof(TCHAR)); _snprintf((LPTSTR) lpDisplayBuf, - LocalSize(lpDisplayBuf) / sizeof(TCHAR), - TEXT("%s failed with error %d: %s"), __FILE__, dw, lpMsgBuf); + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s failed with error %d: %s"), __FILE__, dw, lpMsgBuf); - cc_log("can't execute %s\nOS returned error: %s\n", - full_path_win_ext, (char*)lpDisplayBuf); + cc_log("can't execute %s; OS returned error: %s", + full_path_win_ext, (char*)lpDisplayBuf); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); diff --git a/util.c b/util.c index e360afd77..4b8dd155d 100644 --- a/util.c +++ b/util.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2002 Andrew Tridgell - * Copyright (C) 2009-2014 Joel Rosdahl + * Copyright (C) 2009-2015 Joel Rosdahl * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -496,74 +496,72 @@ get_hostname(void) { static char hostname[260] = ""; - if (!hostname[0]) { - strcpy(hostname, "unknown"); + if (hostname[0]) { + return hostname; + } + + strcpy(hostname, "unknown"); #if HAVE_GETHOSTNAME - gethostname(hostname, sizeof(hostname)-1); + gethostname(hostname, sizeof(hostname) - 1); #elif defined(_WIN32) + const char *computer_name = getenv("COMPUTERNAME"); + if (computer_name) { + snprintf(hostname, sizeof(hostname), "%s", computer_name); + return hostname; + } - const char* computer_name = getenv("COMPUTERNAME"); - if (computer_name) - { - strncpy(hostname, computer_name, sizeof(hostname) -1); - return hostname; - } - - WORD wVersionRequested; - WSADATA wsaData; - int err; + WORD wVersionRequested; + WSADATA wsaData; + int err; - wVersionRequested = MAKEWORD(2, 2); + wVersionRequested = MAKEWORD(2, 2); - err = WSAStartup(wVersionRequested, &wsaData); - if (err != 0) { - /* Tell the user that we could not find a usable */ - /* Winsock DLL. */ - cc_log("WSAStartup failed with error: %d", err); - return hostname; - } + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable Winsock DLL. */ + cc_log("WSAStartup failed with error: %d", err); + return hostname; + } - if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { - /* Tell the user that we could not find a usable */ - /* WinSock DLL. */ - cc_log("Could not find a usable version of Winsock.dll\n"); - WSACleanup(); - return hostname; - } - - int result = gethostname(hostname, sizeof(hostname)-1); - if (result != 0) { - int last_error = WSAGetLastError(); - LPVOID lpMsgBuf; - LPVOID lpDisplayBuf; - DWORD dw = last_error; - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, 0, NULL); - - lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) - + 200) * sizeof(TCHAR)); - _snprintf((LPTSTR) lpDisplayBuf, - LocalSize(lpDisplayBuf) / sizeof(TCHAR), - TEXT("%s failed with error %d: %s"), __FILE__, dw, - lpMsgBuf); - - cc_log("can't get hostname OS returned error: %s\n", - (char*) lpDisplayBuf); - - LocalFree(lpMsgBuf); - LocalFree(lpDisplayBuf); - } + if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { + /* Tell the user that we could not find a usable WinSock DLL. */ + cc_log("Could not find a usable version of Winsock.dll"); WSACleanup(); -#endif - hostname[sizeof(hostname)-1] = 0; + return hostname; + } + + int result = gethostname(hostname, sizeof(hostname) - 1); + if (result != 0) { + int last_error = WSAGetLastError(); + LPVOID lpMsgBuf; + LPVOID lpDisplayBuf; + DWORD dw = last_error; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &lpMsgBuf, 0, NULL); + + lpDisplayBuf = (LPVOID) LocalAlloc( + LMEM_ZEROINIT, + (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 200) + * sizeof(TCHAR)); + _snprintf((LPTSTR) lpDisplayBuf, + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s failed with error %d: %s"), __FILE__, dw, + lpMsgBuf); + + cc_log("can't get hostname OS returned error: %s", (char*)lpDisplayBuf); + + LocalFree(lpMsgBuf); + LocalFree(lpDisplayBuf); } + WSACleanup(); +#endif + hostname[sizeof(hostname) - 1] = 0; return hostname; } @@ -1046,14 +1044,12 @@ x_realpath(const char *path) path_handle = CreateFile( path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if(INVALID_HANDLE_VALUE != path_handle) - { + if (INVALID_HANDLE_VALUE != path_handle) { GetFinalPathNameByHandle(path_handle, ret, maxlen, FILE_NAME_NORMALIZED); CloseHandle(path_handle); - p = ret+4;// strip the \\?\ from the file name - } else - { - strncpy(ret, path, maxlen); + p = ret + 4; /* strip \\?\ from the file name */ + } else { + snprintf(ret, maxlen, "%s", path); p = ret; } #else @@ -1372,41 +1368,41 @@ update_mtime(const char *path) int x_rename(const char *oldpath, const char *newpath) { -#ifdef _WIN32 +#ifndef _WIN32 + return rename(oldpath, newpath); +#else /* Windows' rename() refuses to overwrite an existing file. */ unlink(newpath); /* not x_unlink, as x_unlink calls x_rename */ - /*If the function succeeds, the return value is nonzero.*/ + /* If the function succeeds, the return value is nonzero. */ if (MoveFileA(oldpath, newpath) == 0) { LPVOID lpMsgBuf; LPVOID lpDisplayBuf; DWORD dw = GetLastError(); FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, - 0, NULL); - - lpDisplayBuf = (LPVOID) LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 40) - * sizeof(TCHAR)); + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, + 0, NULL); + + lpDisplayBuf = (LPVOID) LocalAlloc( + LMEM_ZEROINIT, + (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) __FILE__) + 40) + * sizeof(TCHAR)); _snprintf((LPTSTR) lpDisplayBuf, - LocalSize(lpDisplayBuf) / sizeof(TCHAR), - TEXT("%s failed with error %d: %s"), __FILE__, dw, lpMsgBuf); + LocalSize(lpDisplayBuf) / sizeof(TCHAR), + TEXT("%s failed with error %d: %s"), __FILE__, dw, lpMsgBuf); - cc_log("can't rename file %s to %s OS returned error: %s\n", - oldpath, newpath, (char*) lpDisplayBuf); + cc_log("can't rename file %s to %s OS returned error: %s", + oldpath, newpath, (char*) lpDisplayBuf); LocalFree(lpMsgBuf); LocalFree(lpDisplayBuf); return -1; - } else - { + } else { return 0; } -#else - return rename(oldpath, newpath); #endif }