From: Alexander Bluhm Subject: ddb machine sysregs overflow To: tech@openbsd.org Date: Wed, 12 Feb 2025 18:14:03 +0100 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 #include #include +#include #include #include @@ -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 */