This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 05/10] Implement protection of stack variables


On 2012-11-02 16:00 , Dodji Seketeli wrote:
This patch implements the protection of stack variables.

To understand how this works, lets look at this example on x86_64
where the stack grows downward:

  int
  foo ()
  {
    char a[23] = {0};
    int b[2] = {0};

    a[5] = 1;
    b[1] = 2;

    return a[5] + b[1];
  }

For this function, the stack protected by asan will be organized as
follows, from the top of the stack to the bottom:

Slot 1/ [red zone of 32 bytes called 'RIGHT RedZone']

Slot 2/ [24 bytes for variable 'a']

Slot 3/ [8 bytes of red zone, that adds up to the space of 'a' to make
          the next slot be 32 bytes aligned; this one is called Partial
          Redzone; this 32 bytes alignment is an asan constraint]

Slot 4/ [red zone of 32 bytes called 'Middle RedZone']

Slot 5/ [8 bytes for variable 'b']

Slot 6/ [24 bytes of Partial Red Zone (similar to slot 3]

Slot 7/ [32 bytes of Red Zone at the bottom of the stack, called 'LEFT
          RedZone']

[A cultural question I've kept asking myself is Why has address
  sanitizer authors called these red zones (LEFT, MIDDLE, RIGHT)
  instead of e.g, (BOTTOM, MIDDLE, TOP).  Maybe they can step up and
  educate me so that I get less confused in the future.  :-)]

I believe they layout the stack from right to left (top is to the right). Feels like reading a middle earth map. Kostya, is my recollection correct?


The 32 bytes of LEFT red zone at the bottom of the stack can be
decomposed as such:

     1/ The first 8 bytes contain a magical asan number that is always
     0x41B58AB3.

     2/ The following 8 bytes contains a pointer to a string (to be
     parsed at runtime by the runtime asan library), which format is
     the following:

      "<function-name> <space> <num-of-variables-on-the-stack>
      (<32-bytes-aligned-offset-in-bytes-of-variable> <space>
      <length-of-var-in-bytes> ){n} "

	where '(...){n}' means the content inside the parenthesis occurs 'n'
	times, with 'n' being the number of variables on the stack.

      3/ The following 16 bytes of the red zone have no particular
      format.

The shadow memory for that stack layout is going to look like this:

     - content of shadow memory 8 bytes for slot 7: 0xFFFFFFFFF1F1F1F1.
       The F1 byte pattern is a magic number called
       ASAN_STACK_MAGIC_LEFT and is a way for the runtime to know that
       the memory for that shadow byte is part of a the LEFT red zone
       intended to seat at the bottom of the variables on the stack.

     - content of shadow memory 8 bytes for slots 6 and 5:
       0xFFFFFFFFF4F4F400.  The F4 byte pattern is a magic number
       called ASAN_STACK_MAGIC_PARTIAL.  It flags the fact that the
       memory region for this shadow byte is a PARTIAL red zone
       intended to pad a variable A, so that the slot following
       {A,padding} is 32 bytes aligned.

       Note that the fact that the least significant byte of this
       shadow memory content is 00 means that 8 bytes of its
       corresponding memory (which corresponds to the memory of
       variable 'b') is addressable.

     - content of shadow memory 8 bytes for slot 4: 0xFFFFFFFFF2F2F2F2.
       The F2 byte pattern is a magic number called
       ASAN_STACK_MAGIC_MIDDLE.  It flags the fact that the memory
       region for this shadow byte is a MIDDLE red zone intended to
       seat between two 32 aligned slots of {variable,padding}.

     - content of shadow memory 8 bytes for slot 3 and 2:
       0xFFFFFFFFF4000000.  This represents is the concatenation of
       variable 'a' and the partial red zone following it, like what we
       had for variable 'b'.  The least significant 3 bytes being 00
       means that the 3 bytes of variable 'a' are addressable.

     - content of shadow memory 8 bytes for slot 1: 0xFFFFFFFFF3F3F3F3.
       The F3 byte pattern is a magic number called
       ASAN_STACK_MAGIC_RIGHT.  It flags the fact that the memory
       region for this shadow byte is a RIGHT red zone intended to seat
       at the top of the variables of the stack.


This is a great summary. Please put it at the top of asan.c or in some other prominent place.



-	  offset = alloc_stack_frame_space (stack_vars[i].size, alignb);
+	  if (flag_asan && pred)
+	    {
+	      HOST_WIDE_INT prev_offset = frame_offset;
+	      tree repr_decl = NULL_TREE;
+
+	      offset
+		= alloc_stack_frame_space (stack_vars[i].size
+					   + ASAN_RED_ZONE_SIZE,
+					   MAX (alignb, ASAN_RED_ZONE_SIZE));
+	      VEC_safe_push (HOST_WIDE_INT, heap, data->asan_vec,
+			     prev_offset);
+	      VEC_safe_push (HOST_WIDE_INT, heap, data->asan_vec,
+			     offset + stack_vars[i].size);

Oh, gee, thanks. More VEC() code for me to convert ;)



The patch is OK.



Diego.



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]