Greg,

> Hi Larry,
> 
> On 09/26/2012 12:49 PM, Larry Baker wrote:
>> I have been chasing what I suspect are stack overflows in NTP.  I spotted 
>> mention of that there was a gcc option, -fstack-check-symbol=__stack_start, 
>> for run-time stack checking on uClinux.  I tried that, but it caused an 
>> internal compiler error.  My development environment is the Sourcery (now 
>> Mentor Graphics) CodeBench Lite for ColdFire uClinux SDK.  I modified their 
>> GCC source to add support for -fstack-limit-symbol.  Unfortunately, using 
>> the __stack_start symbol to detect stack overflow does not seem to be 
>> working out.  For my test uClinux executable, stack-overflow.c:
>> 
>> #include <stdio.h>
>> 
>> void overflow( int i ) {
>> 
>> /* Allocate automatic array j[256] so stack limit checking works. */
>> 
>>    int j[256];
>> 
>> /* Stack limit checking tests only whether the stack is large enough for  */
>> /* the initial stack allocation: saved registers and automatic variables. */
>> /* Stack limit checking does not test for stack overflow in the body of a */
>> /* function.  That is what happens when j[] is not present.  When j[] is  */
>> /* too large, the program will abnormally terminate on its own (illegal   */
>> /* instruction trap?).  j[256] works.                                     */
>> 
>>    i++;
>>    printf( "i = %i\n", i );
>>    overflow( i );
>> 
>> }
>> 
>> int main() {
>> 
>>    overflow( 0 );
>> 
>>    return 0;
>> 
>> }
>> 
>> the stack is allocated 4K (0x1000).
> 
> How are you setting the app stack size?

I take the default.  I build two images: one with and one without 
-fstack-limit-symbol=__stack_start:

# toolchains/freescale-coldfire-2011.09-patched/bin/m68k-uclinux-gcc -mcpu=5208 
-fomit-frame-pointer -fno-common -fno-builtin -fno-dwarf2-cfi-asm -msep-data -o 
no-check-stack-overflow stack-overflow.c
 
# toolchains/freescale-coldfire-2011.09-patched/bin/m68k-uclinux-gcc -mcpu=5208 
-fomit-frame-pointer -fno-common -fno-builtin -fno-dwarf2-cfi-asm -msep-data 
-fstack-limit-symbol=__stack_start -o check-stack-overflow stack-overflow.c

The executable says the stack size is 0x1000:

# toolchains/freescale-coldfire-2011.09-patched/bin/m68k-uclinux-flthdr -p 
check-stack-overflow
check-stack-overflow
    Magic:        bFLT
    Rev:          4
    Build Date:   Wed Sep 26 11:54:28 2012
    Entry:        0x44
    Data Start:   0x3c60
    Data End:     0x44e4
    BSS End:      0x6590
    Stack Size:   0x1000
    Reloc Start:  0x44e4
    Reloc Count:  0x29
    Flags:        0x2 ( Has-PIC-GOT )

> 
>> When I hacked the .s file to print out the stack pointer and __stack start, 
>> it shows that there is more than 4K between the value in the stack pointer 
>> and __stack_start:
>> 
>> %sp = 0x405f3ee4
>> __stack_start = 0x405f08b4
>> 
>> That is not what I was expecting.
>> 
> 
> This is a little deceptive, and not completely accurate in general.
> 
> If you look at what binfmt_flat.c does when loading a flat format file
> you will see that that point is labeled the start of the "brk" region.
> When allocating the memory for the process (text, data, stack) we may
> get a larger region than requested(1). We use the extra space if we get
> it, and that will push the stack further away from the end of the data
> region if we do. This is probably what you are seeing.

If this were the case, __stack_start would still be an accurate value for 
detecting stack overrun.  I see signs of stack overrun before the stack check 
trips.  When I force a trap (trap #7), I get no messages from the O/S on the 
console, and the shell prompt reappears.  (Should I see something?  Is there a 
kernel build option I should enable?)  When I run my stack checking test 
program with j[32], the hardware watchdog timer trips.  I'll have to hack the 
.s file some more to print out __stack_start and %sp when this happens.  
Perhaps the stack check for j[32] (128 bytes) passes, but the printf library 
routine is using more stack and is actually causing the system failure.

There should be nothing but stack between __stack_start and the end of the 
region, where the initial %sp points, correct?  If not, I can't use 
__stack_start as a sentinel.

> A little trace
> in binfmt_flat.c will let you see the exact regions and addresses you
> are getting on process start.
> 
> (1) Page aligning or buddy allocator rounding means we may get a bit
>    more, or even potentially a lot more.
> 
> Regards
> Greg
> 
> 
> ------------------------------------------------------------------------
> Greg Ungerer  --  Principal Engineer        EMAIL:     g...@snapgear.com
> SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
> 8 Gardner Close,                            FAX:         +61 7 3891 3630
> Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com


Larry Baker
US Geological Survey
650-329-5608
ba...@usgs.gov

_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev

Reply via email to