Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1befa65 authored by Vasily Gorbik's avatar Vasily Gorbik Committed by Martin Schwidefsky
Browse files

s390/vdso: avoid 64-bit vdso mapping for compat tasks



vdso_fault used is_compat_task function (on s390 it tests "current"
thread_info flags) to distinguish compat tasks and map 31-bit vdso
pages. But "current" task might not correspond to mm context.

When 31-bit compat inferior is executed under gdb, gdb does
PTRACE_PEEKTEXT on vdso page, causing vdso_fault with "current" being
64-bit gdb process. So, 31-bit inferior ends up with 64-bit vdso mapped.

To avoid this problem a new compat_mm flag has been introduced into
mm context. This flag is used in vdso_fault and vdso_mremap instead
of is_compat_task.

Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 1c472d46
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ typedef struct {
	unsigned int uses_cmm:1;
	/* The gmaps associated with this context are allowed to use huge pages. */
	unsigned int allow_gmap_hpage_1m:1;
	/* The mmu context is for compat task */
	unsigned int compat_mm:1;
} mm_context_t;

#define INIT_MM_CONTEXT(name)						   \
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ static inline int init_new_context(struct task_struct *tsk,
	atomic_set(&mm->context.flush_count, 0);
	mm->context.gmap_asce = 0;
	mm->context.flush_mm = 0;
	mm->context.compat_mm = 0;
#ifdef CONFIG_PGSTE
	mm->context.alloc_pgste = page_table_allocate_pgste ||
		test_thread_flag(TIF_PGSTE) ||
+5 −3
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ static vm_fault_t vdso_fault(const struct vm_special_mapping *sm,
	vdso_pagelist = vdso64_pagelist;
	vdso_pages = vdso64_pages;
#ifdef CONFIG_COMPAT
	if (is_compat_task()) {
	if (vma->vm_mm->context.compat_mm) {
		vdso_pagelist = vdso32_pagelist;
		vdso_pages = vdso32_pages;
	}
@@ -77,7 +77,7 @@ static int vdso_mremap(const struct vm_special_mapping *sm,

	vdso_pages = vdso64_pages;
#ifdef CONFIG_COMPAT
	if (is_compat_task())
	if (vma->vm_mm->context.compat_mm)
		vdso_pages = vdso32_pages;
#endif

@@ -224,8 +224,10 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)

	vdso_pages = vdso64_pages;
#ifdef CONFIG_COMPAT
	if (is_compat_task())
	if (is_compat_task()) {
		vdso_pages = vdso32_pages;
		mm->context.compat_mm = 1;
	}
#endif
	/*
	 * vDSO has a problem and was disabled, just don't "enable" it for