0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/binfmts.h>
0010 #include <linux/compat.h>
0011 #include <linux/elf.h>
0012 #include <linux/errno.h>
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/mm.h>
0016 #include <linux/slab.h>
0017 #include <linux/smp.h>
0018 #include <linux/time_namespace.h>
0019 #include <linux/random.h>
0020 #include <vdso/datapage.h>
0021 #include <asm/vdso.h>
0022
0023 extern char vdso64_start[], vdso64_end[];
0024 extern char vdso32_start[], vdso32_end[];
0025
0026 static struct vm_special_mapping vvar_mapping;
0027
0028 static union {
0029 struct vdso_data data[CS_BASES];
0030 u8 page[PAGE_SIZE];
0031 } vdso_data_store __page_aligned_data;
0032
0033 struct vdso_data *vdso_data = vdso_data_store.data;
0034
0035 enum vvar_pages {
0036 VVAR_DATA_PAGE_OFFSET,
0037 VVAR_TIMENS_PAGE_OFFSET,
0038 VVAR_NR_PAGES,
0039 };
0040
0041 #ifdef CONFIG_TIME_NS
0042 struct vdso_data *arch_get_vdso_data(void *vvar_page)
0043 {
0044 return (struct vdso_data *)(vvar_page);
0045 }
0046
0047 static struct page *find_timens_vvar_page(struct vm_area_struct *vma)
0048 {
0049 if (likely(vma->vm_mm == current->mm))
0050 return current->nsproxy->time_ns->vvar_page;
0051
0052
0053
0054
0055
0056
0057
0058 WARN(1, "vvar_page accessed remotely");
0059 return NULL;
0060 }
0061
0062
0063
0064
0065
0066
0067
0068
0069 int vdso_join_timens(struct task_struct *task, struct time_namespace *ns)
0070 {
0071 struct mm_struct *mm = task->mm;
0072 struct vm_area_struct *vma;
0073
0074 mmap_read_lock(mm);
0075 for (vma = mm->mmap; vma; vma = vma->vm_next) {
0076 unsigned long size = vma->vm_end - vma->vm_start;
0077
0078 if (!vma_is_special_mapping(vma, &vvar_mapping))
0079 continue;
0080 zap_page_range(vma, vma->vm_start, size);
0081 break;
0082 }
0083 mmap_read_unlock(mm);
0084 return 0;
0085 }
0086 #else
0087 static inline struct page *find_timens_vvar_page(struct vm_area_struct *vma)
0088 {
0089 return NULL;
0090 }
0091 #endif
0092
0093 static vm_fault_t vvar_fault(const struct vm_special_mapping *sm,
0094 struct vm_area_struct *vma, struct vm_fault *vmf)
0095 {
0096 struct page *timens_page = find_timens_vvar_page(vma);
0097 unsigned long addr, pfn;
0098 vm_fault_t err;
0099
0100 switch (vmf->pgoff) {
0101 case VVAR_DATA_PAGE_OFFSET:
0102 pfn = virt_to_pfn(vdso_data);
0103 if (timens_page) {
0104
0105
0106
0107
0108 addr = vmf->address + VVAR_TIMENS_PAGE_OFFSET * PAGE_SIZE;
0109 err = vmf_insert_pfn(vma, addr, pfn);
0110 if (unlikely(err & VM_FAULT_ERROR))
0111 return err;
0112 pfn = page_to_pfn(timens_page);
0113 }
0114 break;
0115 #ifdef CONFIG_TIME_NS
0116 case VVAR_TIMENS_PAGE_OFFSET:
0117
0118
0119
0120
0121
0122
0123
0124 if (!timens_page)
0125 return VM_FAULT_SIGBUS;
0126 pfn = virt_to_pfn(vdso_data);
0127 break;
0128 #endif
0129 default:
0130 return VM_FAULT_SIGBUS;
0131 }
0132 return vmf_insert_pfn(vma, vmf->address, pfn);
0133 }
0134
0135 static int vdso_mremap(const struct vm_special_mapping *sm,
0136 struct vm_area_struct *vma)
0137 {
0138 current->mm->context.vdso_base = vma->vm_start;
0139 return 0;
0140 }
0141
0142 static struct vm_special_mapping vvar_mapping = {
0143 .name = "[vvar]",
0144 .fault = vvar_fault,
0145 };
0146
0147 static struct vm_special_mapping vdso64_mapping = {
0148 .name = "[vdso]",
0149 .mremap = vdso_mremap,
0150 };
0151
0152 static struct vm_special_mapping vdso32_mapping = {
0153 .name = "[vdso]",
0154 .mremap = vdso_mremap,
0155 };
0156
0157 int vdso_getcpu_init(void)
0158 {
0159 set_tod_programmable_field(smp_processor_id());
0160 return 0;
0161 }
0162 early_initcall(vdso_getcpu_init);
0163
0164 static int map_vdso(unsigned long addr, unsigned long vdso_mapping_len)
0165 {
0166 unsigned long vvar_start, vdso_text_start, vdso_text_len;
0167 struct vm_special_mapping *vdso_mapping;
0168 struct mm_struct *mm = current->mm;
0169 struct vm_area_struct *vma;
0170 int rc;
0171
0172 BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES);
0173 if (mmap_write_lock_killable(mm))
0174 return -EINTR;
0175
0176 if (is_compat_task()) {
0177 vdso_text_len = vdso32_end - vdso32_start;
0178 vdso_mapping = &vdso32_mapping;
0179 } else {
0180 vdso_text_len = vdso64_end - vdso64_start;
0181 vdso_mapping = &vdso64_mapping;
0182 }
0183 vvar_start = get_unmapped_area(NULL, addr, vdso_mapping_len, 0, 0);
0184 rc = vvar_start;
0185 if (IS_ERR_VALUE(vvar_start))
0186 goto out;
0187 vma = _install_special_mapping(mm, vvar_start, VVAR_NR_PAGES*PAGE_SIZE,
0188 VM_READ|VM_MAYREAD|VM_IO|VM_DONTDUMP|
0189 VM_PFNMAP,
0190 &vvar_mapping);
0191 rc = PTR_ERR(vma);
0192 if (IS_ERR(vma))
0193 goto out;
0194 vdso_text_start = vvar_start + VVAR_NR_PAGES * PAGE_SIZE;
0195
0196 vma = _install_special_mapping(mm, vdso_text_start, vdso_text_len,
0197 VM_READ|VM_EXEC|
0198 VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
0199 vdso_mapping);
0200 if (IS_ERR(vma)) {
0201 do_munmap(mm, vvar_start, PAGE_SIZE, NULL);
0202 rc = PTR_ERR(vma);
0203 } else {
0204 current->mm->context.vdso_base = vdso_text_start;
0205 rc = 0;
0206 }
0207 out:
0208 mmap_write_unlock(mm);
0209 return rc;
0210 }
0211
0212 static unsigned long vdso_addr(unsigned long start, unsigned long len)
0213 {
0214 unsigned long addr, end, offset;
0215
0216
0217
0218
0219
0220 start = PAGE_ALIGN(start);
0221
0222
0223 end = (start + len + PMD_SIZE - 1) & PMD_MASK;
0224 if (end >= VDSO_BASE)
0225 end = VDSO_BASE;
0226 end -= len;
0227
0228 if (end > start) {
0229 offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1);
0230 addr = start + (offset << PAGE_SHIFT);
0231 } else {
0232 addr = start;
0233 }
0234 return addr;
0235 }
0236
0237 unsigned long vdso_size(void)
0238 {
0239 unsigned long size = VVAR_NR_PAGES * PAGE_SIZE;
0240
0241 if (is_compat_task())
0242 size += vdso32_end - vdso32_start;
0243 else
0244 size += vdso64_end - vdso64_start;
0245 return PAGE_ALIGN(size);
0246 }
0247
0248 int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
0249 {
0250 unsigned long addr = VDSO_BASE;
0251 unsigned long size = vdso_size();
0252
0253 if (current->flags & PF_RANDOMIZE)
0254 addr = vdso_addr(current->mm->start_stack + PAGE_SIZE, size);
0255 return map_vdso(addr, size);
0256 }
0257
0258 static struct page ** __init vdso_setup_pages(void *start, void *end)
0259 {
0260 int pages = (end - start) >> PAGE_SHIFT;
0261 struct page **pagelist;
0262 int i;
0263
0264 pagelist = kcalloc(pages + 1, sizeof(struct page *), GFP_KERNEL);
0265 if (!pagelist)
0266 panic("%s: Cannot allocate page list for VDSO", __func__);
0267 for (i = 0; i < pages; i++)
0268 pagelist[i] = virt_to_page(start + i * PAGE_SIZE);
0269 return pagelist;
0270 }
0271
0272 static int __init vdso_init(void)
0273 {
0274 vdso64_mapping.pages = vdso_setup_pages(vdso64_start, vdso64_end);
0275 if (IS_ENABLED(CONFIG_COMPAT))
0276 vdso32_mapping.pages = vdso_setup_pages(vdso32_start, vdso32_end);
0277 return 0;
0278 }
0279 arch_initcall(vdso_init);