Index: arch/riscv/riscv/db_disasm.c =================================================================== RCS file: /cvsroot/src/sys/arch/riscv/riscv/db_disasm.c,v retrieving revision 1.4 diff -u -p -r1.4 db_disasm.c --- arch/riscv/riscv/db_disasm.c 19 Apr 2021 07:55:59 -0000 1.4 +++ arch/riscv/riscv/db_disasm.c 23 May 2021 22:26:16 -0000 @@ -39,6 +39,7 @@ __RCSID("$NetBSD: db_disasm.c,v 1.4 2021 #include #include +#include #include #include #include @@ -1484,23 +1485,16 @@ db_disasm(db_addr_t loc, bool altfmt) unsigned n, i; uint32_t insn32; -#ifdef _KERNEL - if ((intptr_t) loc >= 0) { - db_printf("%s: %#"PRIxVADDR" is not a kernel address\n", - __func__, loc); - return loc; - } -#endif - /* * Fetch the instruction. The first halfword tells us how many * more there are, and they're always in little-endian order. */ - insn[0] = ((const uint16_t *)loc)[0]; + db_read_bytes(loc, sizeof(insn[0]), (void *)&insn[0]); n = INSN_HALFWORDS(insn[0]); KASSERT(n > 0 && n <= 5); for (i = 1; i < n; i++) { - insn[i] = ((const uint16_t *)loc)[i]; + db_read_bytes(loc + i * sizeof(insn[i]), sizeof(insn[i]), + (void *)&insn[i]); } switch (n) { Index: arch/riscv/riscv/db_machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/riscv/riscv/db_machdep.c,v retrieving revision 1.7 diff -u -p -r1.7 db_machdep.c --- arch/riscv/riscv/db_machdep.c 14 Apr 2021 06:32:20 -0000 1.7 +++ arch/riscv/riscv/db_machdep.c 23 May 2021 22:26:16 -0000 @@ -42,6 +42,7 @@ __RCSID("$NetBSD: db_machdep.c,v 1.7 202 #include #include #include +#include int db_active = 0; @@ -225,6 +226,19 @@ void db_read_bytes(db_addr_t addr, size_t len, char *data) { const char *src = (char *)addr; + int err; + + /* If asked to fetch from userspace, do it safely */ + if ((intptr_t)addr >= 0) { + err = copyin(src, data, len); + if (err) { +#ifdef DDB + db_printf("address %p is invalid\n", src); +#endif + memset(data, 0, len); + } + return; + } while (len--) { *data++ = *src++; @@ -237,6 +251,19 @@ db_read_bytes(db_addr_t addr, size_t len void db_write_bytes(vaddr_t addr, size_t len, const char *data) { + int err; + + /* If asked to fetch from userspace, do it safely */ + if ((intptr_t)addr >= 0) { + err = copyout(data, (char *)addr, len); + if (err) { +#ifdef DDB + db_printf("address %p is invalid\n", (char *)addr); +#endif + } + return; + } + if (len == 8) { *(uint64_t *)addr = *(const uint64_t *) data; } else if (len == 4) { @@ -244,6 +271,7 @@ db_write_bytes(vaddr_t addr, size_t len, } else if (len == 2) { *(uint16_t *)addr = *(const uint16_t *) data; } else { + KASSERT(len == 1); *(uint8_t *)addr = *(const uint8_t *) data; } __asm("fence rw,rw; fence.i"); Index: arch/mips/mips/db_disasm.c =================================================================== RCS file: /cvsroot/src/sys/arch/mips/mips/db_disasm.c,v retrieving revision 1.33 diff -u -p -r1.33 db_disasm.c --- arch/mips/mips/db_disasm.c 17 Aug 2020 03:14:08 -0000 1.33 +++ arch/mips/mips/db_disasm.c 23 May 2021 22:26:16 -0000 @@ -47,6 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: db_disasm.c, #include +#include #include #include #include @@ -226,19 +227,14 @@ db_disasm(db_addr_t loc, bool altfmt) /* * Take some care with addresses to not UTLB here as it * loses the current debugging context. KSEG2 not checked. + * Update: db_read_bytes is supposed to do that, and now + * does, so we can use that. + * + * XXX db_read_bytes_can't return failure but instead zeros + * the output. That's ok here, but if ever improved the + * proper thing here on error is to return the original loc. */ - if (loc < (db_addr_t)MIPS_KSEG0_START) { -#ifdef _KERNEL - if (ufetch_32((void *)loc, &instr) != 0) { - db_printf("invalid address.\n"); - return loc; - } -#else - return loc; -#endif - } else { - instr = *(uint32_t *)loc; - } + db_read_bytes(loc, sizeof(instr), (void *)&instr); return (db_disasm_insn(instr, loc, altfmt)); } Index: arch/mips/mips/db_interface.c =================================================================== RCS file: /cvsroot/src/sys/arch/mips/mips/db_interface.c,v retrieving revision 1.92 diff -u -p -r1.92 db_interface.c --- arch/mips/mips/db_interface.c 23 Feb 2021 07:13:52 -0000 1.92 +++ arch/mips/mips/db_interface.c 23 May 2021 22:26:16 -0000 @@ -178,6 +178,19 @@ void db_read_bytes(vaddr_t addr, size_t size, char *data) { const char *src = (char *)addr; + int err; + + /* If asked to fetch from userspace, do it safely */ + if (addr < (vaddr_t)MIPS_KSEG0_START) { + err = copyin(src, data, size); + if (err) { +#ifdef DDB + db_printf("address %p is invalid\n", src); +#endif + memset(data, 0, size); + } + return; + } if (size <= 8 && (size & (size-1)) == 0 && (addr & (size-1)) == 0 && ((uintptr_t)data & (size-1)) == 0) { @@ -203,6 +216,18 @@ db_write_bytes(vaddr_t addr, size_t size { char *p = (char *)addr; size_t n = size; + int err; + + /* If asked to fetch from userspace, do it safely */ + if (addr < (vaddr_t)MIPS_KSEG0_START) { + err = copyout(data, p, size); + if (err) { +#ifdef DDB + db_printf("address %p is invalid\n", p); +#endif + } + return; + } if (size <= 8 && (size & (size-1)) == 0 && (addr & (size-1)) == 0 && ((uintptr_t)data & (size-1)) == 0) {