David Litchfield's Weblog

Home
Archives
NGSSoftware
DatabaseSecurity.com


Greymatter Forums

April 2008
SMTWTFS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30      

Valid XHTML 1.0!

Powered By Greymatter

RSS 1.0 FEED
RSS 2.0 FEED
Atom 0.3 FEED
Powered by gm-rss 2.0.1
Home » Archives » April 2008 » A bug in fread() could lead to a buffer overflow vulnerability

[Previous entry: "Are you sure? Surety, integrity, confidentiality and availability"] [Next entry: "Code Commandos, SDL and Metrics"]

04/15/2008: "A bug in fread() could lead to a buffer overflow vulnerability"


Back in October 2005 I isolated a bug in the MS C runtime fread() function which in certain cirumstances could lead to a buffer overflow. When a file is opened in text mode any carriage-returns/line-feeds (CR-LFs) are converted to CR. This is documented on MSDN. However, if the destination buffer for fread is bigger than 4095 bytes then the translation takes place in place and for each CRLF the buffer is shifted left once. Once all CR-LFs are converted no NULL terminator is set. So if a text file has the following contents

"16*CRLF"0123456789ABCDEF

what ends up in the destination buffer is

"16*CR"0123456789ABCDEF0123456789ABCDEF

However the return value for fread is 32. This can lead to an overflow - consider the following code:



#include "stdio.h"

FILE *fd =NULL;
char *buffer = NULL;

int main()
{
unsigned int bytesread = 0;
unsigned char name[36]="";
buffer = (char *) malloc(4100);
if(!buffer)
return 0;
memset(buffer,0,4100);
fd = fopen("foo.txt","r");
if(!fd)
{
free(buffer);
return 0;
}
bytesread = fread(buffer,1,4096,fd);
printf("Bytes read = %d\n",bytesread);

// check that there are no more than 32 bytes in the buffer
if(bytesread > 32)
{
free(buffer);
fclose(fd);
printf("Name is too long\n");
return 1;
}
strcpy(name,buffer);
printf("%s\n",name);
free(buffer);
fclose(fd);
return 0;
}


Also, if 0x1A (Ctrl^Z) is encountered then fread returns the number of bytes up to 0x1A even though the number of bytes in the buffer is longer.

Now this is not going to turn into a class of flaw like format string bugs or anything, of course, but the lessson here is don't trust the return value of fread() as you could end up in trouble!