0

Please help me understand - why am I getting this run-time error:

*** stack smashing detected ***:
Program received signal SIGABRT, Aborted.

for the following code :

#define WORD_SIZE   (sizeof(int))
#define FLOOR_MASK  0xfffffffc


static void SetVal(void* _block, int _size)
{
    *(int*)_block = _size;
}

void BufferInit(void* _buffer, size_t _totalSize)
{
  int alignedSize;

  assert(_buffer);

  /* align _totalSize to be WORD_SIZE multiple */
  alignedSize = _totalSize & FLOOR_MASK;

  /* mark end of buffer */
  SetVal(_buffer + alignedSize, END_VAL);
}

int main()
{
    Byte buffer[36];

    BufferInit(buffer, 37);

    return 0;
}

P.S: The error occurs at the end of the run (on line "return 0;" ).

Thanks.

cookya
  • 3,019
  • 7
  • 26
  • 37
  • Can we see the code for SetVal? Seems like you have a stack allocated buffer and you might be writing past the end of it. – CallMeNorm Feb 13 '13 at 22:15
  • @CallMeNorm Right, I added it now. – cookya Feb 13 '13 at 22:17
  • @wildplasser Why? It's 0 – cookya Feb 13 '13 at 22:29
  • 1
    Are you sure that this is the code? `_buffer + alignedSize` should not compile, you cannot perform pointer arithmetic with `void *`. – Omri Barel Feb 13 '13 at 22:30
  • @OmriBarel: Most compilers (including GCC) treat `void *` as if it were `char *` for the purposes of pointer arithmetic. –  Feb 13 '13 at 22:37
  • @OmriBarel This is the code, and it's compiled. http://stackoverflow.com/a/3524270/1355968 But It doesn't work for all versions, I suppose. – cookya Feb 13 '13 at 22:37
  • @duskwuff: thanks for that! I routinely use 7-8 different compilers for different platforms, and had they impression that most (if not all) of them didn't like `void *` arithmetic. I must be using `-pedantic -Werror` far too often... – Omri Barel Feb 13 '13 at 23:00

2 Answers2

3

The SetVal() function writes to 4 bytes to the location you have indicated as the end. That is:

BufferInit(buffer, 37);

... Leads to ... 

SetVal(_buffer + alignedSize, END_VAL);

... which does ...

*(int*)_block = _size;

alignedSize is 36 (37 & ~3 = 36) [~3 = 0xFFFFFFFC]. 4 bytes at offset 36 writes to bytes 36, 37, 38 and 39. Since your buffer originally is 36 bytes long, it's outside of your buffer. Either change your buffer to be 40 bytes long, or change your 37 to be 33 [or a lower number].

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • Thanks! Just got to the same conclusion myself. :) Since I want to change the last Word (4 bytes) in the buffer, I'm now reducing WORD_SIZE from the prev buffer offset. – cookya Feb 13 '13 at 23:00
0

Stupid mistake..

I exceeded buffer's size:

alignedSize [= buffer size] = 36
bytes allocated for buffer:   0-35

I'm changing (buffer+36) = buffer[36] which is beyond buffer's memory limit.

Fixed code:

SetVal(_buffer + alignedSize - WORD_SIZE, END_VAL); 
cookya
  • 3,019
  • 7
  • 26
  • 37