From d2576a9f5e61d63b07f8b686610b189feeef2efc Mon Sep 17 00:00:00 2001 From: Pete Batard Date: Thu, 25 Jun 2015 19:51:42 +0100 Subject: [PATCH] [misc] fix a buffer overflow issue in RunCommand * The size in CreatePipe is a suggested size, not an absolute one. * As a result, we could overflow our fixed size buffer. --- src/rufus.rc | 16 ++++++++-------- src/stdfn.c | 24 ++++++++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/rufus.rc b/src/rufus.rc index a598397f..051eaff9 100644 --- a/src/rufus.rc +++ b/src/rufus.rc @@ -32,7 +32,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL IDD_DIALOG DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Rufus 2.3.681" +CAPTION "Rufus 2.3.682" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -157,7 +157,7 @@ END IDD_DIALOG_XP DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Rufus 2.3.681" +CAPTION "Rufus 2.3.682" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -283,7 +283,7 @@ END IDD_DIALOG_RTL DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL -CAPTION "Rufus 2.3.681" +CAPTION "Rufus 2.3.682" FONT 8, "Segoe UI", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -415,7 +415,7 @@ END IDD_DIALOG_RTL_XP DIALOGEX 12, 12, 242, 376 STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_RTLREADING | WS_EX_APPWINDOW | WS_EX_LAYOUTRTL -CAPTION "Rufus 2.3.681" +CAPTION "Rufus 2.3.682" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Device",IDS_DEVICE_TXT,9,6,200,8 @@ -671,8 +671,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 2,3,681,0 - PRODUCTVERSION 2,3,681,0 + FILEVERSION 2,3,682,0 + PRODUCTVERSION 2,3,682,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -689,13 +689,13 @@ BEGIN BEGIN VALUE "CompanyName", "Akeo Consulting (http://akeo.ie)" VALUE "FileDescription", "Rufus" - VALUE "FileVersion", "2.3.681" + VALUE "FileVersion", "2.3.682" VALUE "InternalName", "Rufus" VALUE "LegalCopyright", "© 2011-2015 Pete Batard (GPL v3)" VALUE "LegalTrademarks", "http://www.gnu.org/copyleft/gpl.html" VALUE "OriginalFilename", "rufus.exe" VALUE "ProductName", "Rufus" - VALUE "ProductVersion", "2.3.681" + VALUE "ProductVersion", "2.3.682" END END BLOCK "VarFileInfo" diff --git a/src/stdfn.c b/src/stdfn.c index 884300d6..ef163bf2 100644 --- a/src/stdfn.c +++ b/src/stdfn.c @@ -535,16 +535,18 @@ DWORD GetResourceSize(HMODULE module, char* name, char* type, const char* desc) // Run a console command, with optional redirection of stdout and stderr to our log DWORD RunCommand(const char* cmd, const char* dir, BOOL log) { - DWORD ret, dwRead, dwAvail, dwMsg; + DWORD ret, dwRead, dwAvail, dwPipeSize = 4096; STARTUPINFOA si = {0}; PROCESS_INFORMATION pi = {0}; HANDLE hOutputRead = INVALID_HANDLE_VALUE, hOutputWrite = INVALID_HANDLE_VALUE; HANDLE hDupOutputWrite = INVALID_HANDLE_VALUE; - char output[1024]; + static char* output; si.cb = sizeof(si); if (log) { - if (!CreatePipe(&hOutputRead, &hOutputWrite, NULL, sizeof(output)-1)) { + // NB: The size of a pipe is a suggestion, NOT an absolute gaurantee + // This means that you may get a pipe of 4K even if you requested 1K + if (!CreatePipe(&hOutputRead, &hOutputWrite, NULL, dwPipeSize)) { ret = GetLastError(); uprintf("Could not set commandline pipe: %s", WindowsErrorString()); goto out; @@ -568,13 +570,15 @@ DWORD RunCommand(const char* cmd, const char* dir, BOOL log) if (log) { while (1) { // coverity[string_null] - if (PeekNamedPipe(hOutputRead, output, sizeof(output)-1, &dwRead, &dwAvail, &dwMsg)) { - // Don't care about possible multiple reads being needed - if ((dwAvail != 0) && (ReadFile(hOutputRead, output, dwAvail, &dwRead, NULL)) && (dwRead != 0)) { - // This seems to be needed. Won't overflow since we set our max sizes to sizeof(output)-1 - output[dwAvail] = 0; - // coverity[tainted_string] - uprintf(output); + if (PeekNamedPipe(hOutputRead, NULL, dwPipeSize, NULL, &dwAvail, NULL)) { + if (dwAvail != 0) { + output = malloc(dwAvail + 1); + if ((output != NULL) && (ReadFile(hOutputRead, output, dwAvail, &dwRead, NULL)) && (dwRead != 0)) { + output[dwAvail] = 0; + // coverity[tainted_string] + uprintf(output); + } + free(output); } } if (WaitForSingleObject(pi.hProcess, 0) == WAIT_OBJECT_0)