
We recently identified a potential buffer overflow in the C/C++ runtime library (RTL). Although this is an issue that was introduced to the code in 1997 with no exploitation since its introduction, we are publishing a notification and a fix for safety and openness, out of an abundance of caution.
Issue information:
- Affects _wgetcurdir, _wsearchstr, plus the “_t” variants _tgetdcwd and _tgetcwd. These methods get the current working directory, and are non-ISO standard functions based on POSIX getcwd, or macros that can resolve to using them, extended for wide characters.
- Affects Unicode builds
- Only occurs when these methods are used when passed null as the buffer. In this situation, the method allocates the buffer itself, but for Unicode, only allocates half the space needed. This means some of the current working directory names may be written past the buffer bounds.
- Affects applications (a) that use these methods and (b) are built with the classic, Win32 Clang, and old Win64 Clang (Clang v5) toolchains for Windows. These all use the affected RTL.
- It does not affect the STL
- It does not affect applications that are built with the new, Windows 64-bit Modern C++ toolchain
- It does not affect C++Builder or RAD Studio itself
Recommended mitigation
Check if your source code uses any of these methods, and if so rebuild the RTL with the below patch applied, or if you use a version without source available or don’t want to / cannot rebuild the RTL, simply pass the method a pre-allocated buffer or replace usage of the method with the Windows API GetCurrentDirectory.
Patch
A patch, with the key lines highlighted (first a comment and second the affected line of code) is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
--- a/source/io/getdcwd.c +++ b/source/io/getdcwd.c @@ -37,7 +37,7 @@ Description _getdcwd gets the full path name of the working directory error occurs. The drive is 0 for the default drive, 1=A, 2=B, etc. - If buf is NULL, a buffer n bytes long will be allocated + If buf is NULL, a buffer n characters long will be allocated for you with malloc. You can later free the allocated buffer by passing the _getdcwd return value to the function free. @@ -117,7 +117,7 @@ _TCHAR * _RTLENTRY _EXPFUNC _tgetdcwd(int drive, _TCHAR *bufP, int bufL) */ if (bufP == NULL) { - if ((bufP = malloc(bufL)) == NULL) + if ((bufP = malloc(bufL * sizeof(_TCHAR))) == NULL) { errno = ENOMEM; return NULL; |
Apply this to your copy of getdcwd.c, and rebuild the RTL following the instructions in the RTL source directory. For RAD Studio 12.1, you can download a prebuilt version of the RTL on my.embarcadero.com named “C++Builder and RAD Studio 12.1 C++ RTL Replacement”. If you have any issues, we recommend contacting Support.
Affected versions
The issue affects C++Builder 12.1 and earlier, including the Community Edition and Free Compiler. Future versions of C++Builder and RAD Studio will no longer have this issue.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition
Standing ovation!