aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2010-03-05 16:44:12 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-06 14:26:46 -0500
commit30736a4d43f4af7f1a7836d6a266be17082195c4 (patch)
tree54e388cdaf4795bdb7651be03c50bba67eb0b43a /fs/binfmt_elf.c
parent8d9032bbe4671dc481261ccd4e161cd96e54b118 (diff)
coredump: pass mm->flags as a coredump parameter for consistency
Pass mm->flags as a coredump parameter for consistency. --- 1787 if (mm->core_state || !get_dumpable(mm)) { <- (1) 1788 up_write(&mm->mmap_sem); 1789 put_cred(cred); 1790 goto fail; 1791 } 1792 [...] 1798 if (get_dumpable(mm) == 2) { /* Setuid core dump mode */ <-(2) 1799 flag = O_EXCL; /* Stop rewrite attacks */ 1800 cred->fsuid = 0; /* Dump root private */ 1801 } --- Since dumpable bits are not protected by lock, there is a chance to change these bits between (1) and (2). To solve this issue, this patch copies mm->flags to coredump_params.mm_flags at the beginning of do_coredump() and uses it instead of get_dumpable() while dumping core. This copy is also passed to binfmt->core_dump, since elf*_core_dump() uses dump_filter bits in mm->flags. [akpm@linux-foundation.org: fix merge] Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Acked-by: Roland McGrath <roland@redhat.com> Cc: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Reviewed-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c14
1 files changed, 3 insertions, 11 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 78de530cfb02..535e763ab1a6 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1882,7 +1882,6 @@ static int elf_core_dump(struct coredump_params *cprm)
1882 struct vm_area_struct *vma, *gate_vma; 1882 struct vm_area_struct *vma, *gate_vma;
1883 struct elfhdr *elf = NULL; 1883 struct elfhdr *elf = NULL;
1884 loff_t offset = 0, dataoff, foffset; 1884 loff_t offset = 0, dataoff, foffset;
1885 unsigned long mm_flags;
1886 struct elf_note_info info; 1885 struct elf_note_info info;
1887 struct elf_phdr *phdr4note = NULL; 1886 struct elf_phdr *phdr4note = NULL;
1888 struct elf_shdr *shdr4extnum = NULL; 1887 struct elf_shdr *shdr4extnum = NULL;
@@ -1957,14 +1956,7 @@ static int elf_core_dump(struct coredump_params *cprm)
1957 1956
1958 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); 1957 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1959 1958
1960 /* 1959 offset += elf_core_vma_data_size(gate_vma, cprm->mm_flags);
1961 * We must use the same mm->flags while dumping core to avoid
1962 * inconsistency between the program headers and bodies, otherwise an
1963 * unusable core file can be generated.
1964 */
1965 mm_flags = current->mm->flags;
1966
1967 offset += elf_core_vma_data_size(gate_vma, mm_flags);
1968 offset += elf_core_extra_data_size(); 1960 offset += elf_core_extra_data_size();
1969 e_shoff = offset; 1961 e_shoff = offset;
1970 1962
@@ -1995,7 +1987,7 @@ static int elf_core_dump(struct coredump_params *cprm)
1995 phdr.p_offset = offset; 1987 phdr.p_offset = offset;
1996 phdr.p_vaddr = vma->vm_start; 1988 phdr.p_vaddr = vma->vm_start;
1997 phdr.p_paddr = 0; 1989 phdr.p_paddr = 0;
1998 phdr.p_filesz = vma_dump_size(vma, mm_flags); 1990 phdr.p_filesz = vma_dump_size(vma, cprm->mm_flags);
1999 phdr.p_memsz = vma->vm_end - vma->vm_start; 1991 phdr.p_memsz = vma->vm_end - vma->vm_start;
2000 offset += phdr.p_filesz; 1992 offset += phdr.p_filesz;
2001 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; 1993 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -2030,7 +2022,7 @@ static int elf_core_dump(struct coredump_params *cprm)
2030 unsigned long addr; 2022 unsigned long addr;
2031 unsigned long end; 2023 unsigned long end;
2032 2024
2033 end = vma->vm_start + vma_dump_size(vma, mm_flags); 2025 end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags);
2034 2026
2035 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { 2027 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
2036 struct page *page; 2028 struct page *page;