diff mbox

[4.9] Backport fix for PR sanitizer/64820.

Message ID 564C44AD.20203@partner.samsung.com
State New
Headers show

Commit Message

max Nov. 18, 2015, 9:28 a.m. UTC
Hi,

this small patch fixes the logic in ASan vs SSP interaction to provide 
correct "size" parameter to asan_stack_malloc_[N] routines. With current 
logic, we would have assertion failure in libsanitizer in UAR mode on 
32-bit targets due to wrong granularity of resulting addr + size address.

Regtested via make check RUNTESTFLAGS="--target_board=unix'{-m32,-m64}' 
-j12 on x86_64-unknown-linux-gnu and bootstrapped on 
x86_64-unknown-linux-gnu.

Ok for gcc-4_9-branch?

-Maxim

Comments

max Nov. 25, 2015, 9:14 a.m. UTC | #1
I would like to ping the patch: 
https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02174.html.
max Dec. 1, 2015, 5:23 p.m. UTC | #2
On 25/11/15 12:14, Maxim Ostapenko wrote:
> I would like to ping the patch: 
> https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02174.html.
>

Ping.

-Maxim
Joakim Tjernlund Dec. 1, 2015, 7:28 p.m. UTC | #3
On Tue, 2015-12-01 at 20:23 +0300, Maxim Ostapenko wrote:
> On 25/11/15 12:14, Maxim Ostapenko wrote:
> > I would like to ping the patch: 
> > https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02174.html.
> > 
> 
> Ping.

Yes, please add :)
max Dec. 8, 2015, 10:48 a.m. UTC | #4
On 01/12/15 20:23, Maxim Ostapenko wrote:
> On 25/11/15 12:14, Maxim Ostapenko wrote:
>> I would like to ping the patch: 
>> https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02174.html.
>>
>
> Ping.
>

Ping.

-Maxim
Jakub Jelinek Dec. 8, 2015, 10:54 a.m. UTC | #5
On Tue, Dec 08, 2015 at 01:48:46PM +0300, Maxim Ostapenko wrote:
> 
> On 01/12/15 20:23, Maxim Ostapenko wrote:
> >On 25/11/15 12:14, Maxim Ostapenko wrote:
> >>I would like to ping the patch:
> >>https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02174.html.
> >>
> >
> >Ping.
> >
> 
> Ping.

Ok.

	Jakub
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4df00bf..f1f2744 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@ 
+2015-11-18  Max Ostapenko  <m.ostapenko@partner.samsung.com>
+
+	Backport from mainline.
+	2015-03-16  Max Ostapenko  <m.ostapenko@partner.samsung.com>
+
+	PR sanitizer/64820
+	* cfgexpand.c (align_base): New function.
+	(alloc_stack_frame_space): Call it.
+	(expand_stack_vars): Align prev_frame to be sure
+	data->asan_vec elements aligned properly.
+
 2015-11-12  Eric Botcazou  <ebotcazou@adacore.com>
 
 	PR target/67265
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 14511e1..8bebd85 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -248,6 +248,15 @@  align_local_variable (tree decl)
   return align / BITS_PER_UNIT;
 }
 
+/* Align given offset BASE with ALIGN.  Truncate up if ALIGN_UP is true,
+   down otherwise.  Return truncated BASE value.  */
+
+static inline unsigned HOST_WIDE_INT
+align_base (HOST_WIDE_INT base, unsigned HOST_WIDE_INT align, bool align_up)
+{
+  return align_up ? (base + align - 1) & -align : base & -align;
+}
+
 /* Allocate SIZE bytes at byte alignment ALIGN from the stack frame.
    Return the frame offset.  */
 
@@ -256,20 +265,17 @@  alloc_stack_frame_space (HOST_WIDE_INT size, unsigned HOST_WIDE_INT align)
 {
   HOST_WIDE_INT offset, new_frame_offset;
 
-  new_frame_offset = frame_offset;
   if (FRAME_GROWS_DOWNWARD)
     {
-      new_frame_offset -= size + frame_phase;
-      new_frame_offset &= -align;
-      new_frame_offset += frame_phase;
+      new_frame_offset
+	= align_base (frame_offset - frame_phase - size,
+		      align, false) + frame_phase;
       offset = new_frame_offset;
     }
   else
     {
-      new_frame_offset -= frame_phase;
-      new_frame_offset += align - 1;
-      new_frame_offset &= -align;
-      new_frame_offset += frame_phase;
+      new_frame_offset
+	= align_base (frame_offset - frame_phase, align, true) + frame_phase;
       offset = new_frame_offset;
       new_frame_offset += size;
     }
@@ -983,13 +989,16 @@  expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
 	  base = virtual_stack_vars_rtx;
 	  if ((flag_sanitize & SANITIZE_ADDRESS) && ASAN_STACK && pred)
 	    {
-	      HOST_WIDE_INT prev_offset = frame_offset;
+	      HOST_WIDE_INT prev_offset
+		= align_base (frame_offset,
+			      MAX (alignb, ASAN_RED_ZONE_SIZE),
+			      FRAME_GROWS_DOWNWARD);
 	      tree repr_decl = NULL_TREE;
-
 	      offset
 		= alloc_stack_frame_space (stack_vars[i].size
 					   + ASAN_RED_ZONE_SIZE,
 					   MAX (alignb, ASAN_RED_ZONE_SIZE));
+
 	      data->asan_vec.safe_push (prev_offset);
 	      data->asan_vec.safe_push (offset + stack_vars[i].size);
 	      /* Find best representative of the partition.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0072132..3d565ec 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@ 
+2015-11-18  Max Ostapenko  <m.ostapenko@partner.samsung.com>
+
+	Backport from mainline.
+	2015-03-16  Max Ostapenko  <m.ostapenko@partner.samsung.com>
+
+	PR sanitizer/64820
+	* c-c++-common/asan/pr64820.c: New test.
+
 2015-11-12  Eric Botcazou  <ebotcazou@adacore.com>
 
 	* gcc.target/i386/pr67265-2.c: New test.
diff --git a/gcc/testsuite/c-c++-common/asan/pr64820.c b/gcc/testsuite/c-c++-common/asan/pr64820.c
new file mode 100644
index 0000000..885a662
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/pr64820.c
@@ -0,0 +1,31 @@ 
+/* { dg-do run } */
+/* { dg-require-effective-target fstack_protector } */
+/* { dg-options "-fstack-protector-strong" } */
+/* { dg-set-target-env-var ASAN_OPTIONS "detect_stack_use_after_return=1" } */
+/* { dg-shouldfail "asan" } */
+
+__attribute__((noinline))
+char *Ident(char *x) {
+  return x;
+}
+
+__attribute__((noinline))
+char *Func1() {
+  char local[1 << 12];
+  return Ident(local);
+}
+
+__attribute__((noinline))
+void Func2(char *x) {
+  *x = 1;
+}
+int main(int argc, char **argv) {
+  Func2(Func1());
+  return 0;
+}
+
+/* { dg-output "AddressSanitizer: stack-use-after-return on address 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output "WRITE of size 1 at .* thread T0.*" } */
+/* { dg-output "    #0.*(Func2)?.*pr64820.(c:21)?.*" } */
+/* { dg-output "is located in stack of thread T0 at offset.*" } */
+/* { dg-output "\'local\' <== Memory access at offset 32 is inside this variable" } */