Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Why does array address in the stack change after every execution?

Reply
Thread Tools

Why does array address in the stack change after every execution?

 
 
CICAP
Guest
Posts: n/a
 
      07-16-2010
Why this simple program compiled with gcc runned on linux kernel
2.6.32 show different behavior after every execution?

int main (int argc, char **argv)
{
int a[10];
printf("%d\n", a[1000]);
return 0;
}

execution 1: 1668312366
execution 2: 0
execution 3: segmentation fault
execution 4: 0

etc...

 
Reply With Quote
 
 
 
 
Denis McMahon
Guest
Posts: n/a
 
      07-16-2010
On 16/07/10 09:44, CICAP wrote:
> Why this simple program compiled with gcc runned on linux kernel
> 2.6.32 show different behavior after every execution?
>
> int main (int argc, char **argv)
> {
> int a[10];
> printf("%d\n", a[1000]);
> return 0;
> }


You wrote a program that deliberately tries to break things, and you
want to know why you get inconsistent behaviour?

Lots of phrases come to mind, none of them particularly complimentary to
your cognitive abilities.

Rgds

Denis McMahon
 
Reply With Quote
 
 
 
 
robertwessel2@yahoo.com
Guest
Posts: n/a
 
      07-16-2010
On Jul 16, 3:44*am, CICAP <(E-Mail Removed)> wrote:
> Why this simple program compiled with gcc *runned on linux kernel
> 2.6.32 show different behavior after every execution?
>
> int main (int argc, char **argv)
> {
> * int a[10];
> * printf("%d\n", a[1000]);
> * return 0;
>
> }
>
> execution 1: 1668312366
> execution 2: 0
> execution 3: segmentation fault
> execution 4: 0
>
> etc...



Referencing past the end of an array results in undefined behavior.
Anything can happen.

Assuming the common Linux/GCC implementations, and typical downward
growing stack, you're attempting to display the contents of the memory
typically past the start of the stack. And there you entirely at the
mercy of whatever pages may or may not be allocated there, and what
they've been filed with.

