steleman / address-sanitizer

Automatically exported from code.google.com/p/address-sanitizer
0 stars 0 forks source link

ASan shouldn't instrument globals defined in ".CRT*$*" sections #305

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Example program:
-------------------------
#include <stdio.h>

int met_you = 0;

void call_me_maybe() {
  met_you = 1;
}

typedef void (*FPTR)();
#pragma data_seg(".CRT$XIB")
// Put a global callback in the right section
// to be invoked before the CRT initializers.
FPTR run_on_startup = call_me_maybe;

#pragma data_seg()
// Back to normal compilation.

// __xi_a and __xi_z are defined in VC/crt/src/crt0dat.c
// and are located in .CRT$XIA and .CRT$XIZ respectively.
extern "C" FPTR __xi_a, __xi_z;

int main() {
  if (!met_you) {
    printf("this is crazy\n");
    return 1;
  }

  // Helps debugging.
  printf("&run_on_startup = %p, call_me_maybe = %p\n",
         &run_on_startup, call_me_maybe);

  // Iterate through CRT initializers.
  for (FPTR* it = &__xi_a; it < &__xi_z; ++it)
    printf(".CRT$XI*: %p => %p\n", it, *it);
}
-------------------------

Background:
.CRT$XIA...XIZ sections are arrays of callbacks to be invoked at CRT 
initialization time in a for loop (unless an entry is zero).  One can add an 
extra initialization callback simply by defining a global function pointer in 
the appropriate section.

The problem is that ASan happily adds redzones after these globals, thus breaks 
typical traversal of the list of callbacks.  We should probably just disable 
adding redzones for globals in ".CRT*$*" sections.

Original issue reported on code.google.com by timurrrr@google.com on 5 May 2014 at 1:11

GoogleCodeExporter commented 9 years ago
Forgot to put the output under ASan here:
=================================================================
&run_on_startup = 002A21A0, call_me_maybe = 00271000
.CRT$XI*: 002A2188 => 00000000
.CRT$XI*: 002A218C => 00000000
.CRT$XI*: 002A2190 => 00000000
.CRT$XI*: 002A2194 => 00000000
.CRT$XI*: 002A2198 => 00000000
.CRT$XI*: 002A219C => 00000000
.CRT$XI*: 002A21A0 => 00271000
=================================================================
==7588==ERROR: AddressSanitizer: global-buffer-overflow on address 0x002a21a4 
at pc 0x2712cf sp 0x1af914
READ of size 4 at 0x002a21a4 thread T0
    #0 0x2712ce in main test.cpp:34

0x002a21a4 is located 0 bytes to the right of global variable 
'☺?run_on_startup@@3P6AXXZA' from 'test.cpp' (0x2a21a0) of size 4
SUMMARY: AddressSanitizer: global-buffer-overflow test.cpp:34 main
Shadow bytes around the buggy address:
  0x200543e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x200543f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x20054400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x20054410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x20054420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x20054430: 00 00 00 00[04]f9 f9 f9 f9 f9 f9 f9 00 00 00 00

Original comment by timurrrr@google.com on 5 May 2014 at 1:12

GoogleCodeExporter commented 9 years ago
http://llvm.org/viewvc/llvm-project?revision=207968&view=revision

Original comment by timurrrr@google.com on 5 May 2014 at 2:45