[uClinux-dev] __stack_start for ColdFire uClinux

Larry Baker baker at usgs.gov
Wed Sep 26 16:25:04 EDT 2012


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:     gerg at 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
baker at usgs.gov

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.uclinux.org/pipermail/uclinux-dev/attachments/20120926/da5cbde0/attachment.html>


More information about the uClinux-dev mailing list