Commit 47648303 authored by Yury Norov's avatar Yury Norov Committed by Chen Jun
Browse files

arm64: signal32: move ilp32 and aarch32 common code to separated file

maillist inclusion
category: feature
bugzilla: 46790
CVE: NA

Reference: https://github.com/norov/linux/commits/ilp32-5.2



--------------------------------

ILP32 needs to mix 32bit struct siginfo and 64bit sigframe for its signal
handlers. Move the existing compat code for copying siginfo to user space
and manipulating signal masks into signal32_common.c so it can be used to
deliver aarch32 and ilp32 signals.

Signed-off-by: default avatarYury Norov <ynorov@caviumnetworks.com>
Signed-off-by: default avatarYury Norov <ynorov@marvell.com>
Signed-off-by: default avatarXiongfeng Wang <wangxiongfeng2@huawei.com>
Acked-by: default avatarXie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: default avatarChen Jun <chenjun102@huawei.com>
parent c6b5fb4f
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */

#ifndef __ASM_SIGNAL32_COMMON_H
#define __ASM_SIGNAL32_COMMON_H

#ifdef CONFIG_COMPAT

int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set);
int get_sigset_t(sigset_t *set, const compat_sigset_t __user *uset);

#endif /* CONFIG_COMPAT*/

#endif /* __ASM_SIGNAL32_COMMON_H */
+2 −2
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ static int get_sigframe(struct rt_sigframe_user_layout *user,
	/*
	 * Check that we can actually write to the signal frame.
	 */
	if (!access_ok(VERIFY_WRITE, user->sigframe, sp_top - sp))
	if (!access_ok(user->sigframe, sp_top - sp))
		return -EFAULT;

	return 0;
@@ -252,7 +252,7 @@ static long __sys_rt_sigreturn(struct pt_regs *regs)

	frame = (struct rt_sigframe __user *)regs->sp;

	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
	if (!access_ok(frame, sizeof(*frame)))
		goto badframe;

	if (restore_sigframe(regs, frame))
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ obj-$(CONFIG_AARCH32_EL0) += binfmt_elf32.o sys32.o signal32.o \
obj-$(CONFIG_AARCH32_EL0)			+= sigreturn32.o
obj-$(CONFIG_KUSER_HELPERS)		+= kuser32.o
obj-$(CONFIG_ARM64_ILP32)		+= binfmt_ilp32.o sys_ilp32.o
obj-$(CONFIG_COMPAT)		+= sys32_common.o
obj-$(CONFIG_COMPAT)		+= sys32_common.o signal32_common.o
obj-$(CONFIG_FUNCTION_TRACER)		+= ftrace.o entry-ftrace.o
obj-$(CONFIG_MODULES)			+= module.o
obj-$(CONFIG_ARM64_MODULE_PLTS)		+= module-plts.o
+1 −22
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <asm/fpsimd.h>
#include <asm/signal32.h>
#include <asm/traps.h>
#include <asm/signal32_common.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
#include <asm/vdso.h>
@@ -48,28 +49,6 @@ struct a32_aux_sigframe {

#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))

static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
{
	compat_sigset_t	cset;

	cset.sig[0] = set->sig[0] & 0xffffffffull;
	cset.sig[1] = set->sig[0] >> 32;

	return copy_to_user(uset, &cset, sizeof(*uset));
}

static inline int get_sigset_t(sigset_t *set,
			       const compat_sigset_t __user *uset)
{
	compat_sigset_t s32;

	if (copy_from_user(&s32, uset, sizeof(*uset)))
		return -EFAULT;

	set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
	return 0;
}

/*
 * VFP save/restore code.
 *
+37 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0

/*
 * Based on arch/arm/kernel/signal.c
 *
 * Copyright (C) 1995-2009 Russell King
 * Copyright (C) 2012 ARM Ltd.
 * Modified by Will Deacon <will.deacon@arm.com>
 */

#include <linux/compat.h>
#include <linux/signal.h>
#include <linux/uaccess.h>

#include <asm/signal32_common.h>
#include <asm/unistd.h>

int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
{
	compat_sigset_t	cset;

	cset.sig[0] = set->sig[0] & 0xffffffffull;
	cset.sig[1] = set->sig[0] >> 32;

	return copy_to_user(uset, &cset, sizeof(*uset));
}

int get_sigset_t(sigset_t *set, const compat_sigset_t __user *uset)
{
	compat_sigset_t s32;

	if (copy_from_user(&s32, uset, sizeof(*uset)))
		return -EFAULT;

	set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);
	return 0;
}