lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 10 Apr 2009 06:37:52 +0400 From: Alexey Dobriyan <adobriyan@...il.com> To: akpm@...ux-foundation.org, containers@...ts.linux-foundation.org Cc: xemul@...allels.com, serue@...ibm.com, dave@...ux.vnet.ibm.com, mingo@...e.hu, orenl@...columbia.edu, hch@...radead.org, torvalds@...ux-foundation.org, linux-kernel@...r.kernel.org Subject: [PATCH 18/30] cr: restore vDSO on i386/x86_64 FIXME: check VMA has same parameters. FIXME: abort if target kernel has vDSO disabled (?) FIXME: restore pages, vDSO is writable after all. Signed-off-by: Alexey Dobriyan <adobriyan@...il.com> --- arch/x86/vdso/vdso32-setup.c | 6 ++ include/linux/cr.h | 11 +++++ include/linux/mm.h | 5 +- kernel/cr/cr-mm.c | 87 +++++++++++++++++++++++++++++++++++++++++++ mm/mmap.c | 3 + 5 files changed, 110 insertions(+), 2 deletions(-) --- a/arch/x86/vdso/vdso32-setup.c +++ b/arch/x86/vdso/vdso32-setup.c @@ -328,6 +328,10 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, unsigned long start, map_compat_vdso(compat); + if (start) { + addr = start; + goto map; + } if (compat) addr = VDSO_HIGH_BASE; else { @@ -337,7 +341,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, unsigned long start, goto up_fail; } } - +map: if (compat_uses_vma || !compat) { /* * MAYWRITE to allow gdb to COW and set breakpoints --- a/include/linux/cr.h +++ b/include/linux/cr.h @@ -34,6 +34,7 @@ struct cr_object_header { #define CR_OBJ_FILE 3 #define CR_OBJ_VMA 4 #define CR_OBJ_VMA_CONTENT 5 +#define CR_OBJ_VMA_VDSO 6 __u32 cr_type; /* object type */ __u32 cr_len; /* object length in bytes including header */ } __packed; @@ -177,6 +178,16 @@ struct cr_image_vma { cr_pos_t cr_pos_vm_file; } __packed; +struct cr_image_vma_vdso { + struct cr_object_header cr_hdr; + + __u64 cr_vm_start; + __u64 cr_vm_end; + __u64 cr_vm_page_prot; + __u64 cr_vm_flags; + __u64 cr_vm_pgoff; +} __packed; + struct cr_image_vma_content { struct cr_object_header cr_hdr; --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1129,7 +1129,10 @@ extern int may_expand_vm(struct mm_struct *mm, unsigned long npages); extern int install_special_mapping(struct mm_struct *mm, unsigned long addr, unsigned long len, unsigned long flags, struct page **pages); - +#ifdef CONFIG_CR +struct cr_context; +int special_mapping_checkpoint(struct vm_area_struct *vma, struct cr_context *ctx); +#endif extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, --- a/kernel/cr/cr-mm.c +++ b/kernel/cr/cr-mm.c @@ -332,6 +332,88 @@ static int cr_restore_vma(struct cr_context *ctx, loff_t pos) return cr_restore_vma_content(ctx, pos + sizeof(*i)); } +#ifdef ARCH_HAS_SETUP_ADDITIONAL_PAGES +int special_mapping_checkpoint(struct vm_area_struct *vma, struct cr_context *ctx) +{ + struct cr_image_vma *i; + struct page **page; + unsigned long addr; + int rv; + + i = cr_prepare_image(CR_OBJ_VMA_VDSO, sizeof(*i)); + if (!i) + return -ENOMEM; + + i->cr_vm_start = vma->vm_start; + i->cr_vm_end = vma->vm_end; + i->cr_vm_page_prot = vma->vm_page_prot.pgprot; + i->cr_vm_flags = vma->vm_flags; + i->cr_vm_pgoff = vma->vm_pgoff; + + rv = cr_write(ctx, i, sizeof(*i)); + kfree(i); + if (rv < 0) + return rv; + + page = vma->vm_private_data; + for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) { + struct cr_image_vma_content i; + void *data; + + i.cr_hdr.cr_type = CR_OBJ_VMA_CONTENT; + i.cr_hdr.cr_len = sizeof(i) + 1 * PAGE_SIZE; + + i.cr_start_addr = addr; + i.cr_nr_pages = 1; + i.cr_page_size = PAGE_SIZE; + rv = cr_write(ctx, &i, sizeof(i)); + if (rv < 0) + return rv; + data = kmap(page[(addr - vma->vm_start) / PAGE_SIZE]); + rv = cr_write(ctx, data, 1 * PAGE_SIZE); + kunmap(page[(addr - vma->vm_start) / PAGE_SIZE]); + if (rv < 0) + return rv; + } + printk("dump vDSO: %08lx-%08lx, rv %d\n", vma->vm_start, vma->vm_end, rv); + return 0; +} + +static int cr_restore_vma_vdso(struct cr_context *ctx, loff_t pos) +{ + struct cr_image_vma_vdso *i; + int rv; + + i = kzalloc(sizeof(*i), GFP_KERNEL); + if (!i) + return -ENOMEM; + rv = cr_pread(ctx, i, sizeof(*i), pos); + if (rv < 0) { + kfree(i); + return rv; + } + if (i->cr_hdr.cr_type != CR_OBJ_VMA_VDSO) { + kfree(i); + return -EINVAL; + } + + rv = arch_setup_additional_pages(NULL, i->cr_vm_start, 0); + printk("restore vDSO: %08lx, rv %d\n", (unsigned long)i->cr_vm_start, rv); + kfree(i); + return rv; +} +#else +int special_mapping_checkpoint(struct vm_area_struct *vma, struct cr_context *ctx) +{ + return -EINVAL; +} + +static int cr_restore_vma_vdso(struct cr_context *ctx, loff_t pos) +{ + return -EINVAL; +} +#endif + static int cr_restore_all_vma(struct cr_context *ctx, loff_t pos) { struct cr_object_header cr_hdr; @@ -347,6 +429,11 @@ static int cr_restore_all_vma(struct cr_context *ctx, loff_t pos) if (rv < 0) return rv; break; + case CR_OBJ_VMA_VDSO: + rv = cr_restore_vma_vdso(ctx, pos); + if (rv < 0) + return rv; + break; case CR_OBJ_VMA_CONTENT: break; default: --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2257,6 +2257,9 @@ static void special_mapping_close(struct vm_area_struct *vma) static struct vm_operations_struct special_mapping_vmops = { .close = special_mapping_close, .fault = special_mapping_fault, +#ifdef CONFIG_CR + .checkpoint = special_mapping_checkpoint, +#endif }; /* -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists