DragonFlyBSD Kernel Audit
DF-0935 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/vfs/procfs/procfs_rlimit.c b/sys/vfs/procfs/procfs_rlimit.c
--- a/sys/vfs/procfs/procfs_rlimit.c
+++ b/sys/vfs/procfs/procfs_rlimit.c
@@ -58,15 +58,18 @@
 {
 	struct proc *p = lp->lwp_proc;
 	size_t xlen;
+	size_t remain;
 	char *ps;
 	int error;
 	int i;
+	int n;
 	char psbuf[512];		/* XXX - conservative */
 
 	if (uio->uio_rw != UIO_READ)
 		return (EOPNOTSUPP);
 
 	ps = psbuf;
+	remain = sizeof(psbuf);
 
 	for (i = 0; i < RLIM_NLIMITS; i++) {
 
@@ -74,7 +77,13 @@
 		 * Add the rlimit ident
 		 */
 
-		ps += ksprintf(ps, "%s ", rlimit_ident[i]);
+		n = ksnprintf(ps, remain, "%s ", rlimit_ident[i]);
+		if (n < 0 || (size_t)n >= remain) {
+			error = ENOMEM;
+			goto bailout;
+		}
+		ps += n;
+		remain -= n;
 
 		/*
 		 * Replace RLIM_INFINITY with -1 in the string
@@ -85,27 +94,38 @@
 		 */
 
 		if (p->p_rlimit[i].rlim_cur == RLIM_INFINITY) {
-			ps += ksprintf(ps, "-1 ");
+			n = ksnprintf(ps, remain, "-1 ");
 		} else {
-			ps += ksprintf(ps, "%llu ",
-				(unsigned long long)p->p_rlimit[i].rlim_cur);
+			n = ksnprintf(ps, remain, "%llu ",
+			    (unsigned long long)p->p_rlimit[i].rlim_cur);
+		}
+		if (n < 0 || (size_t)n >= remain) {
+			error = ENOMEM;
+			goto bailout;
 		}
+		ps += n;
+		remain -= n;
 
 		/*
 		 * maximum limit
 		 */
 
 		if (p->p_rlimit[i].rlim_max == RLIM_INFINITY) {
-			ps += ksprintf(ps, "-1\n");
+			n = ksnprintf(ps, remain, "-1\n");
 		} else {
-			ps += ksprintf(ps, "%llu\n",
-				(unsigned long long)p->p_rlimit[i].rlim_max);
+			n = ksnprintf(ps, remain, "%llu\n",
+			    (unsigned long long)p->p_rlimit[i].rlim_max);
+		}
+		if (n < 0 || (size_t)n >= remain) {
+			error = ENOMEM;
+			goto bailout;
 		}
+		ps += n;
+		remain -= n;
 	}
 
 	xlen = ps - psbuf;
 	error = uiomove_frombuf(psbuf, xlen, uio);
-
+bailout:
 	return (error);
 }
-