Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1314589 > unrolled thread

[PATCH 31/33] bpf: Add __bpf_prog_run() to stacktool whitelist

Started byJosh Poimboeuf <jpoimboe@redhat.com>
First post2016-01-22 00:00 +0100
Last post2016-01-22 18:30 +0100
Articles 5 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH 31/33] bpf: Add __bpf_prog_run() to stacktool whitelist Josh Poimboeuf <jpoimboe@redhat.com> - 2016-01-22 00:00 +0100
    Re: [PATCH 31/33] bpf: Add __bpf_prog_run() to stacktool whitelist Daniel Borkmann <daniel@iogearbox.net> - 2016-01-22 00:00 +0100
    Re: [PATCH 31/33] bpf: Add __bpf_prog_run() to stacktool whitelist Alexei Starovoitov <alexei.starovoitov@gmail.com> - 2016-01-22 04:00 +0100
      Re: [PATCH 31/33] bpf: Add __bpf_prog_run() to stacktool whitelist Josh Poimboeuf <jpoimboe@redhat.com> - 2016-01-22 05:20 +0100
        Re: [PATCH 31/33] bpf: Add __bpf_prog_run() to stacktool whitelist Alexei Starovoitov <alexei.starovoitov@gmail.com> - 2016-01-22 18:30 +0100

#1314589 — [PATCH 31/33] bpf: Add __bpf_prog_run() to stacktool whitelist

FromJosh Poimboeuf <jpoimboe@redhat.com>
Date2016-01-22 00:00 +0100
Subject[PATCH 31/33] bpf: Add __bpf_prog_run() to stacktool whitelist
Message-ID<qTwmS-3nT-13@gated-at.bofh.it>
stacktool reports the following false positive warnings:

  stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x5c: sibling call from callable instruction with changed frame pointer
  stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x60: function has unreachable instruction
  stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x64: function has unreachable instruction
  [...]

It's confused by the following dynamic jump instruction in
__bpf_prog_run()::

  jmp     *(%r12,%rax,8)

which corresponds to the following line in the C code:

  goto *jumptable[insn->code];

There's no way for stacktool to deterministically find all possible
branch targets for a dynamic jump, so it can't verify this code.

In this case the jumps all stay within the function, and there's nothing
unusual going on related to the stack, so we can whitelist the function.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: netdev@vger.kernel.org
---
 kernel/bpf/core.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 972d9a8..7108a96 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -27,6 +27,7 @@
 #include <linux/random.h>
 #include <linux/moduleloader.h>
 #include <linux/bpf.h>
+#include <linux/stacktool.h>
 
 #include <asm/unaligned.h>
 
@@ -649,6 +650,7 @@ load_byte:
 		WARN_RATELIMIT(1, "unknown opcode %02x\n", insn->code);
 		return 0;
 }
+STACKTOOL_IGNORE_FUNC(__bpf_prog_run);
 
 bool bpf_prog_array_compatible(struct bpf_array *array,
 			       const struct bpf_prog *fp)
-- 
2.4.3

[toc] | [next] | [standalone]


#1314605

FromDaniel Borkmann <daniel@iogearbox.net>
Date2016-01-22 00:00 +0100
Message-ID<qTwmU-3nT-55@gated-at.bofh.it>
In reply to#1314589
On 01/21/2016 11:49 PM, Josh Poimboeuf wrote:
> stacktool reports the following false positive warnings:
>
>    stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x5c: sibling call from callable instruction with changed frame pointer
>    stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x60: function has unreachable instruction
>    stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x64: function has unreachable instruction
>    [...]
>
> It's confused by the following dynamic jump instruction in
> __bpf_prog_run()::
>
>    jmp     *(%r12,%rax,8)
>
> which corresponds to the following line in the C code:
>
>    goto *jumptable[insn->code];
>
> There's no way for stacktool to deterministically find all possible
> branch targets for a dynamic jump, so it can't verify this code.
>
> In this case the jumps all stay within the function, and there's nothing
> unusual going on related to the stack, so we can whitelist the function.
>
> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
> Cc: Alexei Starovoitov <ast@kernel.org>
> Cc: netdev@vger.kernel.org

Fine by me:

Acked-by: Daniel Borkmann <daniel@iogearbox.net>

[toc] | [prev] | [next] | [standalone]


#1314722

FromAlexei Starovoitov <alexei.starovoitov@gmail.com>
Date2016-01-22 04:00 +0100
Message-ID<qTA77-5UO-7@gated-at.bofh.it>
In reply to#1314589
On Thu, Jan 21, 2016 at 04:49:35PM -0600, Josh Poimboeuf wrote:
> stacktool reports the following false positive warnings:
> 
>   stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x5c: sibling call from callable instruction with changed frame pointer
>   stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x60: function has unreachable instruction
>   stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x64: function has unreachable instruction
>   [...]
> 
> It's confused by the following dynamic jump instruction in
> __bpf_prog_run()::
> 
>   jmp     *(%r12,%rax,8)
> 
> which corresponds to the following line in the C code:
> 
>   goto *jumptable[insn->code];
> 
> There's no way for stacktool to deterministically find all possible
> branch targets for a dynamic jump, so it can't verify this code.
> 
> In this case the jumps all stay within the function, and there's nothing
> unusual going on related to the stack, so we can whitelist the function.

well, few things are very unusual in this function.
did you see what JMP_CALL does? it's a call into a different function,
but not like typical indirect call. Will it be ok as well?

In general it's not possible for any tool to identify all possible
branch targets. bpf programs can be loaded on the fly and
jumping sequence will change.
So if this marking says 'don't bother analyzing this function because
it does sane stuff' that's probably not the case.
If this marking says 'don't bother analyzing, the stack may be crazy
from here on' then it's ok.

[toc] | [prev] | [next] | [standalone]


#1314743

FromJosh Poimboeuf <jpoimboe@redhat.com>
Date2016-01-22 05:20 +0100
Message-ID<qTBmy-74w-19@gated-at.bofh.it>
In reply to#1314722
On Thu, Jan 21, 2016 at 06:55:41PM -0800, Alexei Starovoitov wrote:
> On Thu, Jan 21, 2016 at 04:49:35PM -0600, Josh Poimboeuf wrote:
> > stacktool reports the following false positive warnings:
> > 
> >   stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x5c: sibling call from callable instruction with changed frame pointer
> >   stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x60: function has unreachable instruction
> >   stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x64: function has unreachable instruction
> >   [...]
> > 
> > It's confused by the following dynamic jump instruction in
> > __bpf_prog_run()::
> > 
> >   jmp     *(%r12,%rax,8)
> > 
> > which corresponds to the following line in the C code:
> > 
> >   goto *jumptable[insn->code];
> > 
> > There's no way for stacktool to deterministically find all possible
> > branch targets for a dynamic jump, so it can't verify this code.
> > 
> > In this case the jumps all stay within the function, and there's nothing
> > unusual going on related to the stack, so we can whitelist the function.
> 
> well, few things are very unusual in this function.
> did you see what JMP_CALL does? it's a call into a different function,
> but not like typical indirect call. Will it be ok as well?
> 
> In general it's not possible for any tool to identify all possible
> branch targets. bpf programs can be loaded on the fly and
> jumping sequence will change.
> So if this marking says 'don't bother analyzing this function because
> it does sane stuff' that's probably not the case.
> If this marking says 'don't bother analyzing, the stack may be crazy
> from here on' then it's ok.

So the tool doesn't need to follow all possible call targets.  Instead
it just verifies that all functions follow the frame pointer convention.
That way it doesn't matter *which* function is being called because they
all do the right thing.

But it *does* need to follow all jump targets, so that it can analyze
all possible code paths within the function itself.  With a dynamic
jump, it can't do that.

So the JMP_CALL is fine, but the goto *jumptable[insn->code] isn't.
(And BTW that's the only occurrence of such a dynamic jump table in the
entire kernel.)

-- 
Josh

[toc] | [prev] | [next] | [standalone]


#1315155

FromAlexei Starovoitov <alexei.starovoitov@gmail.com>
Date2016-01-22 18:30 +0100
Message-ID<qTNH4-7bM-5@gated-at.bofh.it>
In reply to#1314743
On Thu, Jan 21, 2016 at 10:13:02PM -0600, Josh Poimboeuf wrote:
> On Thu, Jan 21, 2016 at 06:55:41PM -0800, Alexei Starovoitov wrote:
> > On Thu, Jan 21, 2016 at 04:49:35PM -0600, Josh Poimboeuf wrote:
> > > stacktool reports the following false positive warnings:
> > > 
> > >   stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x5c: sibling call from callable instruction with changed frame pointer
> > >   stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x60: function has unreachable instruction
> > >   stacktool: kernel/bpf/core.o: __bpf_prog_run()+0x64: function has unreachable instruction
> > >   [...]
> > > 
> > > It's confused by the following dynamic jump instruction in
> > > __bpf_prog_run()::
> > > 
> > >   jmp     *(%r12,%rax,8)
> > > 
> > > which corresponds to the following line in the C code:
> > > 
> > >   goto *jumptable[insn->code];
> > > 
> > > There's no way for stacktool to deterministically find all possible
> > > branch targets for a dynamic jump, so it can't verify this code.
> > > 
> > > In this case the jumps all stay within the function, and there's nothing
> > > unusual going on related to the stack, so we can whitelist the function.
> > 
> > well, few things are very unusual in this function.
> > did you see what JMP_CALL does? it's a call into a different function,
> > but not like typical indirect call. Will it be ok as well?
> > 
> > In general it's not possible for any tool to identify all possible
> > branch targets. bpf programs can be loaded on the fly and
> > jumping sequence will change.
> > So if this marking says 'don't bother analyzing this function because
> > it does sane stuff' that's probably not the case.
> > If this marking says 'don't bother analyzing, the stack may be crazy
> > from here on' then it's ok.
> 
> So the tool doesn't need to follow all possible call targets.  Instead
> it just verifies that all functions follow the frame pointer convention.
> That way it doesn't matter *which* function is being called because they
> all do the right thing.
> 
> But it *does* need to follow all jump targets, so that it can analyze
> all possible code paths within the function itself.  With a dynamic
> jump, it can't do that.
> 
> So the JMP_CALL is fine, but the goto *jumptable[insn->code] isn't.
> (And BTW that's the only occurrence of such a dynamic jump table in the
> entire kernel.)

Acked-by: Alexei Starovoitov <ast@kernel.org>

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web