proc/kcore: add vmcoreinfo note to /proc/kcore
authorOmar Sandoval <osandov@fb.com>
Wed, 22 Aug 2018 04:55:20 +0000 (21:55 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 22 Aug 2018 17:52:46 +0000 (10:52 -0700)
The vmcoreinfo information is useful for runtime debugging tools, not just
for crash dumps.  A lot of this information can be determined by other
means, but this is much more convenient, and it only adds a page at most
to the file.

Link: http://lkml.kernel.org/r/fddbcd08eed76344863303878b12de1c1e2a04b6.1531953780.git.osandov@fb.com
Signed-off-by: Omar Sandoval <osandov@fb.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Bhupesh Sharma <bhsharma@redhat.com>
Cc: Eric Biederman <ebiederm@xmission.com>
Cc: James Morse <james.morse@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
fs/proc/Kconfig
fs/proc/kcore.c
include/linux/crash_core.h
kernel/crash_core.c

index 0eaeb41..817c02b 100644 (file)
@@ -31,6 +31,7 @@ config PROC_FS
 config PROC_KCORE
        bool "/proc/kcore support" if !ARM
        depends on PROC_FS && MMU
+       select CRASH_CORE
        help
          Provides a virtual ELF core file of the live kernel.  This can
          be read with gdb and other ELF tools.  No modifications can be
index 758c14e..8046443 100644 (file)
@@ -10,6 +10,7 @@
  *     Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <kanoj@sgi.com>
  */
 
+#include <linux/crash_core.h>
 #include <linux/mm.h>
 #include <linux/proc_fs.h>
 #include <linux/kcore.h>
@@ -81,10 +82,13 @@ static size_t get_kcore_size(int *nphdr, size_t *phdrs_len, size_t *notes_len,
        }
 
        *phdrs_len = *nphdr * sizeof(struct elf_phdr);
-       *notes_len = (3 * (sizeof(struct elf_note) + ALIGN(sizeof(CORE_STR), 4)) +
+       *notes_len = (4 * sizeof(struct elf_note) +
+                     3 * ALIGN(sizeof(CORE_STR), 4) +
+                     VMCOREINFO_NOTE_NAME_BYTES +
                      ALIGN(sizeof(struct elf_prstatus), 4) +
                      ALIGN(sizeof(struct elf_prpsinfo), 4) +
-                     ALIGN(arch_task_struct_size, 4));
+                     ALIGN(arch_task_struct_size, 4) +
+                     ALIGN(vmcoreinfo_size, 4));
        *data_offset = PAGE_ALIGN(sizeof(struct elfhdr) + *phdrs_len +
                                  *notes_len);
        return *data_offset + size;
@@ -406,6 +410,16 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
                                  sizeof(prpsinfo));
                append_kcore_note(notes, &i, CORE_STR, NT_TASKSTRUCT, current,
                                  arch_task_struct_size);
+               /*
+                * vmcoreinfo_size is mostly constant after init time, but it
+                * can be changed by crash_save_vmcoreinfo(). Racing here with a
+                * panic on another CPU before the machine goes down is insanely
+                * unlikely, but it's better to not leave potential buffer
+                * overflows lying around, regardless.
+                */
+               append_kcore_note(notes, &i, VMCOREINFO_NOTE_NAME, 0,
+                                 vmcoreinfo_data,
+                                 min(vmcoreinfo_size, notes_len - i));
 
                tsz = min_t(size_t, buflen, notes_offset + notes_len - *fpos);
                if (copy_to_user(buffer, notes + *fpos - notes_offset, tsz)) {
index b511f6d..525510a 100644 (file)
@@ -60,6 +60,8 @@ phys_addr_t paddr_vmcoreinfo_note(void);
 #define VMCOREINFO_CONFIG(name) \
        vmcoreinfo_append_str("CONFIG_%s=y\n", #name)
 
+extern unsigned char *vmcoreinfo_data;
+extern size_t vmcoreinfo_size;
 extern u32 *vmcoreinfo_note;
 
 Elf_Word *append_elf_note(Elf_Word *buf, char *name, unsigned int type,
index e7b4025..a683bfb 100644 (file)
@@ -14,8 +14,8 @@
 #include <asm/sections.h>
 
 /* vmcoreinfo stuff */
-static unsigned char *vmcoreinfo_data;
-static size_t vmcoreinfo_size;
+unsigned char *vmcoreinfo_data;
+size_t vmcoreinfo_size;
 u32 *vmcoreinfo_note;
 
 /* trusted vmcoreinfo, e.g. we can make a copy in the crash memory */