[PATCH 4/4] programs/cmd: don't overflow internal path buffers

Eric Pouech eric.pouech at gmail.com
Wed Jan 5 08:55:43 CST 2022


this can happen with symbolic links

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>

---
 programs/cmd/builtins.c  |   21 +++++++++++++++------
 programs/cmd/directory.c |    1 +
 2 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 91e4453a4e7..6966a4229b3 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -1256,12 +1256,14 @@ static BOOL WCMD_delete_one (const WCHAR *thisArg) {
     {
       WCHAR modifiedParm[MAX_PATH];
 
-      lstrcpyW(modifiedParm, argCopy);
-      lstrcatW(modifiedParm, L"\\*");
-      FindClose(hff);
-      found = TRUE;
-      WCMD_delete_one(modifiedParm);
-
+      if (wcslen(argCopy) + 2 + 1 <= ARRAY_SIZE(modifiedParm))
+      {
+        lstrcpyW(modifiedParm, argCopy);
+        lstrcatW(modifiedParm, L"\\*");
+        FindClose(hff);
+        found = TRUE;
+        WCMD_delete_one(modifiedParm);
+      }
     } else if (handleParm) {
 
       /* Build the filename to delete as <supplied directory>\<findfirst filename> */
@@ -1269,6 +1271,7 @@ static BOOL WCMD_delete_one (const WCHAR *thisArg) {
       do {
         p = wcsrchr (fpath, '\\');
         if (p != NULL) {
+          if ((p + 1 - fpath) + wcslen(fd.cFileName) + 1 > ARRAY_SIZE(fpath)) continue;
           *++p = '\0';
           lstrcatW (fpath, fd.cFileName);
         }
@@ -1324,6 +1327,7 @@ static BOOL WCMD_delete_one (const WCHAR *thisArg) {
       GetFullPathNameW(argCopy, ARRAY_SIZE(thisDir), thisDir, NULL);
       _wsplitpath(thisDir, drive, dir, fname, ext);
 
+      if (wcslen(drive) + wcslen(dir) + 1 + 1 > ARRAY_SIZE(thisDir)) return found;
       lstrcpyW(thisDir, drive);
       lstrcatW(thisDir, dir);
       cPos = lstrlenW(thisDir);
@@ -1350,6 +1354,7 @@ static BOOL WCMD_delete_one (const WCHAR *thisArg) {
             DIRECTORY_STACK *nextDir;
             WCHAR subParm[MAX_PATH];
 
+            if (wcslen(thisDir) + wcslen(fd.cFileName) + 1 + wcslen(fname) + wcslen(ext) + 1 > ARRAY_SIZE(subParm)) continue;
             /* Work out search parameter in sub dir */
             lstrcpyW (subParm, thisDir);
             lstrcatW (subParm, fd.cFileName);
@@ -1746,6 +1751,7 @@ static void WCMD_add_dirstowalk(DIRECTORY_STACK *dirsToWalk) {
 
   /* Build a generic search and add all directories on the list of directories
      still to walk                                                             */
+  if (wcslen(dirsToWalk->dirName) + 2 + 1 > ARRAY_SIZE(fullitem)) return;
   lstrcpyW(fullitem, dirsToWalk->dirName);
   lstrcatW(fullitem, L"\\*");
   hff = FindFirstFileW(fullitem, &fd);
@@ -2316,12 +2322,14 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
                       WINE_TRACE("Processing FOR filename %s\n", wine_dbgstr_w(fd.cFileName));
 
                       if (doRecurse) {
+                          if (wcslen(dirsToWalk->dirName) + 1 + wcslen(fd.cFileName) + 1 > ARRAY_SIZE(fullitem)) continue;
                           lstrcpyW(fullitem, dirsToWalk->dirName);
                           lstrcatW(fullitem, L"\\");
                           lstrcatW(fullitem, fd.cFileName);
                       } else {
                           if (prefixlen) lstrcpynW(fullitem, item, prefixlen + 1);
                           fullitem[prefixlen] = 0x00;
+                          if (wcslen(fullitem) + wcslen(fd.cFileName) + 1 > ARRAY_SIZE(fullitem)) continue;
                           lstrcatW(fullitem, fd.cFileName);
                       }
                       doExecuted = TRUE;
@@ -2964,6 +2972,7 @@ void WCMD_move (void)
     attribs = GetFileAttributesW(output);
     if (attribs != INVALID_FILE_ATTRIBUTES &&
        (attribs & FILE_ATTRIBUTE_DIRECTORY)) {
+      if (wcslen(output) + 1 + wcslen(fd.cFileName) + 1 > ARRAY_SIZE(dest)) continue;
       lstrcpyW(dest, output);
       lstrcatW(dest, L"\\");
       lstrcatW(dest, fd.cFileName);
diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c
index 24b18bfa81b..3eba2c3e4fc 100644
--- a/programs/cmd/directory.c
+++ b/programs/cmd/directory.c
@@ -480,6 +480,7 @@ static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int le
           while (dirsToCopy > 0) {
             dirsToCopy--;
 
+            if (wcslen(inputparms->dirName) + wcslen(finddata.cFileName) + 1 + 1 > ARRAY_SIZE(string)) continue;
             /* Work out search parameter in sub dir */
             lstrcpyW (string, inputparms->dirName);
             lstrcatW (string, finddata.cFileName);




More information about the wine-devel mailing list