File Index
Files and directories
Sign in
FILE

vsyscall.c

File preview with syntax highlighting.

linux-6.19.14/arch/sh/kernel/vsyscall/vsyscall.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * arch/sh/kernel/vsyscall/vsyscall.c
  4 *
  5 *  Copyright (C) 2006 Paul Mundt
  6 *
  7 * vDSO randomization
  8 * Copyright(C) 2005-2006, Red Hat, Inc., Ingo Molnar
  9 */
 10#include <linux/mm.h>
 11#include <linux/kernel.h>
 12#include <linux/init.h>
 13#include <linux/gfp.h>
 14#include <linux/module.h>
 15#include <linux/elf.h>
 16#include <linux/sched.h>
 17#include <linux/sysctl.h>
 18#include <linux/err.h>
 19
 20/*
 21 * Should the kernel map a VDSO page into processes and pass its
 22 * address down to glibc upon exec()?
 23 */
 24unsigned int __read_mostly vdso_enabled = 1;
 25EXPORT_SYMBOL_GPL(vdso_enabled);
 26
 27static int __init vdso_setup(char *s)
 28{
 29	vdso_enabled = simple_strtoul(s, NULL, 0);
 30	return 1;
 31}
 32__setup("vdso=", vdso_setup);
 33
 34static const struct ctl_table vdso_table[] = {
 35	{
 36		.procname	= "vdso_enabled",
 37		.data		= &vdso_enabled,
 38		.maxlen		= sizeof(vdso_enabled),
 39		.mode		= 0644,
 40		.proc_handler	= proc_dointvec_minmax,
 41		.extra1		= SYSCTL_ZERO,
 42		.extra2		= SYSCTL_ONE,
 43	},
 44};
 45
 46/*
 47 * These symbols are defined by vsyscall.o to mark the bounds
 48 * of the ELF DSO images included therein.
 49 */
 50extern const char vsyscall_trapa_start, vsyscall_trapa_end;
 51static struct page *syscall_pages[1];
 52static struct vm_special_mapping vdso_mapping = {
 53	.name = "[vdso]",
 54	.pages = syscall_pages,
 55};
 56
 57int __init vsyscall_init(void)
 58{
 59	void *syscall_page = (void *)get_zeroed_page(GFP_ATOMIC);
 60	syscall_pages[0] = virt_to_page(syscall_page);
 61
 62	/*
 63	 * XXX: Map this page to a fixmap entry if we get around
 64	 * to adding the page to ELF core dumps
 65	 */
 66
 67	memcpy(syscall_page,
 68	       &vsyscall_trapa_start,
 69	       &vsyscall_trapa_end - &vsyscall_trapa_start);
 70
 71	return 0;
 72}
 73
 74static int __init vm_sysctl_init(void)
 75{
 76       register_sysctl_init("vm", vdso_table);
 77       return 0;
 78}
 79
 80fs_initcall(vm_sysctl_init);
 81
 82/* Setup a VMA at program startup for the vsyscall page */
 83int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
 84{
 85	struct mm_struct *mm = current->mm;
 86	struct vm_area_struct *vma;
 87	unsigned long addr;
 88	int ret;
 89
 90	if (mmap_write_lock_killable(mm))
 91		return -EINTR;
 92
 93	addr = get_unmapped_area(NULL, 0, PAGE_SIZE, 0, 0);
 94	if (IS_ERR_VALUE(addr)) {
 95		ret = addr;
 96		goto up_fail;
 97	}
 98
 99	vdso_mapping.pages = syscall_pages;
100	vma = _install_special_mapping(mm, addr, PAGE_SIZE,
101				      VM_READ | VM_EXEC |
102				      VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC,
103				      &vdso_mapping);
104	ret = PTR_ERR(vma);
105	if (IS_ERR(vma))
106		goto up_fail;
107
108	current->mm->context.vdso = (void *)addr;
109	ret = 0;
110
111up_fail:
112	mmap_write_unlock(mm);
113	return ret;
114}
115
116const char *arch_vma_name(struct vm_area_struct *vma)
117{
118	if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
119		return "[vdso]";
120
121	return NULL;
122}
~/ Read-only file preview.