VYPR
Moderate severityNVD Advisory· Published Oct 28, 2025· Updated Oct 28, 2025

Buffer overflow in CodeChecker log command

CVE-2025-40843

Description

CodeChecker is an analyzer tooling, defect database and viewer extension for the Clang Static Analyzer and Clang Tidy.

CodeChecker versions up to 6.26.1 contain a buffer overflow vulnerability in the internal ldlogger library, which is executed by the CodeChecker log command.

This issue affects CodeChecker: through 6.26.1.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
codecheckerPyPI
< 6.26.26.26.2

Affected products

1

Patches

1
4122eb1b43d0

Merge commit from fork

https://github.com/Ericsson/codecheckerbruntibSep 22, 2025via ghsa
5 files changed · +106 39
  • analyzer/tools/build-logger/src/ldlogger-tool.c+1 1 modified
    @@ -129,7 +129,7 @@ LoggerFile* loggerFileInitFromPath(LoggerFile* file_, const char* path_)
       if (!loggerMakePathAbs(path_, file_->path, 0))
       {
         /* fallback to the given path */
    -    strcpy(file_->path, path_);
    +    safe_strcpy(file_->path, path_, PATH_MAX);
       }
     
       return file_;
    
  • analyzer/tools/build-logger/src/ldlogger-tool-gcc.c+12 10 modified
    @@ -83,11 +83,12 @@ static void getDefaultArguments(const char* prog_, LoggerVector* args_)
       ssize_t readSize;
       int incStarted = 0;
     
    -  strcpy(command, prog_);
    +  safe_strcpy(command, prog_, PATH_MAX);
    +
       /* WARNING: this always gets the C++ compiler include
        * dirs even if we are compiling C file.
        * */
    -  strcat(command, " -xc++ -E -v - < /dev/null 2>&1");
    +  safe_strcat(command, " -xc++ -E -v - < /dev/null 2>&1", PATH_MAX);
     
       cmdOut = popen(command, "r");
       if (!cmdOut)
    @@ -215,9 +216,9 @@ char* findFullPath(const char* executable, char* fullpath) {
       char* dir;
       path = strdup(getenv("PATH"));
       for (dir = strtok(path, ":"); dir; dir = strtok(NULL, ":")) {
    -    strcpy(fullpath, dir);
    -    strcpy(fullpath + strlen(dir), "/");
    -    strcpy(fullpath + strlen(dir) + 1, executable);
    +    safe_strcpy(fullpath, dir, PATH_MAX);
    +    safe_strcat(fullpath, "/", PATH_MAX);
    +    safe_strcat(fullpath, executable, PATH_MAX);
         if (access(fullpath, F_OK ) != -1 ) {
             free(path);
             return fullpath;
    @@ -300,17 +301,18 @@ void transformSomePathsAbsolute(LoggerVector* args_)
           const char* path = (const char*)args_->data[i] + strlen(*flag);
           if (*path)
           {
    -        char newPath[PATH_MAX];
    -        strcpy(newPath, *flag);
    +        // Increased buffer size for flags
    +        char newPath[PATH_MAX + 256];
    +        safe_strcpy(newPath, *flag, 256);
     
             int hasEqual = *path == '=';
             if (hasEqual)
             {
    -          strcat(newPath, "=");
    +          safe_strcat(newPath, "=", 256);
               ++path;
             }
     
    -        loggerMakePathAbs(path, newPath + strlen(*flag) + hasEqual, 0);
    +        loggerMakePathAbs(path, newPath + strlen(newPath), 0);
             loggerVectorReplace(args_, i, loggerStrDup(newPath));
           }
           else
    @@ -441,7 +443,7 @@ int loggerGccParserCollectActions(
                 }
                 else
                 {
    -              strcpy(newPath, current);
    +              safe_strcpy(newPath, current, PATH_MAX);
                 }
                 loggerVectorAddUnique(&action->sources, loggerStrDup(newPath),
                   (LoggerCmpFuc) &strcmp);
    
  • analyzer/tools/build-logger/src/ldlogger-tool-javac.c+17 17 modified
    @@ -47,7 +47,7 @@ static void readArgumentsFromFile(const char* file_, LoggerVector* args_)
       char* line = NULL;
       size_t lineSize = 0;
       ssize_t readSize;
    -  
    +
       FILE* file = fopen(file_, "r");
       if (!file)
       {
    @@ -121,18 +121,18 @@ static int handleClassPath(
     
       **resCp_ = 0;
       classPath = (char*) malloc((strlen(cp_) + 1) * sizeof(char));
    -  strcpy(classPath, cp_);
    +  safe_strcpy(classPath, cp_, strlen(cp_) + 1);
     
       for (cpPart = strtok(classPath, ":"); cpPart; cpPart = strtok(NULL, ":"))
       {
         size_t i;
         char** words;
         wordexp_t we;
    -   
    +
         memset(&we, 0, sizeof(wordexp_t));
         if (wordexp(cpPart, &we, WRDE_NOCMD | WRDE_UNDEF) != 0)
         {
    -      strcpy(*resCp_, cp_);
    +      safe_strcpy(*resCp_, cp_, PATH_MAX);
           free(classPath);
           return 0;
         }
    @@ -155,7 +155,7 @@ static int handleClassPath(
             if (!newMem)
             {
               /* Out of memory */
    -          strcpy(*resCp_, cp_);
    +          safe_strcpy(*resCp_, cp_, PATH_MAX);
               free(classPath);
               wordfree(&we);
               return 0;
    @@ -165,8 +165,8 @@ static int handleClassPath(
             *resCpSize_ = currSize * 2;
           }
     
    -      strcat(*resCp_, path);
    -      strcat(*resCp_, ":");
    +      safe_strcat(*resCp_, path, PATH_MAX);
    +      safe_strcat(*resCp_, ":", PATH_MAX);
         }
     
         wordfree(&we);
    @@ -202,16 +202,16 @@ static void processArg(const char* arg_, ParserData* data_)
         return;
       }
     
    -  strcpy(argToAdd, arg_);
    +  safe_strcpy(argToAdd, arg_, PATH_MAX);
     
       if (data_->state == InClassDir)
       {
         if (!loggerMakePathAbs(arg_, data_->classdir, 0))
         {
    -      strcpy(data_->classdir, arg_);
    +      safe_strcpy(data_->classdir, arg_, PATH_MAX);
         }
     
    -    strcpy(argToAdd, data_->classdir);
    +    safe_strcpy(argToAdd, data_->classdir, PATH_MAX);
         data_->state = Normal;
       }
       else if (data_->state == InClassPath)
    @@ -287,7 +287,7 @@ int loggerJavacParserCollectActions(
           LoggerVector fargs;
     
           loggerVectorInit(&fargs);
    -      
    +
           readArgumentsFromFile(argv_[i] + 1, &fargs);
           for (j = 0; j < fargs.size; ++j)
           {
    @@ -330,17 +330,17 @@ int loggerJavacParserCollectActions(
         if (data.classdir[0] != 0)
         {
           char* fname = loggerGetFileName(src, 1);
    -      strcpy(outputFile, data.classdir);
    -      strcat(outputFile, "/");
    -      strcat(outputFile, fname);
    -      strcat(outputFile, ".class");
    +      safe_strcpy(outputFile, data.classdir, PATH_MAX);
    +      safe_strcat(outputFile, "/", PATH_MAX);
    +      safe_strcat(outputFile, fname, PATH_MAX);
    +      safe_strcat(outputFile, ".class", PATH_MAX);
           free(fname);
         }
         else
         {
           char* path = loggerGetFilePathWithoutExt(src);
    -      strcpy(outputFile, path);
    -      strcat(outputFile, ".class");
    +      safe_strcpy(outputFile, path, PATH_MAX);
    +      safe_strcat(outputFile, ".class", PATH_MAX);
           free(path);
         }
     
    
  • analyzer/tools/build-logger/src/ldlogger-util.c+49 8 modified
    @@ -16,6 +16,7 @@
     #include <stdlib.h>
     #include <stdint.h>
     #include <stdio.h>
    +#include <string.h>
     #include <sys/file.h>
     #include <sys/stat.h>
     #include <time.h>
    @@ -29,12 +30,12 @@ static char* makePathAbsRec(const char* path_, char* resolved_)
     
       if (realpath(path_, pathBuff))
       {
    -    pathBuff[PATH_MAX - 1] = 0;
    -    return strcpy(resolved_, pathBuff);
    +    safe_strcpy(resolved_, pathBuff, PATH_MAX);
    +    return resolved_;
       }
       else
       {
    -    strcpy(pathBuff, path_);
    +    safe_strcpy(pathBuff, path_, PATH_MAX);
       }
     
       /* cut off the last part */
    @@ -54,8 +55,8 @@ static char* makePathAbsRec(const char* path_, char* resolved_)
       *slashPos = 0;
       if (makePathAbsRec(pathBuff, resolved_))
       {
    -    strcat(resolved_, "/");
    -    strcat(resolved_, child);
    +    safe_strcat(resolved_, "/", PATH_MAX);
    +    safe_strcat(resolved_, child, PATH_MAX);
         return resolved_;
       }
     
    @@ -248,8 +249,8 @@ char* loggerMakePathAbs(const char* path_, char* resolved_, int mustExist_)
           return NULL;
         }
     
    -    strcat(newPath, "/");
    -    strcat(newPath, path_);
    +    safe_strcat(newPath, "/", PATH_MAX);
    +    safe_strcat(newPath, path_, PATH_MAX);
         return makePathAbsRec(newPath, resolved_);
       }
     
    @@ -590,7 +591,7 @@ int aquireLock(char const* logFile_)
         return -1;
       }
     
    -  strcat(lockFilePath, ".lock");
    +  safe_strcat(lockFilePath, ".lock", PATH_MAX);
       lockFile = open(lockFilePath, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
       if (lockFile == -1)
       {
    @@ -706,3 +707,43 @@ void logPrint(char* logLevel_, char* fileName_, int line_, char *fmt_,...)
       fclose(stream);
       freeLock(lockFd);
     }
    +
    +char* safe_strcpy(char* dest, const char* src, size_t buf_size)
    +{
    +  if (buf_size == 0)
    +  {
    +    fprintf(stderr, "ERROR: safe_strcpy failed, buffer size invalid\n");
    +    exit(1);
    +  }
    +
    +  strncpy(dest, src, buf_size);
    +
    +  if (dest[buf_size - 1] != '\0')
    +  {
    +    fprintf(stderr, "ERROR: safe_strcpy failed, string too long\n");
    +    exit(1);
    +  }
    +
    +  return dest;
    +}
    +
    +char* safe_strcat(char* dest, const char* src, size_t buf_size)
    +{
    +  if (buf_size == 0)
    +  {
    +    fprintf(stderr, "ERROR: safe_strcat failed, buffer size invalid\n");
    +    exit(1);
    +  }
    +
    +  size_t n = buf_size - strlen(dest) - 1;
    +
    +  if (strlen(src) > n)
    +  {
    +    fprintf(stderr, "ERROR: safe_strcat failed, string too long\n");
    +    exit(1);
    +  }
    +
    +  strncat(dest, src, n);
    +
    +  return dest;
    +}
    
  • analyzer/tools/build-logger/src/ldlogger-util.h+27 3 modified
    @@ -38,7 +38,7 @@ int predictEscapedSize(const char* str_);
      * the documentation of predictEscapedSize() for some examples.
      *
      * The '\\', '\r' and '\v' characters are also escaped correctly.
    - * 
    + *
      * @param str_ a string to escape (non null).
      * @param buff_ an output buffer (non null).
      * @return anways returns buff_.
    @@ -85,7 +85,7 @@ typedef int (*LoggerPredFuc)(const void*);
     /**
      * A very simple vector.
      */
    -typedef struct _LoggerVector 
    +typedef struct _LoggerVector
     {
       /**
        * The actual size of the vector.
    @@ -257,7 +257,7 @@ char* loggerGetFilePathWithoutExt(const char* absPath_);
     
     /**
      * Return the file`s name with or without it`s extension.
    - * 
    + *
      * @param absPath_ the absolute file path.
      * @param withoutExt_ with or without extension.
      * @return file name or NULL on error..
    @@ -297,4 +297,28 @@ void freeLock(int lockFile_);
      */
     void logPrint(char* logLevel_, char* fileName_, int line_, char* fmt_, ...);
     
    +/**
    + * Safe version of strcpy that checks buffer size and exits
    + * if string truncation would occur.
    + *
    + * @param dest destination buffer pointer.
    + * @param src source buffer pointer.
    + * @param buf_size size of the destination buffer.
    + *
    + * @return returns destination pointer dest.
    + */
    +char* safe_strcpy(char* dest, const char* src, size_t buf_size);
    +
    +/**
    + * Safe version of strcat that checks buffer size and exits
    + * if string truncation would occur.
    + *
    + * @param dest destination buffer pointer.
    + * @param src source buffer pointer.
    + * @param buf_size size of the destination buffer.
    + *
    + * @return returns destination pointer dest.
    + */
    +char* safe_strcat(char* dest, const char* src, size_t buf_size);
    +
     #endif /* __LOGGER_UTIL_H__ */
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.