diff options
author | Conrad Meyer <cem@FreeBSD.org> | 2015-09-03 20:32:10 +0000 |
---|---|---|
committer | Conrad Meyer <cem@FreeBSD.org> | 2015-09-03 20:32:10 +0000 |
commit | 14bdbaf2e40a827e84f6c2fe27b1f8229767f03c (patch) | |
tree | 195203ad79430bfd94d54570dd7a2d50c86ee2be /lib/libutil | |
parent | 188458ea7ca26132becba9353b18f732b0eb7663 (diff) | |
download | src-14bdbaf2e40a827e84f6c2fe27b1f8229767f03c.tar.gz src-14bdbaf2e40a827e84f6c2fe27b1f8229767f03c.zip |
Detect badly behaved coredump note helpers
Coredump notes depend on being able to invoke dump routines twice; once
in a dry-run mode to get the size of the note, and another to actually
emit the note to the corefile.
When a note helper emits a different length section the second time
around than the length it requested the first time, the kernel produces
a corrupt coredump.
NT_PROCSTAT_FILES output length, when packing kinfo structs, is tied to
the length of filenames corresponding to vnodes in the process' fd table
via vn_fullpath. As vnodes may move around during dump, this is racy.
So:
- Detect badly behaved notes in putnote() and pad underfilled notes.
- Add a fail point, debug.fail_point.fill_kinfo_vnode__random_path to
exercise the NT_PROCSTAT_FILES corruption. It simply picks random
lengths to expand or truncate paths to in fo_fill_kinfo_vnode().
- Add a sysctl, kern.coredump_pack_fileinfo, to allow users to
disable kinfo packing for PROCSTAT_FILES notes. This should avoid
both FILES note corruption and truncation, even if filenames change,
at the cost of about 1 kiB in padding bloat per open fd. Document
the new sysctl in core.5.
- Fix note_procstat_files to self-limit in the 2nd pass. Since
sometimes this will result in a short write, pad up to our advertised
size. This addresses note corruption, at the risk of sometimes
truncating the last several fd info entries.
- Fix NT_PROCSTAT_FILES consumers libutil and libprocstat to grok the
zero padding.
With suggestions from: bjk, jhb, kib, wblock
Approved by: markj (mentor)
Relnotes: yes
Sponsored by: EMC / Isilon Storage Division
Differential Revision: https://reviews.freebsd.org/D3548
Notes
Notes:
svn path=/head/; revision=287442
Diffstat (limited to 'lib/libutil')
-rw-r--r-- | lib/libutil/kinfo_getfile.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/lib/libutil/kinfo_getfile.c b/lib/libutil/kinfo_getfile.c index 84b64db20204..8a5477f40654 100644 --- a/lib/libutil/kinfo_getfile.c +++ b/lib/libutil/kinfo_getfile.c @@ -44,6 +44,8 @@ kinfo_getfile(pid_t pid, int *cntp) eb = buf + len; while (bp < eb) { kf = (struct kinfo_file *)(uintptr_t)bp; + if (kf->kf_structsize == 0) + break; bp += kf->kf_structsize; cnt++; } @@ -59,6 +61,8 @@ kinfo_getfile(pid_t pid, int *cntp) /* Pass 2: unpack */ while (bp < eb) { kf = (struct kinfo_file *)(uintptr_t)bp; + if (kf->kf_structsize == 0) + break; /* Copy/expand into pre-zeroed buffer */ memcpy(kp, kf, kf->kf_structsize); /* Advance to next packed record */ |