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 > <tycho.andersen@xxxxxxxxxxxxx> wrote: > > Hi Andy, > > > > On Tue, Sep 15, 2015 at 11:13:51AM -0700, Andy Lutomirski wrote: > >> On Tue, Sep 15, 2015 at 9:07 AM, Tycho Andersen > >> <tycho.andersen@xxxxxxxxxxxxx> wrote: > >> > Hi Andy, > >> > > >> > On Mon, Sep 14, 2015 at 10:52:46AM -0700, Andy Lutomirski wrote: > >> >> > >> >> 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 -- To unsubscribe from this list: send the line "unsubscribe linux-api" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html