And you're *not* displaying any addresses, as written the code
displays the contents of the 1001st element of the array "a" (which,
of course doesn't actually exist).
 
Reply With Quote
 
CICAP
Guest
Posts: n/a
 
      07-16-2010
On 16 Lug, 11:50, "(E-Mail Removed)" <(E-Mail Removed)>
wrote:

> > Why this simple program compiled with gcc *runned on linux kernel
> > 2.6.32 show different behavior after every execution?

>
> > int main (int argc, char **argv)
> > {
> > * int a[10];
> > * printf("%d\n", a[1000]);
> > * return 0;

>
> > }

>
> > execution 1: 1668312366
> > execution 2: 0
> > execution 3: segmentation fault
> > execution 4: 0

>
> > etc...

>
> Referencing past the end of an array results in undefined behavior.
> Anything can happen.


I know that. I was wandering because in some system the behavior is
always the same and in other systems not.

> Assuming the common Linux/GCC implementations, and typical downward
> growing stack, you're attempting to display the contents of the memory
> typically past the start of the stack. *And there you entirely at the
> mercy of whatever pages may or may not be allocated there, and what
> they've been filed with.
>
> And you're *not* displaying any addresses, as written the code
> displays the contents of the 1001st element of the array "a" (which,
> of course doesn't actually exist).


I finally discovered that it was caused by ASLR. Disabling ASLR (stack
randomization) the behavior becomes always the same.
Do you know how stack randomization work?

 
Reply With Quote
 
robertwessel2@yahoo.com
Guest
Posts: n/a
 
      07-16-2010
On Jul 16, 4:53*am, CICAP <(E-Mail Removed)> wrote:
> On 16 Lug, 11:50, "(E-Mail Removed)" <(E-Mail Removed)>
> wrote:
>
>
>
>
>
> > > Why this simple program compiled with gcc *runned on linux kernel
> > > 2.6.32 show different behavior after every execution?

>
> > > int main (int argc, char **argv)
> > > {
> > > * int a[10];
> > > * printf("%d\n", a[1000]);
> > > * return 0;

>
> > > }

>
> > > execution 1: 1668312366
> > > execution 2: 0
> > > execution 3: segmentation fault
> > > execution 4: 0

>
> > > etc...

>
> > Referencing past the end of an array results in undefined behavior.
> > Anything can happen.

>
> I know that. I was wandering because in some system the behavior is
> always the same and in other systems not.
>
> > Assuming the common Linux/GCC implementations, and typical downward
> > growing stack, you're attempting to display the contents of the memory
> > typically past the start of the stack. *And there you entirely at the
> > mercy of whatever pages may or may not be allocated there, and what
> > they've been filed with.

>
> > And you're *not* displaying any addresses, as written the code
> > displays the contents of the 1001st element of the array "a" (which,
> > of course doesn't actually exist).

>
> I finally discovered that it was caused by ASLR. Disabling ASLR (stack
> randomization) the behavior becomes always the same.
> Do you know how stack randomization work?



You know, 15 seconds with Google would have answered this for you...

But basically ASLR randomizes where things are loaded and allocated in
memory. The details are implementation specific, but commonly it
causes executables to be loaded at different locations as well as
stacks to be allocated at different locations. Often the OS memory
blocks passed to the C heap manager are subject to some randomization
as well. The idea is to make the typical stack smashing (or buffer
overflow) attacks ineffective, since it becomes very difficult to both
inject code and generate a branch to that code, or to generate a
branch to an abuseable routine in the program, since those addresses
are now unpredictable.

Unlike the traditional non-ASLR case, where you program is always
loaded at (say) 0x10000, and the first stack consistently starts just
below 0x80000000 (or wherever).

In any event, this is all OT for this group.
 
Reply With Quote
 
CICAP
Guest
Posts: n/a
 
      07-16-2010
On 16 Lug, 12:01, "(E-Mail Removed)" <(E-Mail Removed)>
wrote:

> But basically ASLR randomizes where things are loaded and allocated in
> memory.


That is what I thought reading wikipedia etc. But what I am
experimenting in Linux is strange, and I would like to know how is
possible that Stack Pointer is randomized INSIDE the stack. In your
opinion (the last question because as you said I am OT), is the
following stack scheme possible?

Execution 1: |S _ _ _ a _ |
Execution 2: |_ S _ _ _ a |

where "S" is stack poninter, and "a" the array of the example.
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-16-2010
CICAP <(E-Mail Removed)> writes:

> Why this simple program compiled with gcc runned on linux kernel
> 2.6.32 show different behavior after every execution?
>
> int main (int argc, char **argv)
> {
> int a[10];
> printf("%d\n", a[1000]);
> return 0;
> }
>
> execution 1: 1668312366
> execution 2: 0
> execution 3: segmentation fault
> execution 4: 0


From the C point of view, the program can do anything at all. The C
language does define what happens when you call printf without a valid
prototype in scope, and it does define what 'a[1000]' means when 'a' is
a ten element array.

gcc has chosen to produce a set of instructions from this invalid code
and these instructions appear to different things at different times but
all the results you see are equally "correct". You could look at the
generated instructions and study the way your version of Linux sets up
the execution environment of the program to determine exactly what the
possible range of behaviours is, but I would suggest there are better
ways to learn about C and Linux.

--
Ben.
 
Reply With Quote
 
robertwessel2@yahoo.com
Guest
Posts: n/a
 
      07-16-2010
On Jul 16, 5:12*am, CICAP <(E-Mail Removed)> wrote:
> On 16 Lug, 12:01, "(E-Mail Removed)" <(E-Mail Removed)>
> wrote:
>
> > But basically ASLR randomizes where things are loaded and allocated in
> > memory.

>
> That is what I thought reading wikipedia etc. But what I am
> experimenting in Linux is strange, and I would like to know how is
> possible that Stack Pointer is randomized INSIDE the stack. In *your
> opinion (the last question because as you said I am OT), is the
> following stack scheme possible?
>
> Execution 1: |S _ _ _ a _ |
> Execution 2: |_ S _ _ _ a |
>
> where "S" is stack poninter, and "a" the array of the example.



Well, it's dependent on exactly which ALSR implementation you're
using, but no, what happens is that the whole stack is moved. In some
implementations that's just on a page basis, so the first word* on the
stack would always be at 0xXXXXXffc, with only the page - and the
surrounding allocations being randomized - IOW, the 1MB of address
space for the stack is reserved as a sequential set of 256 page frames
somewhere in the address space, and the initial stack pointed is set
to the end of that. Others allocate a large region for the stack in a
fixed location, say 8MB, and start the stack at one of roughly half a
million possible locations - basically any multiple of sixteen at
least 1MB into that reserved area. Other implementations are possible
as well.

At least one *application* that I'm aware of has implemented partial
ALSR by doing a random sized alloca() at startup, which would more or
less match what you described, but I don't know of any OS's that have
implemented it that way.


*assuming a 32 bit machine with a downward growing stack
 
Reply With Quote
 
Mark Bluemel
Guest
Posts: n/a
 
      07-16-2010
On 16 July, 11:12, CICAP <(E-Mail Removed)> wrote:
> ... what I am
> experimenting in Linux is strange, and I would like to know how is
> possible that Stack Pointer is randomized INSIDE the stack. In *your
> opinion (the last question because as you said I am OT), is the
> following stack scheme possible?
>
> Execution 1: |S _ _ _ a _ |
> Execution 2: |_ S _ _ _ a |
>
> where "S" is stack poninter, and "a" the array of the example.


Try this thought experiment. Would my question be significantly
different if my program were written in C++, fortran, haskell or
brainf*ck?

As the answer is "no", then you are clearly off-topic. If you can't
find the documentation for the Linux implementation of ASLR that you
are using, I suggest asking somewhere like comp.unix.programmer as a
starting point.

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      07-16-2010
Ben Bacarisse <(E-Mail Removed)> writes:
[...]
> From the C point of view, the program can do anything at all. The C
> language does define what happens when you call printf without a valid
> prototype in scope, and it does define what 'a[1000]' means when 'a' is
> a ten element array.


I think you mean "does not define" in both cases.

[...]

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Why does std::stack::pop() not throw an exception if the stack is empty? Debajit Adhikary C++ 36 02-10-2011 08:54 PM
C/C++ compilers have one stack for local variables and return addresses and then another stack for array allocations on the stack. Casey Hawthorne C Programming 3 11-01-2009 08:23 PM
Why stack overflow with such a small stack? Kenneth McDonald Ruby 7 09-01-2007 04:21 AM
findcontrol("PlaceHolderPrice") why why why why why why why why why why why Mr. SweatyFinger ASP .Net 2 12-02-2006 03:46 PM
A Paradise DNS address change? What change? There was no change. Tony Neville NZ Computing 7 09-22-2006 01:02 PM



Advertisments