mirror of https://gitee.com/openkylin/linux.git
arm64: sanitize copy_thread(), switch to generic fork/vfork/clone
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
b9763ce33f
commit
9ac0800213
|
@ -33,6 +33,7 @@ config ARM64
|
||||||
select RTC_LIB
|
select RTC_LIB
|
||||||
select SPARSE_IRQ
|
select SPARSE_IRQ
|
||||||
select SYSCTL_EXCEPTION_TRACE
|
select SYSCTL_EXCEPTION_TRACE
|
||||||
|
select CLONE_BACKWARDS
|
||||||
help
|
help
|
||||||
ARM 64-bit (AArch64) Linux support.
|
ARM 64-bit (AArch64) Linux support.
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,8 @@ asmlinkage long sys_sigaltstack_wrapper(const stack_t __user *uss,
|
||||||
* AArch64 sys_clone implementation has a different prototype than the generic
|
* AArch64 sys_clone implementation has a different prototype than the generic
|
||||||
* one (additional TLS value argument).
|
* one (additional TLS value argument).
|
||||||
*/
|
*/
|
||||||
|
asmlinkage long sys_clone(unsigned long, unsigned long, void __user *, int,
|
||||||
|
void __user *);
|
||||||
#define sys_clone sys_clone
|
#define sys_clone sys_clone
|
||||||
|
|
||||||
#include <asm-generic/syscalls.h>
|
#include <asm-generic/syscalls.h>
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
#define __ARCH_WANT_SYS_SIGPROCMASK
|
#define __ARCH_WANT_SYS_SIGPROCMASK
|
||||||
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
|
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
|
||||||
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
|
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
|
||||||
|
#define __ARCH_WANT_SYS_FORK
|
||||||
|
#define __ARCH_WANT_SYS_VFORK
|
||||||
#endif
|
#endif
|
||||||
#define __ARCH_WANT_SYS_EXECVE
|
#define __ARCH_WANT_SYS_EXECVE
|
||||||
|
#define __ARCH_WANT_SYS_CLONE
|
||||||
#include <uapi/asm/unistd.h>
|
#include <uapi/asm/unistd.h>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
__SYSCALL(0, sys_restart_syscall)
|
__SYSCALL(0, sys_restart_syscall)
|
||||||
__SYSCALL(1, sys_exit)
|
__SYSCALL(1, sys_exit)
|
||||||
__SYSCALL(2, compat_sys_fork)
|
__SYSCALL(2, sys_fork)
|
||||||
__SYSCALL(3, sys_read)
|
__SYSCALL(3, sys_read)
|
||||||
__SYSCALL(4, sys_write)
|
__SYSCALL(4, sys_write)
|
||||||
__SYSCALL(5, compat_sys_open)
|
__SYSCALL(5, compat_sys_open)
|
||||||
|
@ -211,7 +211,7 @@ __SYSCALL(186, compat_sys_sigaltstack_wrapper)
|
||||||
__SYSCALL(187, compat_sys_sendfile)
|
__SYSCALL(187, compat_sys_sendfile)
|
||||||
__SYSCALL(188, sys_ni_syscall) /* 188 reserved */
|
__SYSCALL(188, sys_ni_syscall) /* 188 reserved */
|
||||||
__SYSCALL(189, sys_ni_syscall) /* 189 reserved */
|
__SYSCALL(189, sys_ni_syscall) /* 189 reserved */
|
||||||
__SYSCALL(190, compat_sys_vfork)
|
__SYSCALL(190, sys_vfork)
|
||||||
__SYSCALL(191, compat_sys_getrlimit) /* SuS compliant getrlimit */
|
__SYSCALL(191, compat_sys_getrlimit) /* SuS compliant getrlimit */
|
||||||
__SYSCALL(192, sys_mmap_pgoff)
|
__SYSCALL(192, sys_mmap_pgoff)
|
||||||
__SYSCALL(193, compat_sys_truncate64_wrapper)
|
__SYSCALL(193, compat_sys_truncate64_wrapper)
|
||||||
|
|
|
@ -235,15 +235,15 @@ asmlinkage void ret_from_fork(void) asm("ret_from_fork");
|
||||||
|
|
||||||
int copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
int copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
||||||
unsigned long stk_sz, struct task_struct *p,
|
unsigned long stk_sz, struct task_struct *p,
|
||||||
struct pt_regs *regs)
|
struct pt_regs *unused)
|
||||||
{
|
{
|
||||||
struct pt_regs *childregs = task_pt_regs(p);
|
struct pt_regs *childregs = task_pt_regs(p);
|
||||||
unsigned long tls = p->thread.tp_value;
|
unsigned long tls = p->thread.tp_value;
|
||||||
|
|
||||||
memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
|
memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
|
||||||
|
|
||||||
if (likely(regs)) {
|
if (likely(!(p->flags & PF_KTHREAD))) {
|
||||||
*childregs = *regs;
|
*childregs = *current_pt_regs();
|
||||||
childregs->regs[0] = 0;
|
childregs->regs[0] = 0;
|
||||||
if (is_compat_thread(task_thread_info(p))) {
|
if (is_compat_thread(task_thread_info(p))) {
|
||||||
if (stack_start)
|
if (stack_start)
|
||||||
|
@ -266,7 +266,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
||||||
* for the new thread.
|
* for the new thread.
|
||||||
*/
|
*/
|
||||||
if (clone_flags & CLONE_SETTLS)
|
if (clone_flags & CLONE_SETTLS)
|
||||||
tls = regs->regs[3];
|
tls = childregs->regs[3];
|
||||||
} else {
|
} else {
|
||||||
memset(childregs, 0, sizeof(struct pt_regs));
|
memset(childregs, 0, sizeof(struct pt_regs));
|
||||||
childregs->pstate = PSR_MODE_EL1h;
|
childregs->pstate = PSR_MODE_EL1h;
|
||||||
|
|
|
@ -26,17 +26,6 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/syscalls.h>
|
#include <linux/syscalls.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* Clone a task - this clones the calling program thread.
|
|
||||||
*/
|
|
||||||
asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
|
|
||||||
int __user *parent_tidptr, unsigned long tls_val,
|
|
||||||
int __user *child_tidptr)
|
|
||||||
{
|
|
||||||
return do_fork(clone_flags, newsp, current_pt_regs(), 0,
|
|
||||||
parent_tidptr, child_tidptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
|
asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
|
||||||
unsigned long prot, unsigned long flags,
|
unsigned long prot, unsigned long flags,
|
||||||
unsigned long fd, off_t off)
|
unsigned long fd, off_t off)
|
||||||
|
|
|
@ -28,17 +28,6 @@
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
#include <asm/unistd32.h>
|
#include <asm/unistd32.h>
|
||||||
|
|
||||||
asmlinkage int compat_sys_fork(void)
|
|
||||||
{
|
|
||||||
return do_fork(SIGCHLD, 0, current_pt_regs(), 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int compat_sys_vfork(void)
|
|
||||||
{
|
|
||||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
|
|
||||||
current_pt_regs(), 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
|
asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
|
||||||
struct compat_timespec __user *interval)
|
struct compat_timespec __user *interval)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue