Hi Atsushi,

On Thursday 25 May 2017 08:33 AM, Atsushi Kumagai wrote:
Hello Pratyush,

If we have to erase a symbol from vmcore whose address is not present in
vmcoreinfo, then we need to pass vmlinux as well to get the symbol
address.
When kaslr is enabled, virtual address of all the kernel symbols are
randomized with an offset. vmlinux  always has a static address, but all
the arch specific calculation are based on run time kernel address. So
we need to find a way to translate symbol address from vmlinux to kernel
run time address.

without this patch:
  # cat > scrub.conf << EOF
  [vmlinux]
  erase jiffies
  erase init_task.utime
  for tsk in init_task.tasks.next within task_struct:tasks
      erase tsk.utime
  endfor
  EOF

   # makedumpfile --split  -d 5 -x vmlinux --config scrub.conf vmcore 
dumpfile_{1,2,3}

   readpage_kdump_compressed: pfn(f97ea) is excluded from vmcore.
   readmem: type_addr: 1, addr:f97eaff8, size:8
   vtop4_x86_64: Can't get pml4 (page_dir:f97eaff8).
   readmem: Can't convert a virtual address(ffffffff819f1284) to physical 
address.
   readmem: type_addr: 0, addr:ffffffff819f1284, size:390
   check_release: Can't get the address of system_utsname.

After this patch check_release() is ok, and also we are able to erase
symbol from vmcore.

Signed-off-by: Pratyush Anand <[email protected]>
---
arch/x86_64.c  | 36 ++++++++++++++++++++++++++++++++++++
erase_info.c   |  1 +
makedumpfile.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
makedumpfile.h | 16 ++++++++++++++++
4 files changed, 106 insertions(+)

diff --git a/arch/x86_64.c b/arch/x86_64.c
index e978a36f8878..fd2e8ac154d6 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -33,6 +33,42 @@ get_xen_p2m_mfn(void)
        return NOT_FOUND_LONG_VALUE;
}

+unsigned long
+get_kaslr_offset_x86_64(unsigned long vaddr)
+{
+       unsigned int i;
+       char buf[BUFSIZE_FGETS], *endp;
+
+       if (!info->kaslr_offset && info->file_vmcoreinfo) {
+               if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) {
+                       ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n",
+                                       info->name_vmcoreinfo, strerror(errno));
+                       return FALSE;
+               }
+
+               while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
+                       i = strlen(buf);
+                       if (!i)
+                               break;
+                       if (buf[i - 1] == '\n')
+                               buf[i - 1] = '\0';
+                       if (strncmp(buf, STR_KERNELOFFSET,
+                                       strlen(STR_KERNELOFFSET)) == 0)
+                               info->kaslr_offset =
+                                       
strtoul(buf+strlen(STR_KERNELOFFSET),&endp,16);
+               }
+       }
+       if (vaddr >= __START_KERNEL_map &&
+                       vaddr < __START_KERNEL_map + info->kaslr_offset)
+               return info->kaslr_offset;
+       else
+               /*
+                * TODO: we need to check if it is vmalloc/vmmemmap/module
+                * address, we will have different offset
+                */
+               return 0;
+}
+
static int
get_page_offset_x86_64(void)
{
diff --git a/erase_info.c b/erase_info.c
index f2ba9149e93e..60abfa1a1adf 100644
--- a/erase_info.c
+++ b/erase_info.c
@@ -1088,6 +1088,7 @@ resolve_config_entry(struct config_entry *ce, unsigned 
long long base_vaddr,
                                                        ce->line, ce->name);
                        return FALSE;
                }
+               ce->sym_addr += get_kaslr_offset(ce->sym_addr);
                ce->type_name = get_symbol_type_name(ce->name,
                                        DWARF_INFO_GET_SYMBOL_TYPE,
                                        &ce->size, &ce->type_flag);
diff --git a/makedumpfile.c b/makedumpfile.c
index 301772a8820c..4986d098d69a 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2099,6 +2099,13 @@ void
write_vmcoreinfo_data(void)
{
        /*
+        * write 1st kernel's KERNELOFFSET
+        */
+       if (info->kaslr_offset)
+               fprintf(info->file_vmcoreinfo, "%s%lx\n", STR_KERNELOFFSET,
+                   info->kaslr_offset);

When will this data written to VMCOREINFO file be used ?
info->kaslr_offset is necessary for vmlinux but -x and -i are exclusive.

This is what I thought:

Lets says we have got a vmcore1 after re-filtering original vmcore. Now, if we would like to re-filter vmcore1 then we will need kaslr_offset again. So, should we not right kaslr_offset in vmcoreinfo of vmcore1 as well?

Thanks for your review.

~Pratyush


_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to