From 85c8db77a99a10c2a8b1d9dd1efe8d4af17f99f0 Mon Sep 17 00:00:00 2001 From: sashan Date: Sun, 3 Aug 2025 11:17:08 +0000 Subject: [PATCH] Do a btrace(8) favor: don't feed it with invalid instruction address. OK kettenis@ --- sys/arch/amd64/amd64/db_trace.c | 14 ++++++++++++-- sys/arch/i386/i386/db_trace.c | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/sys/arch/amd64/amd64/db_trace.c b/sys/arch/amd64/amd64/db_trace.c index 5279024e04d..517870306f9 100644 --- a/sys/arch/amd64/amd64/db_trace.c +++ b/sys/arch/amd64/amd64/db_trace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_trace.c,v 1.59 2025/08/02 19:22:18 sashan Exp $ */ +/* $OpenBSD: db_trace.c,v 1.60 2025/08/03 11:17:08 sashan Exp $ */ /* $NetBSD: db_trace.c,v 1.1 2003/04/26 18:39:27 fvdl Exp $ */ /* @@ -319,8 +319,18 @@ stacktrace_save_utrace(struct stacktrace *st) st->st_pc[st->st_count++] = lastframe->f_retaddr; while (frame != NULL && st->st_count < STACKTRACE_MAX) { - if (copyin(frame, &f, sizeof(f)) != 0) + if (copyin(frame, &f, sizeof(f)) != 0) { + /* + * If the frame pointer read from the previous frame + * is invalid, assume the return address we read + * from that frame is invalid as well. + */ + if (st->st_count == 0) + st->st_pc[0] = 0; + else + st->st_count--; break; + } st->st_pc[st->st_count++] = f.f_retaddr; frame = f.f_frame; } diff --git a/sys/arch/i386/i386/db_trace.c b/sys/arch/i386/i386/db_trace.c index 140ba9eca33..da4b67ecbc7 100644 --- a/sys/arch/i386/i386/db_trace.c +++ b/sys/arch/i386/i386/db_trace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_trace.c,v 1.49 2025/08/02 19:22:18 sashan Exp $ */ +/* $OpenBSD: db_trace.c,v 1.50 2025/08/03 11:17:08 sashan Exp $ */ /* $NetBSD: db_trace.c,v 1.18 1996/05/03 19:42:01 christos Exp $ */ /* @@ -318,8 +318,18 @@ stacktrace_save_utrace(struct stacktrace *st) st->st_pc[st->st_count++] = lastframe->f_retaddr; while (frame != NULL && st->st_count < STACKTRACE_MAX) { - if (copyin(frame, &f, sizeof(f)) != 0) + if (copyin(frame, &f, sizeof(f)) != 0) { + /* + * If the frame pointer read from the previous frame + * is invalid, assume the return address we read + * from that frame is invalid as well. + */ + if (st->st_count == 0) + st->st_pc[0] = 0; + else + st->st_count--; break; + } st->st_pc[st->st_count++] = f.f_retaddr; frame = f.f_frame; }