Akshay Krishnan R
Akshay Krishnan R

Reputation: 443

Allocation of space for static variables on the stack

The following code contains an 8 bytes buffer.

void vuln() {
    char buffer[8];
    gets(buffer);
    printf("%s",buffer);
}

int main() {
    vuln();
    return 0;
}

So, only 8 bytes of stack is expected to be reserved for this buffer. But the disassembly shows 16 bytes being reserved.

(gdb) 
Dump of assembler code for function vuln:
   0x000000000040057d <+0>:     push   %rbp
   0x000000000040057e <+1>:     mov    %rsp,%rbp
   0x0000000000400581 <+4>:     sub    $0x10,%rsp
   0x0000000000400585 <+8>:     lea    -0x10(%rbp),%rax
   0x0000000000400589 <+12>:    mov    %rax,%rdi
   0x000000000040058c <+15>:    callq  0x400480 <gets@plt>
   0x0000000000400591 <+20>:    lea    -0x10(%rbp),%rax
   0x0000000000400595 <+24>:    mov    %rax,%rsi
   0x0000000000400598 <+27>:    mov    $0x400644,%edi
   0x000000000040059d <+32>:    mov    $0x0,%eax
   0x00000000004005a2 <+37>:    callq  0x400450 <printf@plt>
   0x00000000004005a7 <+42>:    leaveq 
   0x00000000004005a8 <+43>:    retq   
End of assembler dump.

Some actions are to be perform based on the expected size of the buffer on the stack in an automated script. But this crippled the script. May I know the reason why 16 bytes were allocated for the buffer so that I can incorporate it in the script ?

Upvotes: 2

Views: 142

Answers (3)

ouah
ouah

Reputation: 145839

As @Zack put in his answer, x86-64 ABI requires 16 bytes stack alignment. If you are using gcc on x86 or x86_64 by default stack is 16 bytes aligned.

From gcc documentation:

-mpreferred-stack-boundary=num Attempt to keep the stack boundary aligned to a 2 raised to num byte boundary. If -mpreferred-stack-boundary is not specified, the default is 4 (16 bytes or 128 bits).

https://gcc.gnu.org/onlinedocs/gcc/i386-and-x86-64-Options.html

See the documentation further, if SSE is disabled gcc may align stack to 8 bytes (and thus violate ABI requirements).

Upvotes: 1

zwol
zwol

Reputation: 140589

The x86-64 ELF psABI requires the stack pointer to be aligned: section 3.2.2 ("The Stack Frame") says

... The end of the input argument area shall be aligned on a 16 byte boundary. In other words, the value (%rsp− 8) is always a multiple of 16 when control is transferred to the function entry point. The stack pointer, %rsp, always points to the end of the latest allocated stack frame.

Your function allocates 8 bytes on the stack and then calls a one-argument function, gets; that function's one argument is passed in registers, so to maintain the ABI requirement, the compiler has to move the stack pointer down an additional 8 bytes before it makes the function call.

Upvotes: 2

rslemos
rslemos

Reputation: 2731

You can't control what the compiler will do on the stack. You also can't control the order of variables on the stack. The compiler is also allowed to introduce padding so to better align things in memory (although not inside arrays: this is strictly forbidden). In certain cases it won't even allocate variables on stack, but in registers instead.

If you has specific needs on assembly level, do it in assembly.

Upvotes: 0

Related Questions