coredump: fix spam with zero VMA process
Subsystems (2)
PATCH 1/1 coredump: fix spam with zero VMA process
Nobody ever tried to self destruct by unmapping whole address space at once:
munmap((void *)0, (1ULL << 47) - 4096);
Doing this produces 2 warnings for zero-length vmalloc allocations:
a.out[1353]: segfault at 7f80bcc4b757 ip 00007f80bcc4b757 sp 00007fff683939b8 error 14 a.out: vmalloc: allocation failure: 0 bytes, mode:0xcc0(GFP_KERNEL), nodemask=(null)
... a.out: vmalloc: allocation failure: 0 bytes, mode:0xcc0(GFP_KERNEL), nodemask=(null) ...
Fix is to switch to kvmalloc().
Steps to reproduce:
// vsyscall=none
#include <sys/mman.h>
#include <sys/resource.h>
int main(void)
{
setrlimit(RLIMIT_CORE, &(struct rlimit){RLIM_INFINITY, RLIM_INFINITY});
munmap((void *)0, (1ULL << 47) - 4096);
return 0;
}Signed-off-by Alexey Dobriyan <[email protected]>
---
fs/binfmt_elf.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
fs/binfmt_elf.c +8 -8
@@ -1608,8 +1608,8 @@ static int fill_files_note(struct memelfnote *note)if (size >=MAX_FILE_NOTE_SIZE )/* paranoia check */ return -EINVAL ; size =round_up (size,PAGE_SIZE ); - data =vmalloc (size); -if (!data) + data =kvmalloc (size,GFP_KERNEL ); +if (ZERO_OR_NULL_PTR (data))return -ENOMEM ; start_end_ofs = data +2 ;
@@ -1626,7 +1626,7 @@ static int fill_files_note(struct memelfnote *note) filename =file_path (file, name_curpos, remaining);if (IS_ERR (filename)) {if (PTR_ERR (filename) == -ENAMETOOLONG ) { -vfree (data); +kvfree (data); size = size *5 /4 ; goto alloc; }
@@ -1919,7 +1919,7 @@ static void free_note_info(struct elf_note_info *info) kfree(t); }kfree (info->psinfo.data); -vfree (info->files.data); +kvfree (info->files.data); }#else
@@ -2135,7 +2135,7 @@ static void free_note_info(struct elf_note_info *info)/* Free data possibly allocated by fill_files_note(): */ if (info->notes_files) -vfree (info->notes_files->data); +kvfree (info->notes_files->data);kfree (info->prstatus);kfree (info->psinfo);
@@ -2281,8 +2281,8 @@ static int elf_core_dump(struct coredump_params *cprm)if (segs -1 >ULONG_MAX /sizeof (*vma_filesz)) goto end_coredump; - vma_filesz =vmalloc ((segs -1 ) *sizeof (*vma_filesz)); -if (!vma_filesz) + vma_filesz =kvmalloc ((segs -1 ) *sizeof (*vma_filesz),GFP_KERNEL ); +if (ZERO_OR_NULL_PTR (vma_filesz)) goto end_coredump; for (i = 0, vma = first_vma(current, gate_vma); vma != NULL;
@@ -2389,7 +2389,7 @@ static int elf_core_dump(struct coredump_params *cprm) cleanup:free_note_info (&info);kfree (shdr4extnum); -vfree (vma_filesz); +kvfree (vma_filesz);kfree (phdr4note);kfree (elf); out: