tags:

views:

270

answers:

4
+1  Q: 

Stack memory read

Hi,

With the following piece of code:

typedef struct
{
    char    fileName[ 1024];
    time_t  deleteTime; 
} file_item_t;

....
....

setEntry(char *fileName)
{
    file_item_t     file;

    memset( &file, 0x00, sizeof( file_item_t ));

    memcpy( file.fileName, 
         fileName, 
         sizeof( file.fileName ) - 1 );
...
...

When the function is called, it runs OK on a SPARC machine but segfaults on an i386 both running Solaris 10. fileName is a nul-terminated string about 30 chars let's say. It appears that an attempt to read beyond the range of the fileName using memcpy() triggers a segmentation fault on some systems.

It's legacy code and easily correctable. But what I would like to know is about the underlying characteristics that can result in this failing or not. Is it related to read violation on the stack? Some boundary crossing? It is related to memory segmentation and is it just a case of chance (depending on how memory segmentation/paging is done by memory management and OS.) that it can fail or not.

Thanks a lot.

+1  A: 

Are you sure the string pointed to by fileName is really 1024 bytes in length? It somehow feels to me you should strcpy instead of memcpy.

If fileName is shorter, the memcpy copies the bytes behind the real string data, and will probably cause an access violation reading that memory.

Timbo
+5  A: 

You already hit the nail on the head:

In your memcpy you're reading past the length of filename.

Also dirty that will often work if the memory behind the filename is readable. In most cases it is, but if you for example pass a string-literal as an argument, and the linker puts the string into the last kilobyte of the data-section you will get a segmentation fault because the CPU tries to read from a memory location that is not mapped into the address space of your process.

The obvious fix is to use strcpy or strncpy.

Nils Pipenbrinck
A: 

hi. thanks for replies. no problem with the fix. strcpy/strncpy or even strlen with the memcpy works good. I guess the query is more on why it works sometimes and fails otherwise.

Trying to read unmapped memory could explain just that based on the position of the string literal. So essentially is it like an over read of the stack buffer?

+1  A: 

With the information given, we don't know where the argument char *filename is pointing to -- the stack, the heap, the data section, or other...

If it's on the stack, it may be because the default stack size on SPARC is much larger than on x86, and grows much higher. By the SPARC ABI, a stack frame always has space to back up all 16 registers, plus space for six parameters if the function takes any (even if it takes less). SPARC therefore consumes at least 64 or 92 bytes of stack per function call, whereas x86 can get away with just 8 or 4 bytes per function call.

If it's on the heap or in the data section, then it may just be that the runtime (heap) or compiler (data) happens to place the string near the end of a page on x86, so running off the end results in reading bad memory.

ephemient