The function Image_LoadBMP would only stop processing after the image width had been reached, causing it to write one extra pixel beyond the allocated buffer for certain 1-bit BMPs.
case 1:
alpha = *buf_p++;
column--; // decrement to compensate for outer loop
for (c = 0, k = 128; c < 8; c++, k >>= 1) {
red = green = blue = (!!(alpha & k) == 1 ? 0xFF : 0x00);
*pixbuf++ = red; // writes
*pixbuf++ = green;
*pixbuf++ = blue;
*pixbuf++ = 0x00;
if (++column == columns) // only checks bounds after write
break;
}
break;
For a 1x1 image with 4 bytes allocated, the first iteration writes 4 bytes at column 0 (check fails: 0 != 1), but since the check is at the end, it will iterate a second time which will write another 4 bytes (this is the overflow) before the check succeeds and breaks.
static rgbdata_t *CustomDecal_LoadImage( const char *path, void *raw, int size )
{
const char *testname;
// this way we limit file types
if( !Q_stricmp( COM_FileExtension( path ), "png" ))
testname = "#logo.png";
else if( !Q_stricmp( COM_FileExtension( path ), "wad" ))
testname = "#logo.wad";
else testname = "#logo.bmp";
Image_SetForceFlags( IL_LOAD_PLAYER_DECAL );
return FS_LoadImage( testname, raw, size );
}
Summary
The function Image_LoadBMP would only stop processing after the image width had been reached, causing it to write one extra pixel beyond the allocated buffer for certain 1-bit BMPs.
Details
For a 1x1 image with 4 bytes allocated, the first iteration writes 4 bytes at column 0 (check fails: 0 != 1), but since the check is at the end, it will iterate a second time which will write another 4 bytes (this is the overflow) before the check succeeds and breaks.
PoC
CC=clang CXX=clang++ ./waf configure -T sanitize --enable-fuzzer --enable-engine-testsand./waf buildASAN_OPTIONS="detect_leaks=0" LD_LIBRARY_PATH="build/engine" build/utils/run-fuzzer/run-fuzzer-Image_LoadBMP poc.bmpagainst poc.bmpImpact
Any multiplayer users of the engine. According to engine/custom/custom.c, bmp files can be loaded as decals which are transmitted over the network https://steamcommunity.com/sharedfiles/filedetails/?id=3017564644: