From: will.deacon@arm.com (Will Deacon)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] arm: ptrace: fix syscall modification under PTRACE_O_TRACESECCOMP
Date: Fri, 20 Jun 2014 18:23:30 +0100 [thread overview]
Message-ID: <20140620172330.GA30656@arm.com> (raw)
In-Reply-To: <CAGXu5jKJ07bXw_K+7uSAf=H_SDoeoaWPxS4rwuonbR71Svwwmw@mail.gmail.com>
On Fri, Jun 20, 2014 at 05:44:52PM +0100, Kees Cook wrote:
> On Fri, Jun 20, 2014 at 3:22 AM, Will Deacon <will.deacon@arm.com> wrote:
> > I'm struggling to see the bug in the current code, so apologies if my
> > questions aren't helpful.
> >
> > On Wed, Jun 18, 2014 at 09:27:48PM +0100, Kees Cook wrote:
> >> An x86 tracer wanting to change the syscall uses PTRACE_SETREGS
> >> (stored to regs->orig_ax), and an ARM tracer uses PTRACE_SET_SYSCALL
> >> (stored to current_thread_info()->syscall). When this happens, the
> >> syscall can change across the call to secure_computing(), since it may
> >> block on tracer notification, and the tracer can then make changes
> >> to the process, before we return from secure_computing(). This
> >> means the code must respect the changed syscall after the
> >> secure_computing() call in syscall_trace_enter(). The same is true
> >> for tracehook_report_syscall_entry() which may also block and change
> >> the syscall.
> >
> > I don't think I understand what you mean by `the code must respect the
> > changed syscall'. The current code does indeed issue the new syscall, so are
> > you more concerned with secure_computing changing ->syscall, then the
> > debugger can't see the new syscall when it sees the trap from tracehook?
> > Are these even supposed to inter-operate?
>
> The problem is the use of "scno" in the call -- it results in ignoring
> the value that may be set up in ->syscall by a tracer:
>
> syscall_trace_enter(regs, scno):
> current_thread_info()->syscall = scno;
> secure_computing(scno):
> [block on ptrace]
> [ptracer changes current_thread_info()->syscall vis PTRACE_SET_SYSCALL]
> ...
> return scno;
>
> This means the tracer's changed syscall value will be ignored
> (syscall_trace_enter returns original "scno" instead of actual
> current_thread_info()->syscall). In the original code, failure cases
> were propagated correctly, but not tracer-induced changes.
>
> Is that more clear? It's not an obvious state (due to the external
> modification of process state during the ptrace blocking). I've also
> got tests for this, if that's useful to further illustrate:
>
> https://github.com/kees/seccomp/commit/bd24e174593f79784b97178b583f17e0ea9d2aa7
Right, gotcha. Thanks for the explanation. I was confused, because
tracehook_report_syscall does the right thing (returns
current_thread_info()->syscall), but if we don't have TIF_SYSCALL_TRACE set,
then updates during the secure_computing callback will be ignored.
However, my fix to this is significantly smaller than your patch, so I fear
I'm still missing something.
Will
--->8
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 0dd3b79b15c3..0c27ed6f3f23 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -908,7 +908,7 @@ enum ptrace_syscall_dir {
PTRACE_SYSCALL_EXIT,
};
-static int tracehook_report_syscall(struct pt_regs *regs,
+static void tracehook_report_syscall(struct pt_regs *regs,
enum ptrace_syscall_dir dir)
{
unsigned long ip;
@@ -926,7 +926,6 @@ static int tracehook_report_syscall(struct pt_regs *regs,
current_thread_info()->syscall = -1;
regs->ARM_ip = ip;
- return current_thread_info()->syscall;
}
asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
@@ -938,7 +937,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
return -1;
if (test_thread_flag(TIF_SYSCALL_TRACE))
- scno = tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+ tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+
+ scno = current_thread_info()->syscall;
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, scno);
WARNING: multiple messages have this Message-ID (diff)
From: Will Deacon <will.deacon@arm.com>
To: Kees Cook <keescook@chromium.org>
Cc: "linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"Russell King" <linux@arm.linux.org.uk>,
"Andy Lutomirski" <luto@amacapital.net>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Jonathan Austin" <Jonathan.Austin@arm.com>,
"André Hentschel" <nerv@dawncrow.de>,
"Oleg Nesterov" <oleg@redhat.com>,
"linux-arm-kernel@lists.infradead.org"
<linux-arm-kernel@lists.infradead.org>,
"Ricky Zhou" <rickyz@google.com>
Subject: Re: [PATCH] arm: ptrace: fix syscall modification under PTRACE_O_TRACESECCOMP
Date: Fri, 20 Jun 2014 18:23:30 +0100 [thread overview]
Message-ID: <20140620172330.GA30656@arm.com> (raw)
In-Reply-To: <CAGXu5jKJ07bXw_K+7uSAf=H_SDoeoaWPxS4rwuonbR71Svwwmw@mail.gmail.com>
On Fri, Jun 20, 2014 at 05:44:52PM +0100, Kees Cook wrote:
> On Fri, Jun 20, 2014 at 3:22 AM, Will Deacon <will.deacon@arm.com> wrote:
> > I'm struggling to see the bug in the current code, so apologies if my
> > questions aren't helpful.
> >
> > On Wed, Jun 18, 2014 at 09:27:48PM +0100, Kees Cook wrote:
> >> An x86 tracer wanting to change the syscall uses PTRACE_SETREGS
> >> (stored to regs->orig_ax), and an ARM tracer uses PTRACE_SET_SYSCALL
> >> (stored to current_thread_info()->syscall). When this happens, the
> >> syscall can change across the call to secure_computing(), since it may
> >> block on tracer notification, and the tracer can then make changes
> >> to the process, before we return from secure_computing(). This
> >> means the code must respect the changed syscall after the
> >> secure_computing() call in syscall_trace_enter(). The same is true
> >> for tracehook_report_syscall_entry() which may also block and change
> >> the syscall.
> >
> > I don't think I understand what you mean by `the code must respect the
> > changed syscall'. The current code does indeed issue the new syscall, so are
> > you more concerned with secure_computing changing ->syscall, then the
> > debugger can't see the new syscall when it sees the trap from tracehook?
> > Are these even supposed to inter-operate?
>
> The problem is the use of "scno" in the call -- it results in ignoring
> the value that may be set up in ->syscall by a tracer:
>
> syscall_trace_enter(regs, scno):
> current_thread_info()->syscall = scno;
> secure_computing(scno):
> [block on ptrace]
> [ptracer changes current_thread_info()->syscall vis PTRACE_SET_SYSCALL]
> ...
> return scno;
>
> This means the tracer's changed syscall value will be ignored
> (syscall_trace_enter returns original "scno" instead of actual
> current_thread_info()->syscall). In the original code, failure cases
> were propagated correctly, but not tracer-induced changes.
>
> Is that more clear? It's not an obvious state (due to the external
> modification of process state during the ptrace blocking). I've also
> got tests for this, if that's useful to further illustrate:
>
> https://github.com/kees/seccomp/commit/bd24e174593f79784b97178b583f17e0ea9d2aa7
Right, gotcha. Thanks for the explanation. I was confused, because
tracehook_report_syscall does the right thing (returns
current_thread_info()->syscall), but if we don't have TIF_SYSCALL_TRACE set,
then updates during the secure_computing callback will be ignored.
However, my fix to this is significantly smaller than your patch, so I fear
I'm still missing something.
Will
--->8
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 0dd3b79b15c3..0c27ed6f3f23 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -908,7 +908,7 @@ enum ptrace_syscall_dir {
PTRACE_SYSCALL_EXIT,
};
-static int tracehook_report_syscall(struct pt_regs *regs,
+static void tracehook_report_syscall(struct pt_regs *regs,
enum ptrace_syscall_dir dir)
{
unsigned long ip;
@@ -926,7 +926,6 @@ static int tracehook_report_syscall(struct pt_regs *regs,
current_thread_info()->syscall = -1;
regs->ARM_ip = ip;
- return current_thread_info()->syscall;
}
asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
@@ -938,7 +937,9 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
return -1;
if (test_thread_flag(TIF_SYSCALL_TRACE))
- scno = tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+ tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
+
+ scno = current_thread_info()->syscall;
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_enter(regs, scno);
next prev parent reply other threads:[~2014-06-20 17:23 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-06-18 20:27 [PATCH] arm: ptrace: fix syscall modification under PTRACE_O_TRACESECCOMP Kees Cook
2014-06-18 20:27 ` Kees Cook
2014-06-18 20:51 ` Andy Lutomirski
2014-06-18 20:51 ` Andy Lutomirski
2014-06-20 10:22 ` Will Deacon
2014-06-20 10:22 ` Will Deacon
2014-06-20 16:44 ` Kees Cook
2014-06-20 16:44 ` Kees Cook
2014-06-20 17:23 ` Will Deacon [this message]
2014-06-20 17:23 ` Will Deacon
2014-06-20 17:36 ` Kees Cook
2014-06-20 17:36 ` Kees Cook
2014-06-20 18:10 ` Kees Cook
2014-06-20 18:10 ` Kees Cook
2014-06-23 8:46 ` Will Deacon
2014-06-23 8:46 ` Will Deacon
2014-06-23 19:46 ` Kees Cook
2014-06-23 19:46 ` Kees Cook
2014-06-24 8:54 ` Will Deacon
2014-06-24 8:54 ` Will Deacon
2014-06-24 9:20 ` AKASHI Takahiro
2014-06-24 9:20 ` AKASHI Takahiro
2014-07-03 7:43 ` AKASHI Takahiro
2014-07-03 7:43 ` AKASHI Takahiro
2014-07-03 10:24 ` Will Deacon
2014-07-03 10:24 ` Will Deacon
2014-07-03 15:39 ` Andy Lutomirski
2014-07-03 15:39 ` Andy Lutomirski
2014-07-03 16:11 ` Will Deacon
2014-07-03 16:11 ` Will Deacon
2014-07-03 16:13 ` Andy Lutomirski
2014-07-03 16:13 ` Andy Lutomirski
2014-07-03 16:32 ` Will Deacon
2014-07-03 16:32 ` Will Deacon
2014-07-04 23:05 ` Andy Lutomirski
2014-07-04 23:05 ` Andy Lutomirski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140620172330.GA30656@arm.com \
--to=will.deacon@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.