summaryrefslogtreecommitdiffstats
path: root/lib/libkvm
diff options
context:
space:
mode:
authortrociny <trociny@FreeBSD.org>2012-01-15 18:51:07 +0000
committertrociny <trociny@FreeBSD.org>2012-01-15 18:51:07 +0000
commit1e8738d775b6c23863f028042f01eabc2ba1b535 (patch)
tree81ec27bbc5fd9f3063c5da3ecfdd8c5c5faefc03 /lib/libkvm
parentd4e71152bd70ed6531fa416c2cb7a63d7fa160d7 (diff)
downloadFreeBSD-src-1e8738d775b6c23863f028042f01eabc2ba1b535.zip
FreeBSD-src-1e8738d775b6c23863f028042f01eabc2ba1b535.tar.gz
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
Diffstat (limited to 'lib/libkvm')
-rw-r--r--lib/libkvm/kvm_proc.c54
1 files changed, 31 insertions, 23 deletions
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index d32575c..dcf034c 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -658,30 +658,38 @@ kvm_argv(kvm_t *kd, const struct kinfo_proc *kp, int env, int nchr)
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 **
OpenPOWER on IntegriCloud