foxygit / doom Log in
commit e7b54ad4269d09dbeea1748832901de75dcf7551
Author:     Fabian Greffrath <fabian@greffrath.com>
AuthorDate: Fri Nov 10 15:33:40 2023 +0100
Commit:     GitHub <noreply@github.com>
CommitDate: Fri Nov 10 15:33:40 2023 +0100

    fix buffer overflow when loading response files (#1636)

    Fixes #1634

    The additional check in `M_CheckParmWithArgs()` is necessary,
    since `myargv[i] = NULL` may have already happened when `I_Error()`
    is called which in turn calls `M_ParmExists(-nogui)`.
---
 src/m_argv.c | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/m_argv.c b/src/m_argv.c
index fb953d5f..a6be5841 100644
--- a/src/m_argv.c
+++ b/src/m_argv.c
@@ -47,7 +47,10 @@ int M_CheckParmWithArgs(const char *check, int num_args)
 {
     int i;

-    for (i = 1; i < myargc - num_args; i++)
+    // Check if myargv[i] has been set to NULL in LoadResponseFile(),
+    // which may call I_Error(), which in turn calls M_ParmExists("-nogui").
+
+    for (i = 1; i < myargc - num_args && myargv[i]; i++)
     {
 	if (!strcasecmp(check, myargv[i]))
 	    return i;
@@ -129,6 +132,11 @@ static void LoadResponseFile(int argv_index, const char *filename)

     // Copy all the arguments in the list up to the response file

+    if (argv_index >= MAXARGVS)
+    {
+        I_Error("Too many arguments up to the response file!");
+    }
+
     for (i=0; i<argv_index; ++i)
     {
         newargv[i] = myargv[i];
@@ -182,6 +190,12 @@ static void LoadResponseFile(int argv_index, const char *filename)

             infile[k] = '\0';
             ++k;
+
+            if (newargc >= MAXARGVS)
+            {
+                I_Error("Too many arguments in the response file!");
+            }
+
             newargv[newargc++] = M_StringDuplicate(argstart);
         }
         else
@@ -199,14 +213,24 @@ static void LoadResponseFile(int argv_index, const char *filename)
             // Cut off the end of the argument at the first space

             infile[k] = '\0';
-
             ++k;
+
+            if (newargc >= MAXARGVS)
+            {
+                I_Error("Too many arguments in the response file!");
+            }
+
             newargv[newargc++] = M_StringDuplicate(argstart);
         }
     }

     // Add arguments following the response file argument

+    if (newargc + myargc - (argv_index + 1) >= MAXARGVS)
+    {
+        I_Error("Too many arguments following the response file!");
+    }
+
     for (i=argv_index + 1; i<myargc; ++i)
     {
         newargv[newargc] = myargv[i];