Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Eric Paris
On Fri, 2013-03-15 at 11:45 -0700, Kees Cook wrote:
> On Fri, Mar 15, 2013 at 11:28 AM, Nicolas Schichan  
> wrote:

> > diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
> > index 6f19cfd..af27494 100644
> > --- a/include/linux/seccomp.h
> > +++ b/include/linux/seccomp.h
> > @@ -6,6 +6,7 @@
> >  #ifdef CONFIG_SECCOMP
> >
> >  #include 
> > +#include 
> >  #include 
> >
> >  struct seccomp_filter;
> > @@ -47,6 +48,44 @@ static inline int seccomp_mode(struct seccomp *s)
> > return s->mode;
> >  }
> >
> > +/**
> > + * struct seccomp_filter - container for seccomp BPF programs
> > + *
> > + * @usage: reference count to manage the object lifetime.
> > + * get/put helpers should be used when accessing an instance
> > + * outside of a lifetime-guarded section.  In general, this
> > + * is only needed for handling filters shared across tasks.
> > + * @prev: points to a previously installed, or inherited, filter
> > + * @len: the number of instructions in the program
> > + * @insns: the BPF program instructions to evaluate
> 
> This should be updated to include the new bpf_func field.
> 
> Regardless, it'd be better to not expose this structure to userspace.

This is fine

include/uapi/linux/seccomp.h is exposed to userspace
include/linux/seccomp.h is  kernel internal

-Eric

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Nicolas Schichan

On 03/15/2013 08:22 PM, Kees Cook wrote:

On Fri, Mar 15, 2013 at 12:10 PM, Nicolas Schichan  wrote:

On 03/15/2013 07:45 PM, Kees Cook wrote:



Yes, I did not realise that this header was exported to userspace. Do you
know any place not exported to userspace where the structure definition
would be appropriate ?


Nothing really jumps to mind. :( We should probably do the uapi split,
so that this can stay here, but the public stuff is in the other file.
I'm not actually sure what's needed to do that split, though.


Would putting the structure definition in a  file be 
acceptable ? Or is there some preprocessor macro that could prevent part of an 
include file ending up in uapi (similar to __KERNEL__ or __ASSEMBLY__).



Regarding JIT spraying, I believe ARM is actually worse than x86 in that
regard, since the values appearing in the literal pool can be quite easily
controlled by an attacker.


Yeah, same for x86, really. Masking these would be nice, but is
probably a separate discussion.


I meant that ARM makes it even easier in that you don't even have to 
interleave the evil immediate between instruction. The instruction sequence 
will appear verbatim in the litteral pool.


For instance the following BPF code:

struct sock_filter code[] = {
{ BPF_LD, 0, 0, 0xe3a01a02 },
{ BPF_LD, 0, 0, 0xe2411001 },
{ BPF_LD, 0, 0, 0xe00d1001 },
{ BPF_LD, 0, 0, 0xe59111a0 },
{ BPF_LD, 0, 0, 0xe3a02000 },
{ BPF_LD, 0, 0, 0xe5812004 },
{ BPF_LD, 0, 0, 0xe1a0f00e },
{ BPF_RET, 0, 0, 0 },
};

Produces this ARM code:

BPF JIT code: bf00: e92d0010 e3a04000 e59f4020 e59f4020
BPF JIT code: bf10: e59f4020 e59f4020 e59f4020 e59f4020
BPF JIT code: bf20: e59f4020 e3a0 e8bd0010 e12fff1e
BPF JIT code: bf30: e3a01a02 e2411001 e00d1001 e59111a0
BPF JIT code: bf40: e3a02000 e5812004 e1a0f00e

Parts of which disassembles to (only eye-tested):

mov r1, #8192
sub r1, r1, #1   @ r1 = THREAD_SIZE - 1
and r1, sp, r1   @ get current.
ldr r1, [r1, #416]   @ get current->real_cred
mov r2, #0
str r2, [r1, #4] @ store 0 in current->real_cread->uid.
mov pc, lr

Userland can insert code to change the uid of the current process quite easily 
in an executable page. The only remaining task is to trick the kernel into 
executing it :)


Regards,

--
Nicolas Schichan
Freebox SAS
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Kees Cook
On Fri, Mar 15, 2013 at 12:10 PM, Nicolas Schichan  wrote:
> On 03/15/2013 07:45 PM, Kees Cook wrote:
>>
>> On Fri, Mar 15, 2013 at 11:28 AM, Nicolas Schichan 
>> wrote:
>>>
>>> +/**
>>> + * struct seccomp_filter - container for seccomp BPF programs
>>> + *
>>> + * @usage: reference count to manage the object lifetime.
>>> + * get/put helpers should be used when accessing an instance
>>> + * outside of a lifetime-guarded section.  In general, this
>>> + * is only needed for handling filters shared across tasks.
>>> + * @prev: points to a previously installed, or inherited, filter
>>> + * @len: the number of instructions in the program
>>> + * @insns: the BPF program instructions to evaluate
>>
>>
>> This should be updated to include the new bpf_func field.
>
> Sure, I'll fix this in a re-spin of the patch serie.
>
>> Regardless, it'd be better to not expose this structure to userspace.
>
> Yes, I did not realise that this header was exported to userspace. Do you
> know any place not exported to userspace where the structure definition
> would be appropriate ?

Nothing really jumps to mind. :( We should probably do the uapi split,
so that this can stay here, but the public stuff is in the other file.
I'm not actually sure what's needed to do that split, though.

>>> @@ -213,7 +185,7 @@ static u32 seccomp_run_filters(int syscall)
>>>   * value always takes priority (ignoring the DATA).
>>>   */
>>>  for (f = current->seccomp.filter; f; f = f->prev) {
>>> -   u32 cur_ret = sk_run_filter(NULL, f->insns);
>>> +   u32 cur_ret = f->bpf_func(NULL, f->insns);
>>
>> This will make bpf_func a rather attractive target inside the kernel.
>> I wonder if there could be ways to harden it against potential attack.
>
> I'm not sure I follow, but is it because any user can install a SECCOMP
> filter which will trigger JIT code generation with potential JIT spraying
> attack payload ?

I actually mean that when an arbitrary write vulnerability is used
against the kernel, finding bpf_func may make a good target since it
hangs off the process stack. There are plenty of targets, but just
wonder if there would be some trivial way to handle this. Probably
not. :)

