-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
arm64: mte: Dump the MTE tags in the core file
For each vma mapped with PROT_MTE (the VM_MTE flag set), generate a PT_ARM_MEMTAG_MTE segment in the core file and dump the corresponding tags. The in-file size for such segments is 128 bytes per page. For pages in a VM_MTE vma which are not present in the user page tables or don't have the PG_mte_tagged flag set (e.g. execute-only), just write zeros in the core file. An example of program headers for two vmas, one 2-page, the other 4-page long: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align ... LOAD 0x030000 0x0000ffff80034000 0x0000000000000000 0x000000 0x002000 RW 0x1000 LOAD 0x030000 0x0000ffff80036000 0x0000000000000000 0x004000 0x004000 RW 0x1000 ... LOPROC+0x1 0x05b000 0x0000ffff80034000 0x0000000000000000 0x000100 0x002000 0 LOPROC+0x1 0x05b100 0x0000ffff80036000 0x0000000000000000 0x000200 0x004000 0 Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Acked-by: Luis Machado <luis.machado@linaro.org> Reviewed-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20220131165456.2160675-5-catalin.marinas@arm.com Signed-off-by: Will Deacon <will@kernel.org>
- Loading branch information
Catalin Marinas
authored and
Will Deacon
committed
Feb 15, 2022
1 parent
ab1e435
commit 6dd8b1a
Showing
3 changed files
with
125 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
|
||
#include <linux/coredump.h> | ||
#include <linux/elfcore.h> | ||
#include <linux/kernel.h> | ||
#include <linux/mm.h> | ||
|
||
#include <asm/cpufeature.h> | ||
#include <asm/mte.h> | ||
|
||
#define for_each_mte_vma(tsk, vma) \ | ||
if (system_supports_mte()) \ | ||
for (vma = tsk->mm->mmap; vma; vma = vma->vm_next) \ | ||
if (vma->vm_flags & VM_MTE) | ||
|
||
static unsigned long mte_vma_tag_dump_size(struct vm_area_struct *vma) | ||
{ | ||
if (vma->vm_flags & VM_DONTDUMP) | ||
return 0; | ||
|
||
return vma_pages(vma) * MTE_PAGE_TAG_STORAGE; | ||
} | ||
|
||
/* Derived from dump_user_range(); start/end must be page-aligned */ | ||
static int mte_dump_tag_range(struct coredump_params *cprm, | ||
unsigned long start, unsigned long end) | ||
{ | ||
unsigned long addr; | ||
|
||
for (addr = start; addr < end; addr += PAGE_SIZE) { | ||
char tags[MTE_PAGE_TAG_STORAGE]; | ||
struct page *page = get_dump_page(addr); | ||
|
||
/* | ||
* get_dump_page() returns NULL when encountering an empty | ||
* page table entry that would otherwise have been filled with | ||
* the zero page. Skip the equivalent tag dump which would | ||
* have been all zeros. | ||
*/ | ||
if (!page) { | ||
dump_skip(cprm, MTE_PAGE_TAG_STORAGE); | ||
continue; | ||
} | ||
|
||
/* | ||
* Pages mapped in user space as !pte_access_permitted() (e.g. | ||
* PROT_EXEC only) may not have the PG_mte_tagged flag set. | ||
*/ | ||
if (!test_bit(PG_mte_tagged, &page->flags)) { | ||
put_page(page); | ||
dump_skip(cprm, MTE_PAGE_TAG_STORAGE); | ||
continue; | ||
} | ||
|
||
mte_save_page_tags(page_address(page), tags); | ||
put_page(page); | ||
if (!dump_emit(cprm, tags, MTE_PAGE_TAG_STORAGE)) | ||
return 0; | ||
} | ||
|
||
return 1; | ||
} | ||
|
||
Elf_Half elf_core_extra_phdrs(void) | ||
{ | ||
struct vm_area_struct *vma; | ||
int vma_count = 0; | ||
|
||
for_each_mte_vma(current, vma) | ||
vma_count++; | ||
|
||
return vma_count; | ||
} | ||
|
||
int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset) | ||
{ | ||
struct vm_area_struct *vma; | ||
|
||
for_each_mte_vma(current, vma) { | ||
struct elf_phdr phdr; | ||
|
||
phdr.p_type = PT_ARM_MEMTAG_MTE; | ||
phdr.p_offset = offset; | ||
phdr.p_vaddr = vma->vm_start; | ||
phdr.p_paddr = 0; | ||
phdr.p_filesz = mte_vma_tag_dump_size(vma); | ||
phdr.p_memsz = vma->vm_end - vma->vm_start; | ||
offset += phdr.p_filesz; | ||
phdr.p_flags = 0; | ||
phdr.p_align = 0; | ||
|
||
if (!dump_emit(cprm, &phdr, sizeof(phdr))) | ||
return 0; | ||
} | ||
|
||
return 1; | ||
} | ||
|
||
size_t elf_core_extra_data_size(void) | ||
{ | ||
struct vm_area_struct *vma; | ||
size_t data_size = 0; | ||
|
||
for_each_mte_vma(current, vma) | ||
data_size += mte_vma_tag_dump_size(vma); | ||
|
||
return data_size; | ||
} | ||
|
||
int elf_core_write_extra_data(struct coredump_params *cprm) | ||
{ | ||
struct vm_area_struct *vma; | ||
|
||
for_each_mte_vma(current, vma) { | ||
if (vma->vm_flags & VM_DONTDUMP) | ||
continue; | ||
|
||
if (!mte_dump_tag_range(cprm, vma->vm_start, vma->vm_end)) | ||
return 0; | ||
} | ||
|
||
return 1; | ||
} |