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);
 		}

Reply via email to