CVE-2021-26567: Out-of-bounds Write (CWE-787)
value: Stack-based buffer overflow vulnerability in frontend/main.c in faad2 before 2.2.7.1 allow local attackers to execute arbitrary code via filename and pathname options.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.8
Published: 2021-02-26T22:15Z
Repository: https://github.com/knik0/faad2
Language: C
Files changed: frontend/main.c
Commit date: 2012-03-04 09:59:02 +0000
Commit message: Dynamically allocate file name buffers.

Diff: diff --git a/frontend/main.c b/frontend/main.c
index f5d993f..04e2058 100644
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -23,11 +23,11 @@
 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
 **
 ** Commercial non-GPL licensing of this software is possible.
 ** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: main.c,v 1.87 2012/03/02 15:28:44 knik Exp $
+** $Id: main.c,v 1.88 2012/03/04 09:59:02 knik Exp $
 **/
 
 #ifdef _WIN32
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
@@ -1107,13 +1107,13 @@ int main(int argc, char *argv[])
     int old_format = 0;
     int showHelp = 0;
     int mp4file = 0;
     int noGapless = 0;
     char *fnp;
-    char aacFileName[255];
-    char audioFileName[255];
-    char adtsFileName[255];
+    char *aacFileName = NULL;
+    char *audioFileName = NULL;
+    char *adtsFileName = NULL;
     unsigned char header[8];
     float length = 0;
     FILE *hMP4File;
 
 /* System dependant types */
@@ -1157,17 +1157,29 @@ int main(int argc, char *argv[])
         switch (c) {
         case 'o':
             if (optarg)
             {
                 outfile_set = 1;
+                audioFileName = (char *) malloc(sizeof(char) * (strlen(optarg) + 1));
+                if (audioFileName == NULL)
+                {
+                    faad_fprintf(stderr, "Error allocating memory for audioFileName.\n");
+                    return 1;
+                }
                 strcpy(audioFileName, optarg);
             }
             break;
         case 'a':
             if (optarg)
             {
                 adts_out = 1;
+                adtsFileName = (char *) malloc(sizeof(char) * (strlen(optarg) + 1));
+                if (adtsFileName == NULL)
+                {
+                    faad_fprintf(stderr, "Error allocating memory for adtsFileName.\n");
+                    return 1;
+                }
                 strcpy(adtsFileName, optarg);
             }
             break;
         case 's':
             if (optarg)
@@ -1284,10 +1296,16 @@ int main(int argc, char *argv[])
         format = 2;
     }
 #endif
 
     /* point to the specified file name */
+    aacFileName = (char *) malloc(sizeof(char) * (strlen(argv[optind]) + 1));
+    if (aacFileName == NULL)
+    {
+        faad_fprintf(stderr, "Error allocating memory for aacFileName.\n");
+        return 1;
+    }
     strcpy(aacFileName, argv[optind]);
 
 #ifdef _WIN32
     begin = GetTickCount();
 #else
@@ -1297,10 +1315,16 @@ int main(int argc, char *argv[])
     /* Only calculate the path and open the file for writing if
        we are not writing to stdout.
      */
     if(!writeToStdio && !outfile_set)
     {
+        audioFileName = (char *) malloc(sizeof(char) * (strlen(aacFileName) + strlen(file_ext[format]) + 1));
+        if (audioFileName == NULL)
+        {
+            faad_fprintf(stderr, "Error allocating memory for audioFileName.\n");
+            return 1;
+        }
         strcpy(audioFileName, aacFileName);
 
         fnp = (char *)strrchr(audioFileName,'.');
 
         if (fnp)
@@ -1357,10 +1381,15 @@ int main(int argc, char *argv[])
         result = decodeAACfile(aacFileName, audioFileName, adtsFileName, writeToStdio,
             def_srate, object_type, outputFormat, format, downMatrix, infoOnly, adts_out,
             old_format, &length);
     }
 
+    if (audioFileName != NULL)
+      free (audioFileName);
+    if (adtsFileName != NULL)
+      free (adtsFileName);
+
     if (!result && !infoOnly)
     {
 #ifdef _WIN32
         float dec_length = (float)(GetTickCount()-begin)/1000.0;
         SetConsoleTitle("FAAD");
@@ -1372,7 +1401,10 @@ int main(int argc, char *argv[])
 #endif
         faad_fprintf(stderr, "Decoding %s took: %5.2f sec. %5.2fx real-time.\n", aacFileName,
             dec_length, length/dec_length);
     }
 
+    if (aacFileName != NULL)
+      free (aacFileName);
+
     return 0;
 }

Vulnerable code: ** $Id: main.c,v 1.87 2012/03/02 15:28:44 knik Exp $
    char aacFileName[255];
    char audioFileName[255];
    char adtsFileName[255];
Fixed code: ** $Id: main.c,v 1.88 2012/03/04 09:59:02 knik Exp $
    char *aacFileName = NULL;
    char *audioFileName = NULL;
    char *adtsFileName = NULL;
                audioFileName = (char *) malloc(sizeof(char) * (strlen(optarg) + 1));
                if (audioFileName == NULL)
                {
                    faad_fprintf(stderr, "Error allocating memory for audioFileName.\n");
                    return 1;
                }
                adtsFileName = (char *) malloc(sizeof(char) * (strlen(optarg) + 1));
                if (adtsFileName == NULL)
                {
                    faad_fprintf(stderr, "Error allocating memory for adtsFileName.\n");
                    return 1;
                }
    aacFileName = (char *) malloc(sizeof(char) * (strlen(argv[optind]) + 1));
    if (aacFileName == NULL)
    {
        faad_fprintf(stderr, "Error allocating memory for aacFileName.\n");
        return 1;
    }
        audioFileName = (char *) malloc(sizeof(char) * (strlen(aacFileName) + strlen(file_ext[format]) + 1));
        if (audioFileName == NULL)
        {
            faad_fprintf(stderr, "Error allocating memory for audioFileName.\n");
            return 1;
        }
    if (audioFileName != NULL)
      free (audioFileName);
    if (adtsFileName != NULL)
      free (adtsFileName);

    if (aacFileName != NULL)
      free (aacFileName);