[PATCH 1/4] WCMD_run_program overflow fix

Eric Ho ericho921 at gmail.com
Sun Mar 7 14:46:45 CST 2010


This series of patches is a resubmission from the previous attempt as I was
asked to split the patches before submitting it again.  This patch fixes
some overflows in WCMD_run_program
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20100307/39736698/attachment.htm>
-------------- next part --------------
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 2c0e980..f22b9c1 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -24,3 +24,9 @@ Testing case sensitivity with and without /i option
 if seems to default to case sensitivity
 if /i seems to work
 if /I seems to work
+------------ Testing overflow --------------
+Overflow by long filename with no explicit path was caught.
+Overflow by long filename with explicit path was caught.
+Overflow by long path was caught.
+Overflow by stemofsearch concatenation was caught.
+Overflow by allFiles concatenation was caught.
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
old mode 100644
new mode 100755
index f97a1fd..d7bd556
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -1006,6 +1006,7 @@ void WCMD_run_program (WCHAR *command, int called) {
     GetFullPathNameW(param1, sizeof(pathtosearch)/sizeof(WCHAR), pathtosearch, NULL);
     lastSlash = strrchrW(pathtosearch, '\\');
     if (lastSlash && strchrW(lastSlash, '.') != NULL) extensionsupplied = TRUE;
+    if (strlenW(lastSlash+1)>=MAX_PATH) goto run_program_line_too_long;
     strcpyW(stemofsearch, lastSlash+1);
 
     /* Reduce pathtosearch to a path with trailing '\' to support c:\a.bat and
@@ -1037,11 +1038,13 @@ void WCMD_run_program (WCHAR *command, int called) {
     /* Work on the first directory on the search path */
     pos = strchrW(pathposn, ';');
     if (pos) {
+      if (pos-pathposn >= MAX_PATH) goto run_program_line_too_long;
       memcpy(thisDir, pathposn, (pos-pathposn) * sizeof(WCHAR));
       thisDir[(pos-pathposn)] = 0x00;
       pathposn = pos+1;
 
     } else {
+      if (strlenW(pathposn)>=MAX_PATH) goto run_program_line_too_long;
       strcpyW(thisDir, pathposn);
       pathposn = NULL;
     }
@@ -1051,7 +1054,6 @@ void WCMD_run_program (WCHAR *command, int called) {
     strcpyW(temp, thisDir);
     GetFullPathNameW(temp, MAX_PATH, thisDir, NULL);
 
-    /* 1. If extension supplied, see if that file exists */
     strcatW(thisDir, slashW);
     strcatW(thisDir, stemofsearch);
     pos = &thisDir[strlenW(thisDir)]; /* Pos = end of name */
@@ -1069,6 +1071,8 @@ void WCMD_run_program (WCHAR *command, int called) {
       WIN32_FIND_DATAW finddata;
       static const WCHAR allFiles[] = {'.','*','\0'};
 
+      if (strlenW(thisDir)+strlenW(allFiles) >= MAX_PATH) 
+        goto run_program_line_too_long;
       strcatW(thisDir,allFiles);
       h = FindFirstFileW(thisDir, &finddata);
       FindClose(h);
@@ -1081,10 +1085,14 @@ void WCMD_run_program (WCHAR *command, int called) {
           WCHAR *nextExt = strchrW(thisExt, ';');
 
           if (nextExt) {
+            if((pos-thisDir)+(nextExt-thisExt)>=MAX_PATH) 
+              goto run_program_line_too_long;
             memcpy(pos, thisExt, (nextExt-thisExt) * sizeof(WCHAR));
             pos[(nextExt-thisExt)] = 0x00;
             thisExt = nextExt+1;
           } else {
+	    if((pos-thisDir)+strlenW(thisExt)>=MAX_PATH) 
+              goto run_program_line_too_long;
             strcpyW(pos, thisExt);
             thisExt = NULL;
           }
@@ -1183,6 +1191,10 @@ void WCMD_run_program (WCHAR *command, int called) {
   errorlevel = 9009;
   return;
 
+ run_program_line_too_long:
+  WCMD_output_asis(WCMD_LoadMessage(WCMD_LINETOOLONG));
+  errorlevel = 9009;
+  return;
 }
 
 /*****************************************************************************


More information about the wine-patches mailing list