Gitweb: http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=66fa9b107e259d01929fe647796b3021d3a83c4a Commit: 66fa9b107e259d01929fe647796b3021d3a83c4a Parent: 9be26f4c4b138c425598bd3cc50411bd87fce287 Author: Keith Owens <[EMAIL PROTECTED]> AuthorDate: Tue Jun 26 16:25:22 2007 +1000 Committer: Tony Luck <[EMAIL PROTECTED]> CommitDate: Tue Jun 26 13:33:10 2007 -0700
[IA64] Correct unwind validation code Both rp_loc and pfs_loc can be in the register stack area _or_ they can be in the memory stack area, the latter occurs when a struct pt_regs is pushed. Correct the validation check on these fields to check for both stack areas. Not allowing for memory stack locations means no backtrace past ia64_leave_kernel, or any other code that uses PT_REGS_UNWIND_INFO. Signed-off-by: Keith Owens <[EMAIL PROTECTED]> Signed-off-by: Tony Luck <[EMAIL PROTECTED]> --- arch/ia64/kernel/unwind.c | 16 +++++++++++----- 1 files changed, 11 insertions(+), 5 deletions(-) diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index b0b08b5..c1bdb51 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c @@ -1856,11 +1856,19 @@ find_save_locs (struct unw_frame_info *info) return 0; } +static int +unw_valid(const struct unw_frame_info *info, unsigned long* p) +{ + unsigned long loc = (unsigned long)p; + return (loc >= info->regstk.limit && loc < info->regstk.top) || + (loc >= info->memstk.top && loc < info->memstk.limit); +} + int unw_unwind (struct unw_frame_info *info) { unsigned long prev_ip, prev_sp, prev_bsp; - unsigned long ip, pr, num_regs, rp_loc, pfs_loc; + unsigned long ip, pr, num_regs; STAT(unsigned long start, flags;) int retval; @@ -1871,8 +1879,7 @@ unw_unwind (struct unw_frame_info *info) prev_bsp = info->bsp; /* validate the return IP pointer */ - rp_loc = (unsigned long) info->rp_loc; - if ((rp_loc < info->regstk.limit) || (rp_loc > info->regstk.top)) { + if (!unw_valid(info, info->rp_loc)) { /* FIXME: should really be level 0 but it occurs too often. KAO */ UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n", __FUNCTION__, info->ip); @@ -1888,8 +1895,7 @@ unw_unwind (struct unw_frame_info *info) } /* validate the previous stack frame pointer */ - pfs_loc = (unsigned long) info->pfs_loc; - if ((pfs_loc < info->regstk.limit) || (pfs_loc > info->regstk.top)) { + if (!unw_valid(info, info->pfs_loc)) { UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__); STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); return -1; - To unsubscribe from this list: send the line "unsubscribe git-commits-head" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html