summaryrefslogtreecommitdiffstats
path: root/sys/sys
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2016-02-10 00:08:51 +0000
committerjhb <jhb@FreeBSD.org>2016-02-10 00:08:51 +0000
commitcb56e836d9a9db908a5f1e021e6483e1e8aab048 (patch)
treef465785d769592288d951ba36ff13f6bf757cd2a /sys/sys
parentf1429e95c359a7e76f8385cdd47f887b7d1bbd0e (diff)
downloadFreeBSD-src-cb56e836d9a9db908a5f1e021e6483e1e8aab048.zip
FreeBSD-src-cb56e836d9a9db908a5f1e021e6483e1e8aab048.tar.gz
MFC 287442,287537,288944:
Fix corruption of coredumps due to procstat notes changing size during coredump generation. The changes in r287442 required some reworking since the 'fo_fill_kinfo' file op does not exist in stable/10. 287442: 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. 287537: Follow-up to r287442: Move sysctl to compiled-once file Avoid duplicate sysctl nodes. 288944: 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. Approved by: re (gjb)
Diffstat (limited to 'sys/sys')
-rw-r--r--sys/sys/exec.h3
-rw-r--r--sys/sys/user.h11
2 files changed, 12 insertions, 2 deletions
diff --git a/sys/sys/exec.h b/sys/sys/exec.h
index cccebfd..0ccba24 100644
--- a/sys/sys/exec.h
+++ b/sys/sys/exec.h
@@ -83,6 +83,9 @@ void exec_unmap_first_page(struct image_params *);
int exec_register(const struct execsw *);
int exec_unregister(const struct execsw *);
+extern int coredump_pack_fileinfo;
+extern int coredump_pack_vmmapinfo;
+
/*
* note: name##_mod cannot be const storage because the
* linker_file_sysinit() function modifies _file in the
diff --git a/sys/sys/user.h b/sys/sys/user.h
index 9374daf..a697b66 100644
--- a/sys/sys/user.h
+++ b/sys/sys/user.h
@@ -536,6 +536,11 @@ struct kinfo_sigtramp {
#define KERN_PROC_NOTHREADS 0x1
#define KERN_PROC_MASK32 0x2
+/* Flags for kern_proc_filedesc_out. */
+#define KERN_FILEDESC_PACK_KINFO 0x00000001U
+
+/* Flags for kern_proc_vmmap_out. */
+#define KERN_VMMAP_PACK_KINFO 0x00000001U
struct sbuf;
/*
@@ -547,9 +552,11 @@ struct sbuf;
* to be locked on enter. On return the process is unlocked.
*/
-int kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen);
+int kern_proc_filedesc_out(struct proc *p, struct sbuf *sb, ssize_t maxlen,
+ int flags);
int kern_proc_out(struct proc *p, struct sbuf *sb, int flags);
-int kern_proc_vmmap_out(struct proc *p, struct sbuf *sb);
+int kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen,
+ int flags);
int vntype_to_kinfo(int vtype);
#endif /* !_KERNEL */
OpenPOWER on IntegriCloud