> In that case, the same problem exists with struct sk_filter->bpf_func, as
> SO_ATTACH_FILTER, with BPT JIT enabled, does not require any particular
> privilege AFAICS.

Yeah, these problems aren't unique to seccomp, unfortunately.

> Regarding JIT spraying, I believe ARM is actually worse than x86 in that
> regard, since the values appearing in the literal pool can be quite easily
> controlled by an attacker.

Yeah, same for x86, really. Masking these would be nice, but is
probably a separate discussion.

> Thanks for the review.

Sure thing! I think Will Drewry may have more suggestions as well.

-Kees

-- 
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Nicolas Schichan

On 03/15/2013 07:45 PM, Kees Cook wrote:

On Fri, Mar 15, 2013 at 11:28 AM, Nicolas Schichan  wrote:

+/**
+ * struct seccomp_filter - container for seccomp BPF programs
+ *
+ * @usage: reference count to manage the object lifetime.
+ * get/put helpers should be used when accessing an instance
+ * outside of a lifetime-guarded section.  In general, this
+ * is only needed for handling filters shared across tasks.
+ * @prev: points to a previously installed, or inherited, filter
+ * @len: the number of instructions in the program
+ * @insns: the BPF program instructions to evaluate


This should be updated to include the new bpf_func field.


Sure, I'll fix this in a re-spin of the patch serie.


Regardless, it'd be better to not expose this structure to userspace.


Yes, I did not realise that this header was exported to userspace. Do you know 
any place not exported to userspace where the structure definition would be 
appropriate ?



@@ -213,7 +185,7 @@ static u32 seccomp_run_filters(int syscall)
  * value always takes priority (ignoring the DATA).
  */
 for (f = current->seccomp.filter; f; f = f->prev) {
-   u32 cur_ret = sk_run_filter(NULL, f->insns);
+   u32 cur_ret = f->bpf_func(NULL, f->insns);


This will make bpf_func a rather attractive target inside the kernel.
I wonder if there could be ways to harden it against potential attack.


I'm not sure I follow, but is it because any user can install a SECCOMP filter 
which will trigger JIT code generation with potential JIT spraying attack 
payload ?


In that case, the same problem exists with struct sk_filter->bpf_func, as 
SO_ATTACH_FILTER, with BPT JIT enabled, does not require any particular 
privilege AFAICS.


Regarding JIT spraying, I believe ARM is actually worse than x86 in that 
regard, since the values appearing in the literal pool can be quite easily 
controlled by an attacker.


Thanks for the review.

Regards,

--
Nicolas Schichan
Freebox SAS
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Kees Cook
On Fri, Mar 15, 2013 at 11:28 AM, Nicolas Schichan  wrote:
> Architecture must select HAVE_SECCOMP_FILTER_JIT and implement
> seccomp_jit_compile() and seccomp_jit_free() if they intend to support
> jitted seccomp filters.
>
> struct seccomp_filter has been moved to  to make its
> content available to the jit compilation code.
>
> In a way similar to the net BPF, the jit compilation code is expected
> to updates struct seccomp_filter.bpf_func pointer to the generated
> code.

Exciting. :) Thanks for working on this!

>
> Signed-off-by: Nicolas Schichan 
> ---
>  arch/Kconfig|   14 ++
>  include/linux/seccomp.h |   39 +++
>  kernel/seccomp.c|   34 +-
>  3 files changed, 58 insertions(+), 29 deletions(-)
>
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 5a1779c..1284367 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -339,6 +339,10 @@ config HAVE_ARCH_SECCOMP_FILTER
>   - secure_computing return value is checked and a return value of -1
> results in the system call being skipped immediately.
>
> +# Used by archs to tell that they support SECCOMP_FILTER_JIT
> +config HAVE_SECCOMP_FILTER_JIT
> +   bool
> +
>  config SECCOMP_FILTER
> def_bool y
> depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET
> @@ -349,6 +353,16 @@ config SECCOMP_FILTER
>
>   See Documentation/prctl/seccomp_filter.txt for details.
>
> +config SECCOMP_FILTER_JIT
> +   bool "enable Seccomp filter Just In Time compiler"
> +   depends on HAVE_SECCOMP_FILTER_JIT && BPF_JIT && SECCOMP_FILTER
> +   help
> + Seccomp syscall filtering capabilities are normally handled
> + by an interpreter. This option allows kernel to generate a native
> + code when filter is loaded in memory. This should speedup
> + syscall filtering. Note : Admin should enable this feature
> + changing /proc/sys/net/core/bpf_jit_enable
> +
>  config HAVE_CONTEXT_TRACKING
> bool
> help
> diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
> index 6f19cfd..af27494 100644
> --- a/include/linux/seccomp.h
> +++ b/include/linux/seccomp.h
> @@ -6,6 +6,7 @@
>  #ifdef CONFIG_SECCOMP
>
>  #include 
> +#include 
>  #include 
>
>  struct seccomp_filter;
> @@ -47,6 +48,44 @@ static inline int seccomp_mode(struct seccomp *s)
> return s->mode;
>  }
>
> +/**
> + * struct seccomp_filter - container for seccomp BPF programs
> + *
> + * @usage: reference count to manage the object lifetime.
> + * get/put helpers should be used when accessing an instance
> + * outside of a lifetime-guarded section.  In general, this
> + * is only needed for handling filters shared across tasks.
> + * @prev: points to a previously installed, or inherited, filter
> + * @len: the number of instructions in the program
> + * @insns: the BPF program instructions to evaluate

This should be updated to include the new bpf_func field.

Regardless, it'd be better to not expose this structure to userspace.

> + *
> + * seccomp_filter objects are organized in a tree linked via the @prev
> + * pointer.  For any task, it appears to be a singly-linked list starting
> + * with current->seccomp.filter, the most recently attached or inherited 
> filter.
> + * However, multiple filters may share a @prev node, by way of fork(), which
> + * results in a unidirectional tree existing in memory.  This is similar to
> + * how namespaces work.
> + *
> + * seccomp_filter objects should never be modified after being attached
> + * to a task_struct (other than @usage).
> + */
> +struct seccomp_filter {
> +   atomic_t usage;
> +   struct seccomp_filter *prev;
> +   unsigned short len;  /* Instruction count */
> +   unsigned int (*bpf_func)(const struct sk_buff *skb,
> +const struct sock_filter *filter);
> +   struct sock_filter insns[];
> +};
> +
> +#ifdef CONFIG_SECCOMP_FILTER_JIT
> +extern void seccomp_jit_compile(struct seccomp_filter *fp);
> +extern void seccomp_jit_free(struct seccomp_filter *fp);
> +#else
> +static inline void seccomp_jit_compile(struct seccomp_filter *fp) { }
> +static inline void seccomp_jit_free(struct seccomp_filter *fp) { }
> +#endif
> +
>  #else /* CONFIG_SECCOMP */
>
>  #include 
> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
> index b7a1004..a1aadaa 100644
> --- a/kernel/seccomp.c
> +++ b/kernel/seccomp.c
> @@ -30,34 +30,6 @@
>  #include 
>  #include 
>
> -/**
> - * struct seccomp_filter - container for seccomp BPF programs
> - *
> - * @usage: reference count to manage the object lifetime.
> - * get/put helpers should be used when accessing an instance
> - * outside of a lifetime-guarded section.  In general, this
> - * is only needed for handling filters shared across tasks.
> - * @prev: points to a previously installed, or inherited, filter
> - * @len: the number of 

Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Nicolas Schichan

On 03/15/2013 07:28 PM, Nicolas Schichan wrote:
[Sorry, I forgot to put the mailing lists as the receivers of the introductory 
message]


Hi,

This patch serie adds support for jitted seccomp BPF filters, with the
required modifications to make it work on the ARM architecture.

- The first patch in the serie adds the required boiler plate in the
  core kernel seccomp code to invoke the JIT compilation/free code.

- The second patch reworks the ARM BPF JIT code to make the generation
  process less dependent on struct sk_filter.

- The last patch actually implements the ARM part in the BPF jit code.

Some benchmarks, on a 1.6Ghz 88f6282 CPU:

Each system call is tested in two way (fast/slow):

 - on the fast version, the tested system call is accepted immediately
   after checking the architecture (5 BPF instructions).

 - on the slow version, the tested system call is accepted after
   previously checking for 85 syscall (90 instructions, including the
   architecture check).

The tested syscall is invoked in a loop 100 time, the reported
time is the time spent in the loop in seconds.

Without Seccomp JIT:

Syscall Time-Fast  Time-Slow
--- -- --
gettimeofday0.389  1.633
getpid  0.406  1.688
getresuid   1.003  2.266
getcwd  1.342  2.128

With Seccomp JIT:

Syscall Time-Fast  Time-Slow
--- --- -
gettimeofday0.348   0.428
getpid  0.365   0.480
getresuid   0.981   1.060
getcwd  1.237   1.294

For reference, the same code without any seccomp filter:

Syscall Time
--- -
gettimeofday0.119
getpid  0.137
getresuid   0.747
getcwd  1.021

The activation of the BPF JIT for seccomp is still controled with the
/proc/sys/net/core/bpf_jit_enable sysctl knob.

Those changes are based on the latest rmk-for-next branch.

Regards,

--
Nicolas Schichan
Freebox SAS
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Nicolas Schichan
Architecture must select HAVE_SECCOMP_FILTER_JIT and implement
seccomp_jit_compile() and seccomp_jit_free() if they intend to support
jitted seccomp filters.

struct seccomp_filter has been moved to  to make its
content available to the jit compilation code.

In a way similar to the net BPF, the jit compilation code is expected
to updates struct seccomp_filter.bpf_func pointer to the generated
code.

Signed-off-by: Nicolas Schichan 
---
 arch/Kconfig|   14 ++
 include/linux/seccomp.h |   39 +++
 kernel/seccomp.c|   34 +-
 3 files changed, 58 insertions(+), 29 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 5a1779c..1284367 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -339,6 +339,10 @@ config HAVE_ARCH_SECCOMP_FILTER
  - secure_computing return value is checked and a return value of -1
results in the system call being skipped immediately.
 
+# Used by archs to tell that they support SECCOMP_FILTER_JIT
+config HAVE_SECCOMP_FILTER_JIT
+   bool
+
 config SECCOMP_FILTER
def_bool y
depends on HAVE_ARCH_SECCOMP_FILTER && SECCOMP && NET
@@ -349,6 +353,16 @@ config SECCOMP_FILTER
 
  See Documentation/prctl/seccomp_filter.txt for details.
 
+config SECCOMP_FILTER_JIT
+   bool "enable Seccomp filter Just In Time compiler"
+   depends on HAVE_SECCOMP_FILTER_JIT && BPF_JIT && SECCOMP_FILTER
+   help
+ Seccomp syscall filtering capabilities are normally handled
+ by an interpreter. This option allows kernel to generate a native
+ code when filter is loaded in memory. This should speedup
+ syscall filtering. Note : Admin should enable this feature
+ changing /proc/sys/net/core/bpf_jit_enable
+
 config HAVE_CONTEXT_TRACKING
bool
help
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 6f19cfd..af27494 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -6,6 +6,7 @@
 #ifdef CONFIG_SECCOMP
 
 #include 
+#include 
 #include 
 
 struct seccomp_filter;
@@ -47,6 +48,44 @@ static inline int seccomp_mode(struct seccomp *s)
return s->mode;
 }
 
+/**
+ * struct seccomp_filter - container for seccomp BPF programs
+ *
+ * @usage: reference count to manage the object lifetime.
+ * get/put helpers should be used when accessing an instance
+ * outside of a lifetime-guarded section.  In general, this
+ * is only needed for handling filters shared across tasks.
+ * @prev: points to a previously installed, or inherited, filter
+ * @len: the number of instructions in the program
+ * @insns: the BPF program instructions to evaluate
+ *
+ * seccomp_filter objects are organized in a tree linked via the @prev
+ * pointer.  For any task, it appears to be a singly-linked list starting
+ * with current->seccomp.filter, the most recently attached or inherited 
filter.
+ * However, multiple filters may share a @prev node, by way of fork(), which
+ * results in a unidirectional tree existing in memory.  This is similar to
+ * how namespaces work.
+ *
+ * seccomp_filter objects should never be modified after being attached
+ * to a task_struct (other than @usage).
+ */
+struct seccomp_filter {
+   atomic_t usage;
+   struct seccomp_filter *prev;
+   unsigned short len;  /* Instruction count */
+   unsigned int (*bpf_func)(const struct sk_buff *skb,
+const struct sock_filter *filter);
+   struct sock_filter insns[];
+};
+
+#ifdef CONFIG_SECCOMP_FILTER_JIT
+extern void seccomp_jit_compile(struct seccomp_filter *fp);
+extern void seccomp_jit_free(struct seccomp_filter *fp);
+#else
+static inline void seccomp_jit_compile(struct seccomp_filter *fp) { }
+static inline void seccomp_jit_free(struct seccomp_filter *fp) { }
+#endif
+
 #else /* CONFIG_SECCOMP */
 
 #include 
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index b7a1004..a1aadaa 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -30,34 +30,6 @@
 #include 
 #include 
 
-/**
- * struct seccomp_filter - container for seccomp BPF programs
- *
- * @usage: reference count to manage the object lifetime.
- * get/put helpers should be used when accessing an instance
- * outside of a lifetime-guarded section.  In general, this
- * is only needed for handling filters shared across tasks.
- * @prev: points to a previously installed, or inherited, filter
- * @len: the number of instructions in the program
- * @insns: the BPF program instructions to evaluate
- *
- * seccomp_filter objects are organized in a tree linked via the @prev
- * pointer.  For any task, it appears to be a singly-linked list starting
- * with current->seccomp.filter, the most recently attached or inherited 
filter.
- * However, multiple filters may share a @prev node, by way of fork(), which
- * results in a unidirectional tree existing in memory.  This is 

[PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Nicolas Schichan
Architecture must select HAVE_SECCOMP_FILTER_JIT and implement
seccomp_jit_compile() and seccomp_jit_free() if they intend to support
jitted seccomp filters.

struct seccomp_filter has been moved to linux/seccomp.h to make its
content available to the jit compilation code.

In a way similar to the net BPF, the jit compilation code is expected
to updates struct seccomp_filter.bpf_func pointer to the generated
code.

Signed-off-by: Nicolas Schichan nschic...@freebox.fr
---
 arch/Kconfig|   14 ++
 include/linux/seccomp.h |   39 +++
 kernel/seccomp.c|   34 +-
 3 files changed, 58 insertions(+), 29 deletions(-)

diff --git a/arch/Kconfig b/arch/Kconfig
index 5a1779c..1284367 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -339,6 +339,10 @@ config HAVE_ARCH_SECCOMP_FILTER
  - secure_computing return value is checked and a return value of -1
results in the system call being skipped immediately.
 
+# Used by archs to tell that they support SECCOMP_FILTER_JIT
+config HAVE_SECCOMP_FILTER_JIT
+   bool
+
 config SECCOMP_FILTER
def_bool y
depends on HAVE_ARCH_SECCOMP_FILTER  SECCOMP  NET
@@ -349,6 +353,16 @@ config SECCOMP_FILTER
 
  See Documentation/prctl/seccomp_filter.txt for details.
 
+config SECCOMP_FILTER_JIT
+   bool enable Seccomp filter Just In Time compiler
+   depends on HAVE_SECCOMP_FILTER_JIT  BPF_JIT  SECCOMP_FILTER
+   help
+ Seccomp syscall filtering capabilities are normally handled
+ by an interpreter. This option allows kernel to generate a native
+ code when filter is loaded in memory. This should speedup
+ syscall filtering. Note : Admin should enable this feature
+ changing /proc/sys/net/core/bpf_jit_enable
+
 config HAVE_CONTEXT_TRACKING
bool
help
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
index 6f19cfd..af27494 100644
--- a/include/linux/seccomp.h
+++ b/include/linux/seccomp.h
@@ -6,6 +6,7 @@
 #ifdef CONFIG_SECCOMP
 
 #include linux/thread_info.h
+#include linux/filter.h
 #include asm/seccomp.h
 
 struct seccomp_filter;
@@ -47,6 +48,44 @@ static inline int seccomp_mode(struct seccomp *s)
return s-mode;
 }
 
+/**
+ * struct seccomp_filter - container for seccomp BPF programs
+ *
+ * @usage: reference count to manage the object lifetime.
+ * get/put helpers should be used when accessing an instance
+ * outside of a lifetime-guarded section.  In general, this
+ * is only needed for handling filters shared across tasks.
+ * @prev: points to a previously installed, or inherited, filter
+ * @len: the number of instructions in the program
+ * @insns: the BPF program instructions to evaluate
+ *
+ * seccomp_filter objects are organized in a tree linked via the @prev
+ * pointer.  For any task, it appears to be a singly-linked list starting
+ * with current-seccomp.filter, the most recently attached or inherited 
filter.
+ * However, multiple filters may share a @prev node, by way of fork(), which
+ * results in a unidirectional tree existing in memory.  This is similar to
+ * how namespaces work.
+ *
+ * seccomp_filter objects should never be modified after being attached
+ * to a task_struct (other than @usage).
+ */
+struct seccomp_filter {
+   atomic_t usage;
+   struct seccomp_filter *prev;
+   unsigned short len;  /* Instruction count */
+   unsigned int (*bpf_func)(const struct sk_buff *skb,
+const struct sock_filter *filter);
+   struct sock_filter insns[];
+};
+
+#ifdef CONFIG_SECCOMP_FILTER_JIT
+extern void seccomp_jit_compile(struct seccomp_filter *fp);
+extern void seccomp_jit_free(struct seccomp_filter *fp);
+#else
+static inline void seccomp_jit_compile(struct seccomp_filter *fp) { }
+static inline void seccomp_jit_free(struct seccomp_filter *fp) { }
+#endif
+
 #else /* CONFIG_SECCOMP */
 
 #include linux/errno.h
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index b7a1004..a1aadaa 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -30,34 +30,6 @@
 #include linux/tracehook.h
 #include linux/uaccess.h
 
