1 /* 2 * arch/sh/kernel/vsyscall/vsyscall.c 3 * 4 * Copyright (C) 2006 Paul Mundt 5 * 6 * vDSO randomization 7 * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar 8 * 9 * This file is subject to the terms and conditions of the GNU General Public 10 * License. See the file "COPYING" in the main directory of this archive 11 * for more details. 12 */ 13 #include <linux/mm.h> 14 #include <linux/slab.h> 15 #include <linux/kernel.h> 16 #include <linux/init.h> 17 #include <linux/gfp.h> 18 #include <linux/module.h> 19 #include <linux/elf.h> 20 #include <linux/sched.h> 21 #include <linux/err.h> 22 23 /* 24 * Should the kernel map a VDSO page into processes and pass its 25 * address down to glibc upon exec()? 26 */ 27 unsigned int __read_mostly vdso_enabled = 1; 28 EXPORT_SYMBOL_GPL(vdso_enabled); 29 30 static int __init vdso_setup(char *s) 31 { 32 vdso_enabled = simple_strtoul(s, NULL, 0); 33 return 1; 34 } 35 __setup("vdso=", vdso_setup); 36 37 /* 38 * These symbols are defined by vsyscall.o to mark the bounds 39 * of the ELF DSO images included therein. 40 */ 41 extern const char vsyscall_trapa_start, vsyscall_trapa_end; 42 static struct page *syscall_pages[1]; 43 44 int __init vsyscall_init(void) 45 { 46 void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC); 47 syscall_pages[0] = virt_to_page(syscall_page); 48 49 /* 50 * XXX: Map this page to a fixmap entry if we get around 51 * to adding the page to ELF core dumps 52 */ 53 54 memcpy(syscall_page, 55 &vsyscall_trapa_start, 56 &vsyscall_trapa_end - &vsyscall_trapa_start); 57 58 return 0; 59 } 60 61 /* Setup a VMA at program startup for the vsyscall page */ 62 int arch_setup_additional_pages(struct linux_binprm *bprm, 63 int executable_stack) 64 { 65 struct mm_struct *mm = current->mm; 66 unsigned long addr; 67 int ret; 68 69 down_write(&mm->mmap_sem); 70 addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0); 71 if (IS_ERR_VALUE(addr)) { 72 ret = addr; 73 goto up_fail; 74 } 75 76 ret = install_special_mapping(mm, addr, PAGE_SIZE, 77 VM_READ | VM_EXEC | 78 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC | 79 VM_ALWAYSDUMP, 80 syscall_pages); 81 if (unlikely(ret)) 82 goto up_fail; 83 84 current->mm->context.vdso = (void *)addr; 85 86 up_fail: 87 up_write(&mm->mmap_sem); 88 return ret; 89 } 90 91 const char *arch_vma_name(struct vm_area_struct *vma) 92 { 93 if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso) 94 return "[vdso]"; 95 96 return NULL; 97 } 98 99 struct vm_area_struct *get_gate_vma(struct task_struct *task) 100 { 101 return NULL; 102 } 103 104 int in_gate_area(struct task_struct *task, unsigned long address) 105 { 106 return 0; 107 } 108 109 int in_gate_area_no_task(unsigned long address) 110 { 111 return 0; 112 } 113