Looping forever,can this be right?

Alex gcc-help@alex.gotdns.org
Sat Mar 11 15:27:00 GMT 2006


On x86 (and probably most other PCs),  data and program memory occupy the 
same address space.

The (virtual) memory is divded into 4096 byte (pages) frames. 
Segmentation faults only occur when a program accesses an address outside 
its valid page set.

The runtime stack holds the local variables that are used in a function. 
The SAME stack also holds the arguments passed to a function and the 
return address (for when the function ends).

If you write outside the bounds of an array on the stack,  you will likely 
overwrite the return address part.   Which means when the function ends, 
it will not return to where you expected.  Basically, if you write outside 
ANY array in a C/C++ program,  you cannot expect it to work correctly -- 
even if just a single element is incorrectly written.  (Off-by-one errors 
can be really nasty)

This is how the so-called "buffer-overflow" attacks work.  They manage to 
inject and execute executable code in this manner.  Do a google search on 
"Stack smashing for fun and profit"...  Sadly, I think many C programmers 
still don't know about this.

If you want to make sure a program segfaults when an invalid array index 
is accessed,  then do a READ and not a WRITE to that array.  This will not 
affect program stability but will have the intended affect.

-Alex

On Sat, 11 Mar 2006, Petur Thors wrote:

> Hi Sven.
> Yes I was doing the out of bound error on purpose, I was making sure it
> segfaulted, but this forever looping thing was not what I was expecting.
> The i loopcounter variable should not be affected by a[i] = 1 (which
> doesn't happen in a[i] = 11) but it seems to reset itself! This is very
> strange.
> It would be brilliant if someone could explain this totally different
> behavior depending on using a[i] = 1 (forever loop) or a[i] = 11
> (segfaults after 1531 loops) in the body of the for-loop.
> Thanks very much.
> Petur
>
> Sven Eschenberg wrote:
>
>>  Hi Petur,
>>
>>  This might look strange, but did you realize you are creating a buffer
>>  overflow (out of bound error) and thus I would expect a completely
>>  undefined behavior ... segfaulting really makes sense ... if you ask me
>>  ...
>>
>>  Regards
>>
>>  -Sven
>> 
>>
>>  Petur Thors wrote:
>> 
>> >  Hi
>> >  Please correct me if I'm totally lost here , but compiling this program 
>> >  (a.c)  with gcc -Wall -pedantic -o a a.c :
>> > 
>> >  #include <stdio.h>
>> >  int main(int argc,char **argv)
>> >  {
>> >     int i;
>> >     int a[10];
>> >     for(i = 0; i < 2000; i++) {
>> >         printf("a[%d] is %d\n",i,a[i]);
>> >         a[i] = 1;
>> >     }
>> >     return 0;
>>> }
>> > 
>> > 
>> >  and running it i get :
>> > 
>> >  a[0] is 0
>> >  a[1] is 0
>> >  a[2] is -2146329632
>> >  a[3] is 51
>> >  a[4] is 4195584
>> >  a[5] is 0
>> >  a[6] is 4195312
>> >  a[7] is 0
>> >  a[8] is -4327808
>> >  a[9] is 32767
>> >  a[10] is 0
>> >  a[11] is 11
>> >  a[2] is 1
>> >  a[3] is 1
>> >  a[4] is 1
>> >  a[5] is 1
>> >  a[6] is 1
>> >  a[7] is 1
>> >  a[8] is 1
>> >  a[9] is 1
>> >  a[10] is 1
>> >  a[11] is 11
>> >  a[2] is 1
>> >  a[3] is 1
>> >  a[4] is 1
>> >  a[5] is 1
>> >  a[6] is 1
>> >  a[7] is 1
>> >  ....
>> >  looping forever and ever........
>> > 
>> >  But when I change a[i] = 1 to a[i] = 11 (in the for loop) it segfaults 
>> >  at i = 1532.
>> > 
>> >  Please forgive me if I'm totally missing something obvious here but can 
>> >  this be correct ?
>> > 
>> >  gcc specs:
>> > 
>> >  Using built-in specs.
>> >  Target: x86_64-redhat-linux
>> >  Configured with: ../configure --prefix=/usr --mandir=/usr/share/man 
>> >  --infodir=/usr/share/info --enable-shared --enable-threads=posix 
>> >  --enable-checking=release --with-system-zlib --enable-__cxa_atexit 
>> >  --disable-libunwind-exceptions --enable-libgcj-multifile 
>> >  --enable-languages=c,c++,objc,java,f95,ada --enable-java-awt=gtk 
>> >  --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre 
>> >  --host=x86_64-redhat-linux
>> >  Thread model: posix
>> >  gcc version 4.0.2 20051125 (Red Hat 4.0.2-8)
>> >  Updated Fedora core 4
>> > 
>> >  Thanks in advance and best regards
>> >  Petur
>> > 
>> > 
>> 
>> 
>
>
>



More information about the Gcc-help mailing list