diff options
author | ngie <ngie@FreeBSD.org> | 2016-04-30 09:13:26 +0000 |
---|---|---|
committer | ngie <ngie@FreeBSD.org> | 2016-04-30 09:13:26 +0000 |
commit | 874567745a9accd16d4202ffcb2482517474f2f8 (patch) | |
tree | 5e2b583361331cc065489c37ffba4258719c6e75 | |
parent | 470b1c2a5e88c5167cc16afc572255dfac167af1 (diff) | |
download | FreeBSD-src-874567745a9accd16d4202ffcb2482517474f2f8.zip FreeBSD-src-874567745a9accd16d4202ffcb2482517474f2f8.tar.gz |
Fix memory allocation edgecases in kvm_argv(..)
- Don't leak nbufp on realloc failure in kvm_argv
- Catch malloc errors with bufp
- Set buflen last in the "buflen == 0" case to ensure that
bufp/nbufp is properly reallocated on the next go around
Differential Revision: https://reviews.freebsd.org/D6051
MFC after: 1 week
Reviewed by: jhb, markj
Reported by: cppcheck
Sponsored by: EMC / Isilon Storage Division
-rw-r--r-- | lib/libkvm/kvm_proc.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c index 1eb9872..5cd0493 100644 --- a/lib/libkvm/kvm_proc.c +++ b/lib/libkvm/kvm_proc.c @@ -666,6 +666,7 @@ kvm_argv(kvm_t *kd, const struct kinfo_proc *kp, int env, int nchr) static char *buf, *p; static char **bufp; static int argc; + char **nbufp; if (!ISALIVE(kd)) { _kvm_err(kd, kd->program, @@ -681,9 +682,15 @@ kvm_argv(kvm_t *kd, const struct kinfo_proc *kp, int env, int nchr) _kvm_err(kd, kd->program, "cannot allocate memory"); return (NULL); } - buflen = nchr; argc = 32; bufp = malloc(sizeof(char *) * argc); + if (bufp == NULL) { + free(buf); + buf = NULL; + _kvm_err(kd, kd->program, "cannot allocate memory"); + return (NULL); + } + buflen = nchr; } else if (nchr > buflen) { p = realloc(buf, nchr); if (p != NULL) { @@ -716,8 +723,10 @@ kvm_argv(kvm_t *kd, const struct kinfo_proc *kp, int env, int nchr) p += strlen(p) + 1; if (i >= argc) { argc += argc; - bufp = realloc(bufp, - sizeof(char *) * argc); + nbufp = realloc(bufp, sizeof(char *) * argc); + if (nbufp == NULL) + return (NULL); + bufp = nbufp; } } while (p < buf + bufsz); bufp[i++] = 0; |