summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authortrociny <trociny@FreeBSD.org>2012-02-01 18:02:13 +0000
committertrociny <trociny@FreeBSD.org>2012-02-01 18:02:13 +0000
commitbd849a2aadb65525a867b63fadacf22c044935d2 (patch)
tree06be821c0871e22720f31da0e3845ca84840fa73 /lib
parent8685a56d47f2075e9208beb1818b857cfbacc06d (diff)
downloadFreeBSD-src-bd849a2aadb65525a867b63fadacf22c044935d2.zip
FreeBSD-src-bd849a2aadb65525a867b63fadacf22c044935d2.tar.gz
Try to avoid ambiguity when sysctl returns ENOMEM additionally
checking the returned oldlen: when ENOMEM is due to the supplied buffer being too short the return oldlen is equal to buffer size. Without this additional check kvm_getprocs() gets stuck in loop if the returned ENOMEM was due the exceeded memorylocked limit. This is easily can be observed running `limits -l 1k top'. Submitted by: Andrey Zonov <andrey zonov org> MFC after: 1 week
Diffstat (limited to 'lib')
-rw-r--r--lib/libkvm/kvm_proc.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c
index dcf034c..8fc415c 100644
--- a/lib/libkvm/kvm_proc.c
+++ b/lib/libkvm/kvm_proc.c
@@ -474,7 +474,7 @@ struct kinfo_proc *
kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt)
{
int mib[4], st, nprocs;
- size_t size;
+ size_t size, osize;
int temp_op;
if (kd->procbase != 0) {
@@ -524,10 +524,11 @@ kvm_getprocs(kvm_t *kd, int op, int arg, int *cnt)
_kvm_realloc(kd, kd->procbase, size);
if (kd->procbase == 0)
return (0);
+ osize = size;
st = sysctl(mib, temp_op == KERN_PROC_ALL ||
temp_op == KERN_PROC_PROC ? 3 : 4,
kd->procbase, &size, NULL, 0);
- } while (st == -1 && errno == ENOMEM);
+ } while (st == -1 && errno == ENOMEM && size == osize);
if (st == -1) {
_kvm_syserr(kd, kd->program, "kvm_getprocs");
return (0);
OpenPOWER on IntegriCloud