On Thu, Feb 8, 2018 at 9:26 AM, Tom Hromatka <tom.hroma...@oracle.com> wrote:
> On 02/07/2018 08:30 PM, Paul Moore wrote:
>> On Wed, Feb 7, 2018 at 6:12 PM, Tom Hromatka <tom.hroma...@oracle.com>
>> wrote:
>>>
>>> On 02/07/2018 03:17 PM, Paul Moore wrote:
>>>>
>>>> * Improved performance is always good, but functional equivalency and
>>>> compatibility with the existing API/callers is another hard
>>>> requirement.  I mention this because of your comments regarding
>>>> argument filtering and hybrid BPF filters, can you elaborate a bit
>>>> more on the possible solutions to ensure this works under EBPF
>>>> (including hybrid options)?
>>>
>>> Agreed.  We cannot afford to break existing seccomp users.
>>>
>>> So this is purely theoretical, but I think it should work.  We could
>>> utilize seccomp's ability in the kernel to run multiple seccomp filters.
>>> The first filter to run would be the EBPF filter.  If it returns an
>>> action to run, we could bail out of the for() loop in
>>> seccomp_run_filters()
>>> early.  If not, continue running the cBPF filter(s) as usual. Existing
>>> seccomp users wouldn't even load an EBPF filter so their behavior would
>>> remain unchanged.
>>>
>>> On the libseccomp side, I would expect something like this:
>>>
>>> int sys_filter_load(struct db_filter_col *col)
>>> {
>>>      int rc;
>>>
>>>      /* load the classic BPF filter first */
>>>      rc = sys_bpf_filter_load(col);
>>>      if (rc < 0)
>>>          return rc;
>>>
>>>      /* process the EBPF filter.  note - it will only load a
>>>       * filter if it has been instructed to do so by the user.
>>>       * for classic seccomp filters this is effectively a nop
>>>       */
>>>      rc = sys_ebpf_filter_load(col);
>>>
>>>      return rc;
>>> }
>>
>> One of the gotchas with loading multiple filters is that the first,
>> and all non-final, filters need to allow the syscalls necessary to
>> load the additional filter (I'm not 100% on EBPF, but I believe it is
>> still just seccomp(2)).  Generally this is user/caller problem, but if
>> we are hiding the fact that we are loading two filters instead of one
>> we are going to need to do some additional work to ensure we can load
>> the second filter and not allow any syscalls the caller didn't intend.
>
> You are definitely correct.  The cBPF filter would have to
> (at a minimum) allow __NR_seccomp and __NR_bpf.  __NR_bpf is
> used to create and populate the EBPF map.
>
> If a user was especially security conscious, they would then
> need to block those syscalls in the EBPF map.  This is
> potentially error prone and slightly cumbersome.

Yes, exactly.

It's also not backwards compatible, you need a new(er) kernel for this
to work.  Like I said earlier, it might be easier to look into
improving the existing syscall sorting code in libseccomp; I believe
all the relevant code lives in src/gen_bpf.c:_gen_bpf_arch() and
should be relatively easy to play with ... much easier than the stuff
in src/db.c ;)

>> It might be a better use of time and energy to look into improving
>> libseccomp's filter generation, e.g. Kees' comments around
>> sorted-trees/qsort.

-- 
paul moore
www.paul-moore.com

-- 
You received this message because you are subscribed to the Google Groups 
"libseccomp" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to libseccomp+unsubscr...@googlegroups.com.
To post to this group, send email to libseccomp@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to