Thread (40 messages) 40 messages, 5 authors, 2015-09-15

Re: v2 of seccomp filter c/r patches

From: Tycho Andersen <hidden>
Date: 2015-09-15 21:38:21
Also in: linux-api, lkml

Hi Andy,

On Tue, Sep 15, 2015 at 01:01:23PM -0700, Andy Lutomirski wrote:
On Tue, Sep 15, 2015 at 11:26 AM, Tycho Andersen
[off-list ref] wrote:
quoted
Hi Andy,

On Tue, Sep 15, 2015 at 11:13:51AM -0700, Andy Lutomirski wrote:
quoted
On Tue, Sep 15, 2015 at 9:07 AM, Tycho Andersen
[off-list ref] wrote:
quoted
Hi Andy,

On Mon, Sep 14, 2015 at 10:52:46AM -0700, Andy Lutomirski wrote:
quoted
I'm not sure I entirely like this solution...
Ok. Since we also aren't going to do all the eBPF stuff now, how about
something that looks like this:

struct seccomp_layer {
  unsigned int size;
  unsigned int type; /* SECCOMP_BPF_CLASSIC or SECCOMP_EBPF or ... */
  bool inherited;
  union {
    unsigned int insn_cnt;
    struct bpf_insn *insns;
  };
};

with a ptrace command:

ptrace(PTRACE_SECCOMP_DUMP_LAYER, pid, i, &layer);

If we save a pointer to the current seccomp filter on fork (if there
is one), then I think the inherited flag is just,

inherited = is_ancestor(child->seccomp.filter, child->seccomp.inherited_filter)
I'm lost.  What is the inherited flag for?
We need some way to expose the seccomp hierarchy, specifically which
filters are inherited, so that we can correctly restore the filter
tree for tasks that may use TSYNC in the future. You've mentioned that
you don't like kcmp, so this is an alternative to that.
My only objection to kcmp is that IMO it's a suboptimal interface and
could be better.  I have no problem with the general principle of
asking to compare two objects.
Ok, in that case I think we can get rid of all the inherited stuff,
and use kcmp to figure it out.
The thing I really don't have a good handle on is whether the seccomp
filter hierarchy should look more like A:

struct seccomp_filter {
    ...;
    struct seccomp_filter *prev;
};

with the seccomp_filter being the user-visible object

Or B:

struct seccomp_layer {
   ...;  /* BPF program, etc. */
}

struct seccomp_filter {
   struct seccomp_layer *layer;
   struct seccomp_filter *prev;
};  /* or equivalent */

with seccomp_layer being the user-visible object.

A is simpler to implement in a memory-efficient way, but it's less
flexible.  I haven't come up with a compelling use case for B where A
doesn't work, with the caveat that, if an fd points to a
seccomp_filter in model A, you can't attach it unless your current
state matches its "prev" state (or an ancestor thereof), which might
be a little bit awkward.
Perhaps, although I don't think it would be an issue for c/r.
Am I making more sense now?
Yes, thanks for the clarifications. I guess personally I'd probably
choose option A. If this (using kcmp and one of A/B) sounds good to
you, I'll start working on a set to do c/r that way.

Tycho
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help