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

Commit 3f063501 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
parents 0859ab59 d786a4a6
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -325,7 +325,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
	const struct user_regset_view *view;
	const struct user_regset_view *view;
	int ret;
	int ret;


	view = task_user_regset_view(child);
	view = task_user_regset_view(current);


	switch(request) {
	switch(request) {
	case PTRACE_GETREGS: {
	case PTRACE_GETREGS: {
+97 −51
Original line number Original line Diff line number Diff line
@@ -114,6 +114,85 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
	preempt_enable();
	preempt_enable();
}
}


static int get_from_target(struct task_struct *target, unsigned long uaddr,
			   void *kbuf, int len)
{
	if (target == current) {
		if (copy_from_user(kbuf, (void __user *) uaddr, len))
			return -EFAULT;
	} else {
		int len2 = access_process_vm(target, uaddr, kbuf, len, 0);
		if (len2 != len)
			return -EFAULT;
	}
	return 0;
}

static int set_to_target(struct task_struct *target, unsigned long uaddr,
			 void *kbuf, int len)
{
	if (target == current) {
		if (copy_to_user((void __user *) uaddr, kbuf, len))
			return -EFAULT;
	} else {
		int len2 = access_process_vm(target, uaddr, kbuf, len, 1);
		if (len2 != len)
			return -EFAULT;
	}
	return 0;
}

static int regwindow64_get(struct task_struct *target,
			   const struct pt_regs *regs,
			   struct reg_window *wbuf)
{
	unsigned long rw_addr = regs->u_regs[UREG_I6];

	if (test_tsk_thread_flag(current, TIF_32BIT)) {
		struct reg_window32 win32;
		int i;

		if (get_from_target(target, rw_addr, &win32, sizeof(win32)))
			return -EFAULT;
		for (i = 0; i < 8; i++)
			wbuf->locals[i] = win32.locals[i];
		for (i = 0; i < 8; i++)
			wbuf->ins[i] = win32.ins[i];
	} else {
		rw_addr += STACK_BIAS;
		if (get_from_target(target, rw_addr, wbuf, sizeof(*wbuf)))
			return -EFAULT;
	}

	return 0;
}

static int regwindow64_set(struct task_struct *target,
			   const struct pt_regs *regs,
			   struct reg_window *wbuf)
{
	unsigned long rw_addr = regs->u_regs[UREG_I6];

	if (test_tsk_thread_flag(current, TIF_32BIT)) {
		struct reg_window32 win32;
		int i;

		for (i = 0; i < 8; i++)
			win32.locals[i] = wbuf->locals[i];
		for (i = 0; i < 8; i++)
			win32.ins[i] = wbuf->ins[i];

		if (set_to_target(target, rw_addr, &win32, sizeof(win32)))
			return -EFAULT;
	} else {
		rw_addr += STACK_BIAS;
		if (set_to_target(target, rw_addr, wbuf, sizeof(*wbuf)))
			return -EFAULT;
	}

	return 0;
}

enum sparc_regset {
enum sparc_regset {
	REGSET_GENERAL,
	REGSET_GENERAL,
	REGSET_FP,
	REGSET_FP,
@@ -133,25 +212,13 @@ static int genregs64_get(struct task_struct *target,
	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
				  regs->u_regs,
				  regs->u_regs,
				  0, 16 * sizeof(u64));
				  0, 16 * sizeof(u64));
	if (!ret) {
	if (!ret && count && pos < (32 * sizeof(u64))) {
		unsigned long __user *reg_window = (unsigned long __user *)
		struct reg_window window;
			(regs->u_regs[UREG_I6] + STACK_BIAS);
		unsigned long window[16];


		if (target == current) {
		if (regwindow64_get(target, regs, &window))
			if (copy_from_user(window, reg_window, sizeof(window)))
			return -EFAULT;
			return -EFAULT;
		} else {
			if (access_process_vm(target,
					      (unsigned long) reg_window,
					      window,
					      sizeof(window), 0) !=
			    sizeof(window))
				return -EFAULT;
		}

		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
		ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
					  window,
					  &window,
					  16 * sizeof(u64),
					  16 * sizeof(u64),
					  32 * sizeof(u64));
					  32 * sizeof(u64));
	}
	}
@@ -173,10 +240,11 @@ static int genregs64_get(struct task_struct *target,
					  36 * sizeof(u64));
					  36 * sizeof(u64));
	}
	}


	if (!ret)
	if (!ret) {
		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
		ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
					       36 * sizeof(u64), -1);
					       36 * sizeof(u64), -1);


	}
	return ret;
	return ret;
}
}


@@ -194,43 +262,21 @@ static int genregs64_set(struct task_struct *target,
	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
				 regs->u_regs,
				 regs->u_regs,
				 0, 16 * sizeof(u64));
				 0, 16 * sizeof(u64));
	if (!ret && count > 0) {
	if (!ret && count && pos < (32 * sizeof(u64))) {
		unsigned long __user *reg_window = (unsigned long __user *)
		struct reg_window window;
			(regs->u_regs[UREG_I6] + STACK_BIAS);
		unsigned long window[16];


		if (target == current) {
		if (regwindow64_get(target, regs, &window))
			if (copy_from_user(window, reg_window, sizeof(window)))
				return -EFAULT;
		} else {
			if (access_process_vm(target,
					      (unsigned long) reg_window,
					      window,
					      sizeof(window), 0) !=
			    sizeof(window))
			return -EFAULT;
			return -EFAULT;
		}


		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
					 window,
					 &window,
					 16 * sizeof(u64),
					 16 * sizeof(u64),
					 32 * sizeof(u64));
					 32 * sizeof(u64));
		if (!ret) {

			if (target == current) {
		if (!ret &&
				if (copy_to_user(reg_window, window,
		    regwindow64_set(target, regs, &window))
						 sizeof(window)))
					return -EFAULT;
			} else {
				if (access_process_vm(target,
						      (unsigned long)
						      reg_window,
						      window,
						      sizeof(window), 1) !=
				    sizeof(window))
			return -EFAULT;
			return -EFAULT;
	}
	}
		}
	}


	if (!ret && count > 0) {
	if (!ret && count > 0) {
		unsigned long tstate;
		unsigned long tstate;
@@ -805,7 +851,7 @@ struct compat_fps {
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
			compat_ulong_t caddr, compat_ulong_t cdata)
			compat_ulong_t caddr, compat_ulong_t cdata)
{
{
	const struct user_regset_view *view = task_user_regset_view(child);
	const struct user_regset_view *view = task_user_regset_view(current);
	compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
	compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
	struct pt_regs32 __user *pregs;
	struct pt_regs32 __user *pregs;
	struct compat_fps __user *fps;
	struct compat_fps __user *fps;
@@ -913,7 +959,7 @@ struct fps {


long arch_ptrace(struct task_struct *child, long request, long addr, long data)
long arch_ptrace(struct task_struct *child, long request, long addr, long data)
{
{
	const struct user_regset_view *view = task_user_regset_view(child);
	const struct user_regset_view *view = task_user_regset_view(current);
	unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
	unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
	struct pt_regs __user *pregs;
	struct pt_regs __user *pregs;
	struct fps __user *fps;
	struct fps __user *fps;