Re: __stack_start for ColdFire uClinux

Larry Baker <[email protected]>
Newsgroups gmane.linux.uclinux.devel
Message-ID <[email protected]>
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:     [email protected]
> 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
[email protected]

_______________________________________________
uClinux-dev mailing list
[email protected]
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by [email protected]
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.