Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc canaries : undefined reference to __stack_chk_guard

Tags:

c

gcc

compilation

I'm trying to enable gcc' s canaries' generation but I get an undefined reference to __stack_chk_guard.

From gcc's man about canaries :

-mstack-protector-guard=guard
       Generate stack protection code using canary at guard.  Supported locations are global for
       global canary or tls for per-thread canary in the TLS block (the default).  This option
       has effect only when -fstack-protector or -fstack-protector-all is specified.

   These -m switches are supported in addition to the above on x86-64 processors in 64-bit
   environments.

I've done this test program :

#define VALUE 2048
int    main()
{
  char arr[VALUE];
  int  i;

  for (i = 0; i < VALUE + 15; i++) // "i < VALUE + 15" is to test if canaries works but the code doesn't compile anymore with "i < 10" 
    arr[i] = '0';
  return 0;
}

As said in gcc's man, my compilation line is :

gcc main.c -fstack-protector-all -mstack-protector-guard=global

But I get the following error :

/tmp/ccXxxxVd.o: In function `main':
main.c:(.text+0xe): undefined reference to `__stack_chk_guard'
main.c:(.text+0x51): undefined reference to `__stack_chk_guard'
collect2: error: ld returned 1 exit status

How can I remove this error ?

EDIT:

  • OS: ubuntu 14.10 utopic
  • architecture: x86-64
  • environments: 64-bit
like image 849
Jérémy Pouyet Avatar asked Dec 04 '14 09:12

Jérémy Pouyet


People also ask

What is __ Stack_chk_guard?

__stack_chk_guard , which contains the value of the stack protection canary word. __stack_chk_fail , a callback function that is invoked when a stack buffer overflow is detected.

How do stack canaries work?

Stack canaries, named for their analogy to a canary in a coal mine, are used to detect a stack buffer overflow before execution of malicious code can occur. This method works by placing a small integer, the value of which is randomly chosen at program start, in memory just before the stack return pointer.

What does FNO stack protector do?

-fno-stack-protector disables stack protection. -fstack-protector enables stack protection for vulnerable functions that contain: A character array larger than 8 bytes. An 8-bit integer array larger than 8 bytes.

How does stack protector work?

The basic idea behind stack protection is to push a "canary" (a randomly chosen integer) on the stack just after the function return pointer has been pushed. The canary value is then checked before the function returns; if it has changed, the program will abort.


3 Answers

It would appear that the -mstack-protector-guard option is only for backwards compatibility with how the stack protector worked in the past. In the past the canary was in a global variable. Later it was switched to TLS. It would appear that the operating system / libc you use either removed or never had support for the global variable canary, so only TLS works.

Don't touch the -mstack-protector-guard option and everything should work. The default should be fine when you use -fstack-protector-all.

like image 83
Art Avatar answered Oct 17 '22 18:10

Art


Provide __stack_chk_guard with a random value in c file, avoid using regular values like all zero's or FF's because the stack can easily get these values during any memory operation. Wiki on providing magic number implementation. This __stack_chk_guard will be placed at the top and bottom of the stack, which will be checked during every stack access. Any change in the value implies a corrupted stack and returns with error providing the stack protection.

unsigned long __stack_chk_guard;
void __stack_chk_guard_setup(void)
{
     __stack_chk_guard = 0xBAAAAAAD;//provide some magic numbers
}

void __stack_chk_fail(void)                         
{
 /* Error message */                                 
}// will be called when guard variable is corrupted 
like image 4
Sathiya Avatar answered Oct 17 '22 16:10

Sathiya


There are two ways to remove this error: 1. From the compiler option disable(comment out) the "stack guard".

  1. Define __stack_chk_guard in you c file.

When you define __stack_chk_guard make sure you provide random value to it. For providing random value you need to pass as an argument to the random function.

For any further detail you can refer to the compiler manual.

like image 2
Ravi Ranjan Kishor Avatar answered Oct 17 '22 16:10

Ravi Ranjan Kishor