Module Name: src
Committed By: maxv
Date: Fri Nov 2 08:59:59 UTC 2018
Modified Files:
src/sys/ddb: db_proc.c
Log Message:
Don't overflow on the strings we read. Introduce db_read_string(), which
stops on '\0'. Probably this doesn't matter a lot because the read is
supposed to be safe, but let's not have bugs in the debugger.
Detected by kASan, via skrll@ on aarch64, by typing "ps/l" on DDB.
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/ddb/db_proc.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/ddb/db_proc.c
diff -u src/sys/ddb/db_proc.c:1.6 src/sys/ddb/db_proc.c:1.7
--- src/sys/ddb/db_proc.c:1.6 Sun Oct 23 13:30:20 2011
+++ src/sys/ddb/db_proc.c Fri Nov 2 08:59:59 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: db_proc.c,v 1.6 2011/10/23 13:30:20 jym Exp $ */
+/* $NetBSD: db_proc.c,v 1.7 2018/11/02 08:59:59 maxv Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_proc.c,v 1.6 2011/10/23 13:30:20 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_proc.c,v 1.7 2018/11/02 08:59:59 maxv Exp $");
#ifndef _KERNEL
#include <stdbool.h>
@@ -107,6 +107,18 @@ db_proc_find(pid_t pid)
return NULL;
}
+static void
+db_read_string(const char *src, size_t len, char *dst)
+{
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ db_read_bytes((db_addr_t)&src[i], 1, &dst[i]);
+ if (src[i] == '\0')
+ break;
+ }
+}
+
void
db_show_all_procs(db_expr_t addr, bool haddr, db_expr_t count,
const char *modif)
@@ -176,8 +188,9 @@ db_show_all_procs(db_expr_t addr, bool h
case 'l':
while (lp != NULL) {
if (l.l_name != NULL) {
- db_read_bytes((db_addr_t)l.l_name,
+ db_read_string(l.l_name,
MAXCOMLEN, db_nbuf);
+ db_nbuf[MAXCOMLEN] = '\0';
} else {
strlcpy(db_nbuf, p.p_comm,
sizeof(db_nbuf));
@@ -191,8 +204,9 @@ db_show_all_procs(db_expr_t addr, bool h
} else
cpuno = -1;
if (l.l_wchan && l.l_wmesg) {
- db_read_bytes((db_addr_t)l.l_wmesg,
- sizeof(wbuf), (char *)wbuf);
+ db_read_string(l.l_wmesg,
+ sizeof(wbuf), wbuf);
+ wbuf[MAXCOMLEN] = '\0';
} else {
wbuf[0] = '\0';
}
@@ -212,8 +226,9 @@ db_show_all_procs(db_expr_t addr, bool h
db_read_bytes((db_addr_t)p.p_pgrp, sizeof(pgrp),
(char *)&pgrp);
if (lp != NULL && l.l_wchan && l.l_wmesg) {
- db_read_bytes((db_addr_t)l.l_wmesg,
- sizeof(wbuf), (char *)wbuf);
+ db_read_string(l.l_wmesg,
+ sizeof(wbuf), wbuf);
+ wbuf[MAXCOMLEN] = '\0';
} else {
wbuf[0] = '\0';
}
@@ -232,8 +247,9 @@ db_show_all_procs(db_expr_t addr, bool h
case 'w':
while (lp != NULL) {
if (l.l_wchan && l.l_wmesg) {
- db_read_bytes((db_addr_t)l.l_wmesg,
- sizeof(wbuf), (char *)wbuf);
+ db_read_string(l.l_wmesg,
+ sizeof(wbuf), wbuf);
+ wbuf[MAXCOMLEN] = '\0';
} else {
wbuf[0] = '\0';
}
@@ -241,8 +257,10 @@ db_show_all_procs(db_expr_t addr, bool h
(l.l_pflag & LP_RUNNING) != 0);
db_read_bytes((db_addr_t)&p.p_emul->e_name,
sizeof(ename), (char *)&ename);
- db_read_bytes((db_addr_t)ename,
- sizeof(db_nbuf), db_nbuf);
+
+ db_read_string(ename, sizeof(db_nbuf), db_nbuf);
+ db_nbuf[MAXCOMLEN] = '\0';
+
db_printf(
"%c%4d %16s %8s %4d %-12s %-18lx\n",
(run ? '>' : ' '), l.l_lid,
@@ -318,8 +336,8 @@ db_show_proc(db_expr_t addr, bool haddr,
db_printf("%slwp %d", (run ? "> " : " "), l.l_lid);
if (l.l_name != NULL) {
- db_read_bytes((db_addr_t)l.l_name,
- MAXCOMLEN, db_nbuf);
+ db_read_string(l.l_name, MAXCOMLEN, db_nbuf);
+ db_nbuf[MAXCOMLEN] = '\0';
db_printf(" [%s]", db_nbuf);
}
db_printf(" %lx pcb %lx\n", (long)lp, (long)l.l_addr);
@@ -334,8 +352,8 @@ db_show_proc(db_expr_t addr, bool haddr,
l.l_stat, l.l_flag, cpuno, l.l_priority);
if (l.l_wchan && l.l_wmesg) {
- db_read_bytes((db_addr_t)l.l_wmesg,
- sizeof(wbuf), (char *)wbuf);
+ db_read_string(l.l_wmesg, MAXCOMLEN, wbuf);
+ wbuf[MAXCOMLEN] = '\0';
db_printf(" wmesg %s wchan %lx\n",
wbuf, (long)l.l_wchan);
}