diff options
author | Mark Kettenis <kettenis@gnu.org> | 2004-01-31 15:42:24 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2004-01-31 15:42:24 +0000 |
commit | 42cdca6c41821c5fc201c915441d51ca11377b1e (patch) | |
tree | ac462294ff0c27b615ee36d3bcfd320d3108c6a4 /gdb | |
parent | 53904d1e5f3bd49eb1c0a8cd11db85c702f69e6c (diff) | |
download | gdb-42cdca6c41821c5fc201c915441d51ca11377b1e.zip gdb-42cdca6c41821c5fc201c915441d51ca11377b1e.tar.gz gdb-42cdca6c41821c5fc201c915441d51ca11377b1e.tar.bz2 |
* sparc-tdep.c (sparc_fetch_wcookie): New function.
(sparc32_frame_prev_register): Handle StackGhost.
(sparc_supply_rwindow, sparc_collect_rwindow): Likewise.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/sparc-tdep.c | 85 |
2 files changed, 91 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ade8531..720dc80 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2004-01-31 Mark Kettenis <kettenis@gnu.org> + + * sparc-tdep.c (sparc_fetch_wcookie): New function. + (sparc32_frame_prev_register): Handle StackGhost. + (sparc_supply_rwindow, sparc_collect_rwindow): Likewise. + 2004-01-29 Roland McGrath <roland@redhat.com> * configure.in (NEW_PROC_API): Also match solaris2.9 for this test. diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index f8adccc..1719109 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -106,6 +106,48 @@ sparc_fetch_instruction (CORE_ADDR pc) return insn; } + +/* OpenBSD/sparc includes StackGhost, which according to the author's + website http://stackghost.cerias.purdue.edu "... transparently and + automatically protects applications' stack frames; more + specifically, it guards the return pointers. The protection + mechanisms require no application source or binary modification and + imposes only a negligible performance penalty." + + The same website provides the following description of how + StackGhost works: + + "StackGhost interfaces with the kernel trap handler that would + normally write out registers to the stack and the handler that + would read them back in. By XORing a cookie into the + return-address saved in the user stack when it is actually written + to the stack, and then XOR it out when the return-address is pulled + from the stack, StackGhost can cause attacker corrupted return + pointers to behave in a manner the attacker cannot predict. + StackGhost can also use several unused bits in the return pointer + to detect a smashed return pointer and abort the process." + + For GDB this means that whenever we're reading %i7 from a stack + frame's window save area, we'll have to XOR the cookie. + + More information on StackGuard can be found on in: + + Mike Frantzen and Mike Shuey. "StackGhost: Hardware Facilitated + Stack Protection." 2001. Published in USENIX Security Symposium + '01. */ + +/* Fetch StackGhost Per-Process XOR cookie. */ + +ULONGEST +sparc_fetch_wcookie (void) +{ + /* FIXME: kettenis/20040131: We should fetch the cookie from the + target. For now, return zero, which is right for targets without + StackGhost. */ + return 0; +} + + /* Return the contents if register REGNUM as an address. */ static CORE_ADDR @@ -666,6 +708,29 @@ sparc32_frame_prev_register (struct frame_info *next_frame, void **this_cache, return; } + /* Handle StackGhost. */ + { + ULONGEST wcookie = sparc_fetch_wcookie (); + + if (wcookie != 0 && !cache->frameless_p && regnum == SPARC_I7_REGNUM) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + CORE_ADDR addr = cache->base + (regnum - SPARC_L0_REGNUM) * 4; + ULONGEST i6; + + /* Read the value in from memory. */ + i6 = get_frame_memory_unsigned (next_frame, addr, 4); + store_unsigned_integer (valuep, 4, i6 ^ wcookie); + } + return; + } + } + /* The previous frame's `local' and `in' registers have been saved in the register save area. */ if (!cache->frameless_p @@ -1163,6 +1228,16 @@ sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum) { target_read_memory (sp + ((i - SPARC_L0_REGNUM) * 4), buf + offset, 4); + + /* Handle StackGhost. */ + if (i == SPARC_I7_REGNUM) + { + ULONGEST wcookie = sparc_fetch_wcookie (); + ULONGEST i6 = extract_unsigned_integer (buf + offset, 4); + + store_unsigned_integer (buf + offset, 4, i6 ^ wcookie); + } + regcache_raw_supply (regcache, i, buf); } } @@ -1206,6 +1281,16 @@ sparc_collect_rwindow (const struct regcache *regcache, if (regnum == -1 || regnum == SPARC_SP_REGNUM || regnum == i) { regcache_raw_collect (regcache, i, buf); + + /* Handle StackGhost. */ + if (i == SPARC_I7_REGNUM) + { + ULONGEST wcookie = sparc_fetch_wcookie (); + ULONGEST i6 = extract_unsigned_integer (buf + offset, 4); + + store_unsigned_integer (buf + offset, 4, i6 ^ wcookie); + } + target_write_memory (sp + ((i - SPARC_L0_REGNUM) * 4), buf + offset, 4); } |