During the discussion session on Friday, Jan 25th, Prof. Yee talked about the "Register Windows" concept that is specific to SPARC processors. He also introduced Register Spilling. Also see what all this means to you?
Here is a tutorial on SPARC Architecture. Chapter 11 of the tutorial talks in depth about Register Windows. Chapter 12 of the tutorial talks about SPARC Stack discipline and standard calling conventions. These chapters supply enough information to help you solve Assignment1.
1) The author of these pages imagines the stack as growing upward rather than growing downward. This should not confuse you because, other than the visualization aspect nothing else changes from what was discussed in the class. The stack still grows from addresses with larger numbers to addresses with smaller numbers.
2) In section 11.3.3, there is an error when the author says:"The restore operation deallocates a register set by decrementing the CWP". Instead it should be :"The restore operation deallocates a register set by incrementing the CWP".
3) The first slice of the stack shown in Figure 12.2 should read "space for %i0-%i7 and %l0-%l7".
Now, what remains to be done is to find the number of register windows in the SPARC processor of ieng9.ucsd.edu. You will be notified very soon.
As the register windows are allocated to called procedures and to procedures that they might call, it is possible that the register windows get exhausted. Under such circumstances the contents of the previous registers are stored onto their stack frames (see section 12.3.3) and this is called register spilling.
What does all this mean to you?
The return address is typically a register. A return is supposed to jump through the address in the register. Given the SPARC architecture, our best bets for a successful buffer overflow attack are on the return address of that function whose registers have spilled onto the stack and hence are susceptible to change.
Suppose there are two register windows. Suppose there are four functions: main( ), fn1( ), fn2 and fn3( ) in a program such that main( ) calls fn1( ), fn1( ) calls fn2( ) and fn2( ) calls fn3( ). If we try to change the return address of fn3 ( returning to fn2), then the chances are that fn2 might not have had a register spill yet. But functions like fn1 or main which are placed higher in the stack ( address with larger number ) might have had a register spill. So the bottom line is that the higher in the stack ( address with larger number ) the attack is launched the more the chances of success.