Headline
CVE-2023-1249: [5/5] coredump: Use the vma snapshot in fill_files_note
A use-after-free flaw was found in the Linux kernel’s core dump subsystem. This flaw allows a local user to crash the system. Only if patch 390031c94211 (“coredump: Use the vma snapshot in fill_files_note”) not applied yet, then kernel could be affected.
@@ -1619,14 +1619,14 @@ static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata, * long file_ofs * followed by COUNT filenames in ASCII: “FILE1” NUL “FILE2” NUL… */ -static int fill_files_note(struct memelfnote *note) +static int fill_files_note(struct memelfnote *note, struct coredump_params *cprm) { struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; unsigned count, size, names_ofs, remaining, n; user_long_t *data; user_long_t *start_end_ofs; char *name_base, *name_curpos;
int i;
/* *Estimated* file count and total data size needed */ count = mm->map_count; @@ -1651,11 +1651,12 @@ static int fill_files_note(struct memelfnote *note) name_base = name_curpos = ((char *)data) + names_ofs; remaining = size - names_ofs; count = 0; - for (vma = mm->mmap; vma != NULL; vma = vma->vm_next) {
for (i = 0; i < cprm->vma_count; i++) {
struct core\_vma\_metadata \*m = &cprm->vma\_meta\[i\]; struct file \*file; const char \*filename;
- file = vma->vm_file;
file = m->file; if (!file) continue; filename = file\_path(file, name\_curpos, remaining);
@@ -1675,9 +1676,9 @@ static int fill_files_note(struct memelfnote *note) memmove(name_curpos, filename, n); name_curpos += n;
- *start_end_ofs++ = vma->vm_start; - *start_end_ofs++ = vma->vm_end; - *start_end_ofs++ = vma->vm_pgoff;
\*start\_end\_ofs++ = m->start;
\*start\_end\_ofs++ = m->end;
}\*start\_end\_ofs++ = m->pgoff; count++;
@@ -1887,7 +1888,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, fill_auxv_note(&info->auxv, current->mm); info->size += notesize(&info->auxv);
- if (fill_files_note(&info->files) == 0)
if (fill_files_note(&info->files, cprm) == 0) info->size += notesize(&info->files);
return 1; @@ -2076,7 +2077,7 @@ static int fill_note_info(struct elfhdr *elf, int phdrs, fill_auxv_note(info->notes + 3, current->mm); info->numnote = 4;
- if (fill_files_note(info->notes + info->numnote) == 0) {
- if (fill_files_note(info->notes + info->numnote, cprm) == 0) { info->notes_files = info->notes + info->numnote; info->numnote++; }
@@ -54,6 +54,7 @@ #include <trace/events/sched.h>
static bool dump_vma_snapshot(struct coredump_params *cprm); +static void free_vma_snapshot(struct coredump_params *cprm);
static int core_uses_pid; static unsigned int core_pipe_limit; @@ -764,7 +765,7 @@ void do_coredump(const kernel_siginfo_t *siginfo) dump_emit(&cprm, "", 1); } file_end_write(cprm.file); - kvfree(cprm.vma_meta);
} if (ispipe && core_pipe_limit) wait_for_dump_helpers(cprm.file); @@ -1085,6 +1086,20 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma, return gate_vma; }free\_vma\_snapshot(&cprm);
+static void free_vma_snapshot(struct coredump_params *cprm) +{
- if (cprm->vma_meta) {
int i;
for (i = 0; i < cprm->vma\_count; i++) {
struct file \*file = cprm->vma\_meta\[i\].file;
if (file)
fput(file);
}
kvfree(cprm->vma\_meta);
cprm->vma\_meta = NULL;
- } +}
/* * Under the mmap_lock, take a snapshot of relevant information about the task’s * VMAs. @@ -1121,6 +1136,11 @@ static bool dump_vma_snapshot(struct coredump_params *cprm) m->end = vma->vm_end; m->flags = vma->vm_flags; m->dump_size = vma_dump_size(vma, cprm->mm_flags);
m->pgoff = vma->vm\_pgoff;
m->file = vma->vm\_file;
if (m->file)
}get\_file(m->file); cprm->vma\_data\_size += m->dump\_size;
@@ -12,6 +12,8 @@ struct core_vma_metadata { unsigned long start, end; unsigned long flags; unsigned long dump_size;
- unsigned long pgoff;
- struct file *file; };
struct coredump_params {
Related news
The kernel tree of CentOS Stream 9 suffers from multiple use-after-free conditions that were already patched in upstream stable trees.