Download raw body.
ddb machine sysregs overflow
Hi,
In 64-bit mode, the operand size of SIDT and SGDT instructions is
8+2 bytes. On amd64 ddb command 'machine sysregs' reserved only
int64_t, resulting in a stack overflow. Use struct region_descriptor
which has the correct memory layout for IDTR and GDTR.
Also call db_sysregs_cmd() with single processor kernel, the #ifdef
MULTIPROCESSOR looks like an oversight.
ok?
bluhm
Index: arch/amd64/amd64/db_interface.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/arch/amd64/amd64/db_interface.c,v
diff -u -p -r1.39 db_interface.c
--- arch/amd64/amd64/db_interface.c 14 Apr 2022 19:47:10 -0000 1.39
+++ arch/amd64/amd64/db_interface.c 12 Feb 2025 16:26:28 -0000
@@ -48,6 +48,7 @@
#include <machine/i82093var.h>
#include <machine/atomic.h>
#include <machine/specialreg.h>
+#include <machine/segments.h>
#include <ddb/db_sym.h>
#include <ddb/db_command.h>
@@ -165,16 +166,16 @@ db_ktrap(int type, int code, db_regs_t *
void
db_sysregs_cmd(db_expr_t addr, int have_addr, db_expr_t count, char *modif)
{
- int64_t idtr, gdtr;
+ struct region_descriptor idtr, gdtr;
uint64_t cr;
uint16_t ldtr, tr;
uint64_t gsb;
__asm__ volatile("sidt %0" : "=m" (idtr));
- db_printf("idtr: 0x%08llx/%04llx\n", idtr >> 16, idtr & 0xffff);
+ db_printf("idtr: 0x%08llx/%04x\n", idtr.rd_base, idtr.rd_limit);
__asm__ volatile("sgdt %0" : "=m" (gdtr));
- db_printf("gdtr: 0x%08llx/%04llx\n", gdtr >> 16, gdtr & 0xffff);
+ db_printf("gdtr: 0x%08llx/%04x\n", gdtr.rd_base, gdtr.rd_limit);
__asm__ volatile("sldt %0" : "=g" (ldtr));
db_printf("ldtr: 0x%04x\n", ldtr);
@@ -409,8 +410,8 @@ const struct db_command db_machine_comma
{ "startcpu", db_startproc_cmd, 0, 0 },
{ "stopcpu", db_stopproc_cmd, 0, 0 },
{ "ddbcpu", db_ddbproc_cmd, 0, 0 },
- { "sysregs", db_sysregs_cmd, 0, 0 },
#endif
+ { "sysregs", db_sysregs_cmd, 0, 0 },
#if NACPI > 0
{ "acpi", NULL, 0, db_acpi_cmds },
#endif /* NACPI > 0 */
ddb machine sysregs overflow