Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
ddb machine sysregs overflow
To:
tech@openbsd.org
Date:
Wed, 12 Feb 2025 18:14:03 +0100

Download raw body.

Thread
  • Alexander Bluhm:

    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 */