Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 15 Jan 2012 18:51:07 +0000 (UTC)
From:      Mikolaj Golub <trociny@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r230146 - head/lib/libkvm
Message-ID:  <201201151851.q0FIp7GC095390@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trociny
Date: Sun Jan 15 18:51:07 2012
New Revision: 230146
URL: http://svn.freebsd.org/changeset/base/230146

Log:
  In kvm_argv(), the case when the supplied buffer was too short to hold the
  requested value was handled incorrectly, and the function retuned NULL
  instead of the truncated result.
  
  Fix this and also remove unnecessary check for buf != NULL, which alway
  retuns true.
  
  MFC after:	3 days

Modified:
  head/lib/libkvm/kvm_proc.c

Modified: head/lib/libkvm/kvm_proc.c
==============================================================================
--- head/lib/libkvm/kvm_proc.c	Sun Jan 15 18:47:24 2012	(r230145)
+++ head/lib/libkvm/kvm_proc.c	Sun Jan 15 18:51:07 2012	(r230146)
@@ -658,30 +658,38 @@ kvm_argv(kvm_t *kd, const struct kinfo_p
 			buflen = nchr;
 		}
 	}
-	if (buf != NULL) {
-		oid[0] = CTL_KERN;
-		oid[1] = KERN_PROC;
-		oid[2] = env ? KERN_PROC_ENV : KERN_PROC_ARGS;
-		oid[3] = kp->ki_pid;
-		bufsz = buflen;
-		i = sysctl(oid, 4, buf, &bufsz, 0, 0);
-		if (i == 0 && bufsz > 0) {
-			i = 0;
-			p = buf;
-			do {
-				bufp[i++] = p;
-				p += strlen(p) + 1;
-				if (i >= argc) {
-					argc += argc;
-					bufp = realloc(bufp,
-					    sizeof(char *) * argc);
-				}
-			} while (p < buf + bufsz);
-			bufp[i++] = 0;
-			return (bufp);
-		}
+	oid[0] = CTL_KERN;
+	oid[1] = KERN_PROC;
+	oid[2] = env ? KERN_PROC_ENV : KERN_PROC_ARGS;
+	oid[3] = kp->ki_pid;
+	bufsz = buflen;
+	if (sysctl(oid, 4, buf, &bufsz, 0, 0) == -1) {
+		/*
+		 * If the supplied buf is too short to hold the requested
+		 * value the sysctl returns with ENOMEM. The buf is filled
+		 * with the truncated value and the returned bufsz is equal
+		 * to the requested len.
+		 */
+		if (errno != ENOMEM || bufsz != (size_t)buflen)
+			return (0);
+		buf[bufsz - 1] = '\0';
+		errno = 0;
+	} else if (bufsz == 0) {
+		return (0);
 	}
-	return (NULL);
+	i = 0;
+	p = buf;
+	do {
+		bufp[i++] = p;
+		p += strlen(p) + 1;
+		if (i >= argc) {
+			argc += argc;
+			bufp = realloc(bufp,
+			    sizeof(char *) * argc);
+		}
+	} while (p < buf + bufsz);
+	bufp[i++] = 0;
+	return (bufp);
 }
 
 char **



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201201151851.q0FIp7GC095390>