This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][arm] avoid stack corruption
- From: "Seongbae Park (박성배, 朴成培)" <seongbae dot park at gmail dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, richard dot earnshaw at arm dot com
- Date: Tue, 19 Jun 2007 01:02:44 -0700
- Subject: [PATCH][arm] avoid stack corruption
Hi,
This patch fixes a potential stack corruption in thumb1 mode.
# cat m.c
int main() {
return 0;
}
# install.base/bin/arm-elf-gcc -O -mthumb -fno-omit-frame-pointer -S m.c
# cat m.s
.code 16
.file "m.c"
.text
.align 2
.global main
.code 16
.thumb_func
.type main, %function
main:
push {r7, lr}
add r7, sp, #8
mov r0, #0
mov sp, r7
sub sp, sp, #8
@ sp needed for prologue
pop {r7, pc}
.size main, .-main
.ident "GCC: (GNU) 4.3.0 20070618 (experimental)"
#
This is with the mainline.
As you can see, there's a window of potential stack corruption
if the interrupt arrives at the right time.
This is due to "amount" (i.e. frame size)
becoming negative in thumb1_expand_epilogue.
Not sure of how to test -mthumb -fno-omit-frame-pointer
combination effectively - how do I pass those into check-gcc tests ? -
I just tested as arm-elf on arm simulator and saw no regression.
Ok for mainline and for 4.2 and 4.1 branches ?
gcc/ChangeLog:
2007-04-19 Seongbae Park <seongbae.park@gmail.com>
* config/arm/arm.c (arm_get_frame_offsets): Set
offsets->locals_base to avoid negative stack size.
(thumb1_expand_prologue): Assert on negative stack size.
gcc/testsuite/ChangeLog:
2007-04-19 Seongbae Park <seongbae.park@gmail.com>
* gcc.target/arm/stack-corruption.c: New test.
--
#pragma ident "Seongbae Park, compiler, http://seongbae.blogspot.com"
Index: gcc/testsuite/gcc.target/arm/stack-corruption.c
===================================================================
--- gcc/testsuite/gcc.target/arm/stack-corruption.c (revision 0)
+++ gcc/testsuite/gcc.target/arm/stack-corruption.c (revision 0)
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mthumb -fno-omit-frame-pointer" } */
+
+int main() {
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "\tadd\tr7, sp, #8\n" } } */
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c (revision 125840)
+++ gcc/config/arm/arm.c (working copy)
@@ -11101,6 +11101,7 @@ arm_get_frame_offsets (void)
if (leaf && frame_size == 0)
{
offsets->outgoing_args = offsets->soft_frame;
+ offsets->locals_base = offsets->soft_frame;
return offsets;
}
@@ -14662,6 +14663,7 @@ thumb1_expand_epilogue (void)
amount = offsets->locals_base - offsets->saved_regs;
}
+ gcc_assert (amount >= 0);
if (amount)
{
if (amount < 512)