summaryrefslogtreecommitdiffstats
path: root/lib/libprocstat
diff options
context:
space:
mode:
authorcem <cem@FreeBSD.org>2015-10-06 18:07:00 +0000
committercem <cem@FreeBSD.org>2015-10-06 18:07:00 +0000
commit9c1e214f79cb8f8fb38ba2f8fa010f282ec5be79 (patch)
tree9844297e32023403c9df2beefdd3462b21290b04 /lib/libprocstat
parenta6f4f28b545e1f0632ba4b20b86a7ab487932373 (diff)
downloadFreeBSD-src-9c1e214f79cb8f8fb38ba2f8fa010f282ec5be79.zip
FreeBSD-src-9c1e214f79cb8f8fb38ba2f8fa010f282ec5be79.tar.gz
Fix core corruption caused by race in note_procstat_vmmap
This fix is spiritually similar to r287442 and was discovered thanks to the KASSERT added in that revision. NT_PROCSTAT_VMMAP output length, when packing kinfo structs, is tied to the length of filenames corresponding to vnodes in the process' vm map via vn_fullpath. As vnodes may move during coredump, this is racy. We do not remove the race, only prevent it from causing coredump corruption. - Add a sysctl, kern.coredump_pack_vmmapinfo, to allow users to disable kinfo packing for PROCSTAT_VMMAP notes. This avoids VMMAP corruption and truncation, even if names change, at the cost of up to PATH_MAX bytes per mapped object. The new sysctl is documented in core.5. - Fix note_procstat_vmmap to self-limit in the second pass. This addresses corruption, at the cost of sometimes producing a truncated result. - Fix PROCSTAT_VMMAP consumers libutil (and libprocstat, via copy-paste) to grok the new zero padding. Reported by: pho (https://people.freebsd.org/~pho/stress/log/datamove4-2.txt) Relnotes: yes Sponsored by: EMC / Isilon Storage Division Differential Revision: https://reviews.freebsd.org/D3824
Diffstat (limited to 'lib/libprocstat')
-rw-r--r--lib/libprocstat/libprocstat.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c
index 932b5a0..3de64aa 100644
--- a/lib/libprocstat/libprocstat.c
+++ b/lib/libprocstat/libprocstat.c
@@ -1867,6 +1867,8 @@ kinfo_getvmmap_core(struct procstat_core *core, int *cntp)
eb = buf + len;
while (bp < eb) {
kv = (struct kinfo_vmentry *)(uintptr_t)bp;
+ if (kv->kve_structsize == 0)
+ break;
bp += kv->kve_structsize;
cnt++;
}
@@ -1882,6 +1884,8 @@ kinfo_getvmmap_core(struct procstat_core *core, int *cntp)
/* Pass 2: unpack */
while (bp < eb) {
kv = (struct kinfo_vmentry *)(uintptr_t)bp;
+ if (kv->kve_structsize == 0)
+ break;
/* Copy/expand into pre-zeroed buffer */
memcpy(kp, kv, kv->kve_structsize);
/* Advance to next packed record */
OpenPOWER on IntegriCloud