[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20201124002932.1220517-18-dima@arista.com>
Date: Tue, 24 Nov 2020 00:29:30 +0000
From: Dmitry Safonov <dima@...sta.com>
To: linux-kernel@...r.kernel.org
Cc: Dmitry Safonov <0x7f454c46@...il.com>,
Dmitry Safonov <dima@...sta.com>,
Alexander Viro <viro@...iv.linux.org.uk>,
Andrew Morton <akpm@...ux-foundation.org>,
Andy Lutomirski <luto@...nel.org>,
Arnd Bergmann <arnd@...db.de>, Borislav Petkov <bp@...en8.de>,
Catalin Marinas <catalin.marinas@....com>,
Christophe Leroy <christophe.leroy@...roup.eu>,
Guo Ren <guoren@...nel.org>, "H. Peter Anvin" <hpa@...or.com>,
Ingo Molnar <mingo@...hat.com>,
Oleg Nesterov <oleg@...hat.com>,
Russell King <linux@...linux.org.uk>,
Thomas Bogendoerfer <tsbogend@...ha.franken.de>,
Thomas Gleixner <tglx@...utronix.de>,
Vincenzo Frascino <vincenzo.frascino@....com>,
Will Deacon <will@...nel.org>, x86@...nel.org
Subject: [PATCH v2 17/19] arm64/vdso: Migrate compat signals to generic vdso_base
Generic way to track the landing vma area.
As a bonus, after unmapping sigpage, kernel won't try to land on its
previous position (due to UNMAPPED_VDSO_BASE check instead of
context.vdso ?= 0 check).
Signed-off-by: Dmitry Safonov <dima@...sta.com>
---
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/signal32.c | 17 ++++++++++++-----
arch/arm64/kernel/vdso.c | 2 +-
3 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 35d8e4acd38d..a93ec99644b8 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -38,6 +38,7 @@ config ARM64
select ARCH_HAS_SYSCALL_WRAPPER
select ARCH_HAS_TEARDOWN_DMA_OPS if IOMMU_SUPPORT
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+ select ARCH_HAS_VDSO_BASE
select ARCH_HAVE_ELF_PROT
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_INLINE_READ_LOCK if !PREEMPTION
diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c
index 2f507f565c48..3d2ac8062e99 100644
--- a/arch/arm64/kernel/signal32.c
+++ b/arch/arm64/kernel/signal32.c
@@ -315,7 +315,7 @@ static void __user *compat_get_sigframe(struct ksignal *ksig,
return frame;
}
-static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+static int compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
compat_ulong_t __user *rc, void __user *frame,
int usig)
{
@@ -342,13 +342,16 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
retcode = ptr_to_compat(ka->sa.sa_restorer);
} else {
/* Set up sigreturn pointer */
+ unsigned long land = (unsigned long)current->mm->vdso_base;
unsigned int idx = thumb << 1;
if (ka->sa.sa_flags & SA_SIGINFO)
idx += 3;
- retcode = (unsigned long)current->mm->context.sigpage +
- (idx << 2) + thumb;
+ if (land == UNMAPPED_VDSO_BASE)
+ return 1;
+
+ retcode = land + (idx << 2) + thumb;
}
regs->regs[0] = usig;
@@ -356,6 +359,8 @@ static void compat_setup_return(struct pt_regs *regs, struct k_sigaction *ka,
regs->compat_lr = retcode;
regs->pc = handler;
regs->pstate = spsr;
+
+ return 0;
}
static int compat_setup_sigframe(struct compat_sigframe __user *sf,
@@ -425,7 +430,8 @@ int compat_setup_rt_frame(int usig, struct ksignal *ksig,
err |= compat_setup_sigframe(&frame->sig, regs, set);
if (err == 0) {
- compat_setup_return(regs, &ksig->ka, frame->sig.retcode, frame, usig);
+ err = compat_setup_return(regs, &ksig->ka,
+ frame->sig.retcode, frame, usig);
regs->regs[1] = (compat_ulong_t)(unsigned long)&frame->info;
regs->regs[2] = (compat_ulong_t)(unsigned long)&frame->sig.uc;
}
@@ -448,7 +454,8 @@ int compat_setup_frame(int usig, struct ksignal *ksig, sigset_t *set,
err |= compat_setup_sigframe(frame, regs, set);
if (err == 0)
- compat_setup_return(regs, &ksig->ka, frame->retcode, frame, usig);
+ err = compat_setup_return(regs, &ksig->ka,
+ frame->retcode, frame, usig);
return err;
}
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 91c1b7c716b7..03a6519d50cd 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -394,7 +394,7 @@ static int aarch32_sigreturn_setup(struct mm_struct *mm)
if (IS_ERR(ret))
goto out;
- mm->context.sigpage = (void *)addr;
+ mm->vdso_base = (void __user *)addr;
out:
return PTR_ERR_OR_ZERO(ret);
--
2.29.2
Powered by blists - more mailing lists