um/ptrace: Fix the syscall number update after a ptrace
Update the syscall number after each PTRACE_SETREGS on ORIG_*AX.
This is needed to get the potentially altered syscall number in the
seccomp filters after RET_TRACE.
This fix four seccomp_bpf tests:
> [ RUN ] TRACE_syscall.skip_after_RET_TRACE
> seccomp_bpf.c:1560:TRACE_syscall.skip_after_RET_TRACE:Expected -1 (18446744073709551615) == syscall(39) (26)
> seccomp_bpf.c:1561:TRACE_syscall.skip_after_RET_TRACE:Expected 1 (1) == (*__errno_location ()) (22)
> [ FAIL ] TRACE_syscall.skip_after_RET_TRACE
> [ RUN ] TRACE_syscall.kill_after_RET_TRACE
> TRACE_syscall.kill_after_RET_TRACE: Test exited normally instead of by signal (code: 1)
> [ FAIL ] TRACE_syscall.kill_after_RET_TRACE
> [ RUN ] TRACE_syscall.skip_after_ptrace
> seccomp_bpf.c:1622:TRACE_syscall.skip_after_ptrace:Expected -1 (18446744073709551615) == syscall(39) (26)
> seccomp_bpf.c:1623:TRACE_syscall.skip_after_ptrace:Expected 1 (1) == (*__errno_location ()) (22)
> [ FAIL ] TRACE_syscall.skip_after_ptrace
> [ RUN ] TRACE_syscall.kill_after_ptrace
> TRACE_syscall.kill_after_ptrace: Test exited normally instead of by signal (code: 1)
> [ FAIL ] TRACE_syscall.kill_after_ptrace
Fixes: 26703c636c
("um/ptrace: run seccomp after ptrace")
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Acked-by: Kees Cook <keescook@chromium.org>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Richard Weinberger <richard@nod.at>
Cc: James Morris <jmorris@namei.org>
Cc: user-mode-linux-devel@lists.sourceforge.net
Signed-off-by: James Morris <james.l.morris@oracle.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
This commit is contained in:
parent
972939e285
commit
ce29856a5e
3 changed files with 7 additions and 5 deletions
|
@ -27,12 +27,7 @@ void handle_syscall(struct uml_pt_regs *r)
|
|||
if (secure_computing(NULL) == -1)
|
||||
goto out;
|
||||
|
||||
/* Update the syscall number after orig_ax has potentially been updated
|
||||
* with ptrace.
|
||||
*/
|
||||
UPT_SYSCALL_NR(r) = PT_SYSCALL_NR(r->gp);
|
||||
syscall = UPT_SYSCALL_NR(r);
|
||||
|
||||
if (syscall >= 0 && syscall <= __NR_syscall_max)
|
||||
PT_REGS_SET_SYSCALL_RETURN(regs,
|
||||
EXECUTE_SYSCALL(syscall, regs));
|
||||
|
|
|
@ -84,7 +84,10 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
|
|||
case EAX:
|
||||
case EIP:
|
||||
case UESP:
|
||||
break;
|
||||
case ORIG_EAX:
|
||||
/* Update the syscall number. */
|
||||
UPT_SYSCALL_NR(&child->thread.regs.regs) = value;
|
||||
break;
|
||||
case FS:
|
||||
if (value && (value & 3) != 3)
|
||||
|
|
|
@ -78,7 +78,11 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
|
|||
case RSI:
|
||||
case RDI:
|
||||
case RBP:
|
||||
break;
|
||||
|
||||
case ORIG_RAX:
|
||||
/* Update the syscall number. */
|
||||
UPT_SYSCALL_NR(&child->thread.regs.regs) = value;
|
||||
break;
|
||||
|
||||
case FS:
|
||||
|
|
Loading…
Reference in a new issue