-/**
- * struct seccomp_filter - container for seccomp BPF programs
- *
- * @usage: reference count to manage the object lifetime.
- * get/put helpers should be used when accessing an instance
- * outside of a lifetime-guarded section.  In general, this
- * is only needed for handling filters shared across tasks.
- * @prev: points to a previously installed, or inherited, filter
- * @len: the number of instructions in the program
- * @insns: the BPF program instructions to evaluate
- *
- * seccomp_filter objects are organized in a tree linked via the @prev
- * pointer.  For any task, it appears to be a singly-linked list starting
- * with current-seccomp.filter, the most recently attached or inherited 
filter.
- * However, multiple filters may 

Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Nicolas Schichan

On 03/15/2013 07:28 PM, Nicolas Schichan wrote:
[Sorry, I forgot to put the mailing lists as the receivers of the introductory 
message]


Hi,

This patch serie adds support for jitted seccomp BPF filters, with the
required modifications to make it work on the ARM architecture.

- The first patch in the serie adds the required boiler plate in the
  core kernel seccomp code to invoke the JIT compilation/free code.

- The second patch reworks the ARM BPF JIT code to make the generation
  process less dependent on struct sk_filter.

- The last patch actually implements the ARM part in the BPF jit code.

Some benchmarks, on a 1.6Ghz 88f6282 CPU:

Each system call is tested in two way (fast/slow):

 - on the fast version, the tested system call is accepted immediately
   after checking the architecture (5 BPF instructions).

 - on the slow version, the tested system call is accepted after
   previously checking for 85 syscall (90 instructions, including the
   architecture check).

The tested syscall is invoked in a loop 100 time, the reported
time is the time spent in the loop in seconds.

Without Seccomp JIT:

Syscall Time-Fast  Time-Slow
--- -- --
gettimeofday0.389  1.633
getpid  0.406  1.688
getresuid   1.003  2.266
getcwd  1.342  2.128

With Seccomp JIT:

Syscall Time-Fast  Time-Slow
--- --- -
gettimeofday0.348   0.428
getpid  0.365   0.480
getresuid   0.981   1.060
getcwd  1.237   1.294

For reference, the same code without any seccomp filter:

Syscall Time
--- -
gettimeofday0.119
getpid  0.137
getresuid   0.747
getcwd  1.021

The activation of the BPF JIT for seccomp is still controled with the
/proc/sys/net/core/bpf_jit_enable sysctl knob.

Those changes are based on the latest rmk-for-next branch.

Regards,

--
Nicolas Schichan
Freebox SAS
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Kees Cook
On Fri, Mar 15, 2013 at 11:28 AM, Nicolas Schichan nschic...@freebox.fr wrote:
 Architecture must select HAVE_SECCOMP_FILTER_JIT and implement
 seccomp_jit_compile() and seccomp_jit_free() if they intend to support
 jitted seccomp filters.

 struct seccomp_filter has been moved to linux/seccomp.h to make its
 content available to the jit compilation code.

 In a way similar to the net BPF, the jit compilation code is expected
 to updates struct seccomp_filter.bpf_func pointer to the generated
 code.

Exciting. :) Thanks for working on this!


 Signed-off-by: Nicolas Schichan nschic...@freebox.fr
 ---
  arch/Kconfig|   14 ++
  include/linux/seccomp.h |   39 +++
  kernel/seccomp.c|   34 +-
  3 files changed, 58 insertions(+), 29 deletions(-)

 diff --git a/arch/Kconfig b/arch/Kconfig
 index 5a1779c..1284367 100644
 --- a/arch/Kconfig
 +++ b/arch/Kconfig
 @@ -339,6 +339,10 @@ config HAVE_ARCH_SECCOMP_FILTER
   - secure_computing return value is checked and a return value of -1
 results in the system call being skipped immediately.

 +# Used by archs to tell that they support SECCOMP_FILTER_JIT
 +config HAVE_SECCOMP_FILTER_JIT
 +   bool
 +
  config SECCOMP_FILTER
 def_bool y
 depends on HAVE_ARCH_SECCOMP_FILTER  SECCOMP  NET
 @@ -349,6 +353,16 @@ config SECCOMP_FILTER

   See Documentation/prctl/seccomp_filter.txt for details.

 +config SECCOMP_FILTER_JIT
 +   bool enable Seccomp filter Just In Time compiler
 +   depends on HAVE_SECCOMP_FILTER_JIT  BPF_JIT  SECCOMP_FILTER
 +   help
 + Seccomp syscall filtering capabilities are normally handled
 + by an interpreter. This option allows kernel to generate a native
 + code when filter is loaded in memory. This should speedup
 + syscall filtering. Note : Admin should enable this feature
 + changing /proc/sys/net/core/bpf_jit_enable
 +
  config HAVE_CONTEXT_TRACKING
 bool
 help
 diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
 index 6f19cfd..af27494 100644
 --- a/include/linux/seccomp.h
 +++ b/include/linux/seccomp.h
 @@ -6,6 +6,7 @@
  #ifdef CONFIG_SECCOMP

  #include linux/thread_info.h
 +#include linux/filter.h
  #include asm/seccomp.h

  struct seccomp_filter;
 @@ -47,6 +48,44 @@ static inline int seccomp_mode(struct seccomp *s)
 return s-mode;
  }

 +/**
 + * struct seccomp_filter - container for seccomp BPF programs
 + *
 + * @usage: reference count to manage the object lifetime.
 + * get/put helpers should be used when accessing an instance
 + * outside of a lifetime-guarded section.  In general, this
 + * is only needed for handling filters shared across tasks.
 + * @prev: points to a previously installed, or inherited, filter
 + * @len: the number of instructions in the program
 + * @insns: the BPF program instructions to evaluate

This should be updated to include the new bpf_func field.

Regardless, it'd be better to not expose this structure to userspace.

 + *
 + * seccomp_filter objects are organized in a tree linked via the @prev
 + * pointer.  For any task, it appears to be a singly-linked list starting
 + * with current-seccomp.filter, the most recently attached or inherited 
 filter.
 + * However, multiple filters may share a @prev node, by way of fork(), which
 + * results in a unidirectional tree existing in memory.  This is similar to
 + * how namespaces work.
 + *
 + * seccomp_filter objects should never be modified after being attached
 + * to a task_struct (other than @usage).
 + */
 +struct seccomp_filter {
 +   atomic_t usage;
 +   struct seccomp_filter *prev;
 +   unsigned short len;  /* Instruction count */
 +   unsigned int (*bpf_func)(const struct sk_buff *skb,
 +const struct sock_filter *filter);
 +   struct sock_filter insns[];
 +};
 +
 +#ifdef CONFIG_SECCOMP_FILTER_JIT
 +extern void seccomp_jit_compile(struct seccomp_filter *fp);
 +extern void seccomp_jit_free(struct seccomp_filter *fp);
 +#else
 +static inline void seccomp_jit_compile(struct seccomp_filter *fp) { }
 +static inline void seccomp_jit_free(struct seccomp_filter *fp) { }
 +#endif
 +
  #else /* CONFIG_SECCOMP */

  #include linux/errno.h
 diff --git a/kernel/seccomp.c b/kernel/seccomp.c
 index b7a1004..a1aadaa 100644
 --- a/kernel/seccomp.c
 +++ b/kernel/seccomp.c
 @@ -30,34 +30,6 @@
  #include linux/tracehook.h
  #include linux/uaccess.h

 -/**
 - * struct seccomp_filter - container for seccomp BPF programs
 - *
 - * @usage: reference count to manage the object lifetime.
 - * get/put helpers should be used when accessing an instance
 - * outside of a lifetime-guarded section.  In general, this
 - * is only needed for handling filters shared across tasks.
 - * @prev: points to a previously installed, or inherited, filter
 - * @len: the 

Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Nicolas Schichan

On 03/15/2013 07:45 PM, Kees Cook wrote:

On Fri, Mar 15, 2013 at 11:28 AM, Nicolas Schichan nschic...@freebox.fr wrote:

+/**
+ * struct seccomp_filter - container for seccomp BPF programs
+ *
+ * @usage: reference count to manage the object lifetime.
+ * get/put helpers should be used when accessing an instance
+ * outside of a lifetime-guarded section.  In general, this
+ * is only needed for handling filters shared across tasks.
+ * @prev: points to a previously installed, or inherited, filter
+ * @len: the number of instructions in the program
+ * @insns: the BPF program instructions to evaluate


This should be updated to include the new bpf_func field.


Sure, I'll fix this in a re-spin of the patch serie.


Regardless, it'd be better to not expose this structure to userspace.


Yes, I did not realise that this header was exported to userspace. Do you know 
any place not exported to userspace where the structure definition would be 
appropriate ?



@@ -213,7 +185,7 @@ static u32 seccomp_run_filters(int syscall)
  * value always takes priority (ignoring the DATA).
  */
 for (f = current-seccomp.filter; f; f = f-prev) {
-   u32 cur_ret = sk_run_filter(NULL, f-insns);
+   u32 cur_ret = f-bpf_func(NULL, f-insns);


This will make bpf_func a rather attractive target inside the kernel.
I wonder if there could be ways to harden it against potential attack.


I'm not sure I follow, but is it because any user can install a SECCOMP filter 
which will trigger JIT code generation with potential JIT spraying attack 
payload ?


In that case, the same problem exists with struct sk_filter-bpf_func, as 
SO_ATTACH_FILTER, with BPT JIT enabled, does not require any particular 
privilege AFAICS.


Regarding JIT spraying, I believe ARM is actually worse than x86 in that 
regard, since the values appearing in the literal pool can be quite easily 
controlled by an attacker.


Thanks for the review.

Regards,

--
Nicolas Schichan
Freebox SAS
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Kees Cook
On Fri, Mar 15, 2013 at 12:10 PM, Nicolas Schichan nschic...@freebox.fr wrote:
 On 03/15/2013 07:45 PM, Kees Cook wrote:

 On Fri, Mar 15, 2013 at 11:28 AM, Nicolas Schichan nschic...@freebox.fr
 wrote:

 +/**
 + * struct seccomp_filter - container for seccomp BPF programs
 + *
 + * @usage: reference count to manage the object lifetime.
 + * get/put helpers should be used when accessing an instance
 + * outside of a lifetime-guarded section.  In general, this
 + * is only needed for handling filters shared across tasks.
 + * @prev: points to a previously installed, or inherited, filter
 + * @len: the number of instructions in the program
 + * @insns: the BPF program instructions to evaluate


 This should be updated to include the new bpf_func field.

 Sure, I'll fix this in a re-spin of the patch serie.

 Regardless, it'd be better to not expose this structure to userspace.

 Yes, I did not realise that this header was exported to userspace. Do you
 know any place not exported to userspace where the structure definition
 would be appropriate ?

Nothing really jumps to mind. :( We should probably do the uapi split,
so that this can stay here, but the public stuff is in the other file.
I'm not actually sure what's needed to do that split, though.

 @@ -213,7 +185,7 @@ static u32 seccomp_run_filters(int syscall)
   * value always takes priority (ignoring the DATA).
   */
  for (f = current-seccomp.filter; f; f = f-prev) {
 -   u32 cur_ret = sk_run_filter(NULL, f-insns);
 +   u32 cur_ret = f-bpf_func(NULL, f-insns);

 This will make bpf_func a rather attractive target inside the kernel.
 I wonder if there could be ways to harden it against potential attack.

 I'm not sure I follow, but is it because any user can install a SECCOMP
 filter which will trigger JIT code generation with potential JIT spraying
 attack payload ?

I actually mean that when an arbitrary write vulnerability is used
against the kernel, finding bpf_func may make a good target since it
hangs off the process stack. There are plenty of targets, but just
wonder if there would be some trivial way to handle this. Probably
not. :)

 In that case, the same problem exists with struct sk_filter-bpf_func, as
 SO_ATTACH_FILTER, with BPT JIT enabled, does not require any particular
 privilege AFAICS.

Yeah, these problems aren't unique to seccomp, unfortunately.

 Regarding JIT spraying, I believe ARM is actually worse than x86 in that
 regard, since the values appearing in the literal pool can be quite easily
 controlled by an attacker.

Yeah, same for x86, really. Masking these would be nice, but is
probably a separate discussion.

 Thanks for the review.

Sure thing! I think Will Drewry may have more suggestions as well.

-Kees

-- 
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Nicolas Schichan

On 03/15/2013 08:22 PM, Kees Cook wrote:

On Fri, Mar 15, 2013 at 12:10 PM, Nicolas Schichan nschic...@freebox.fr wrote:

On 03/15/2013 07:45 PM, Kees Cook wrote:



Yes, I did not realise that this header was exported to userspace. Do you
know any place not exported to userspace where the structure definition
would be appropriate ?


Nothing really jumps to mind. :( We should probably do the uapi split,
so that this can stay here, but the public stuff is in the other file.
I'm not actually sure what's needed to do that split, though.


Would putting the structure definition in a linux/seccomp_priv.h file be 
acceptable ? Or is there some preprocessor macro that could prevent part of an 
include file ending up in uapi (similar to __KERNEL__ or __ASSEMBLY__).



Regarding JIT spraying, I believe ARM is actually worse than x86 in that
regard, since the values appearing in the literal pool can be quite easily
controlled by an attacker.


Yeah, same for x86, really. Masking these would be nice, but is
probably a separate discussion.


I meant that ARM makes it even easier in that you don't even have to 
interleave the evil immediate between instruction. The instruction sequence 
will appear verbatim in the litteral pool.


For instance the following BPF code:

struct sock_filter code[] = {
{ BPF_LD, 0, 0, 0xe3a01a02 },
{ BPF_LD, 0, 0, 0xe2411001 },
{ BPF_LD, 0, 0, 0xe00d1001 },
{ BPF_LD, 0, 0, 0xe59111a0 },
{ BPF_LD, 0, 0, 0xe3a02000 },
{ BPF_LD, 0, 0, 0xe5812004 },
{ BPF_LD, 0, 0, 0xe1a0f00e },
{ BPF_RET, 0, 0, 0 },
};

Produces this ARM code:

BPF JIT code: bf00: e92d0010 e3a04000 e59f4020 e59f4020
BPF JIT code: bf10: e59f4020 e59f4020 e59f4020 e59f4020
BPF JIT code: bf20: e59f4020 e3a0 e8bd0010 e12fff1e
BPF JIT code: bf30: e3a01a02 e2411001 e00d1001 e59111a0
BPF JIT code: bf40: e3a02000 e5812004 e1a0f00e

Parts of which disassembles to (only eye-tested):

mov r1, #8192
sub r1, r1, #1   @ r1 = THREAD_SIZE - 1
and r1, sp, r1   @ get current.
ldr r1, [r1, #416]   @ get current-real_cred
mov r2, #0
str r2, [r1, #4] @ store 0 in current-real_cread-uid.
mov pc, lr

Userland can insert code to change the uid of the current process quite easily 
in an executable page. The only remaining task is to trick the kernel into 
executing it :)


Regards,

--
Nicolas Schichan
Freebox SAS
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH RFC 1/3] seccomp: add generic code for jitted seccomp filters.

2013-03-15 Thread Eric Paris
On Fri, 2013-03-15 at 11:45 -0700, Kees Cook wrote:
 On Fri, Mar 15, 2013 at 11:28 AM, Nicolas Schichan nschic...@freebox.fr 
 wrote:

  diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h
  index 6f19cfd..af27494 100644
  --- a/include/linux/seccomp.h
  +++ b/include/linux/seccomp.h
  @@ -6,6 +6,7 @@
   #ifdef CONFIG_SECCOMP
 
   #include linux/thread_info.h
  +#include linux/filter.h
   #include asm/seccomp.h
 
   struct seccomp_filter;
  @@ -47,6 +48,44 @@ static inline int seccomp_mode(struct seccomp *s)
  return s-mode;
   }
 
  +/**
  + * struct seccomp_filter - container for seccomp BPF programs
  + *
  + * @usage: reference count to manage the object lifetime.
  + * get/put helpers should be used when accessing an instance
  + * outside of a lifetime-guarded section.  In general, this
  + * is only needed for handling filters shared across tasks.
  + * @prev: points to a previously installed, or inherited, filter
  + * @len: the number of instructions in the program
  + * @insns: the BPF program instructions to evaluate
 
 This should be updated to include the new bpf_func field.
 
 Regardless, it'd be better to not expose this structure to userspace.

This is fine

include/uapi/linux/seccomp.h is exposed to userspace
include/linux/seccomp.h is  kernel internal

-Eric

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/