From: Tycho Andersen <tycho.andersen@canonical.com>
To: Andy Lutomirski <luto@amacapital.net>
Cc: Kees Cook <keescook@chromium.org>,
Alexei Starovoitov <ast@kernel.org>,
Will Drewry <wad@chromium.org>, Oleg Nesterov <oleg@redhat.com>,
Pavel Emelyanov <xemul@parallels.com>,
"Serge E. Hallyn" <serge.hallyn@ubuntu.com>,
Daniel Borkmann <daniel@iogearbox.net>,
LKML <linux-kernel@vger.kernel.org>,
Network Development <netdev@vger.kernel.org>,
Cyrill Gorcunov <gorcunov@parallels.com>
Subject: Re: [PATCH 3/6] ebpf: add a way to dump an eBPF program
Date: Fri, 4 Sep 2015 18:27:27 -0600 [thread overview]
Message-ID: <20150905002727.GA3890@hopstrocity> (raw)
In-Reply-To: <CALCETrUY7B381DrzfDSvmDyZ98KAdWMHvpbJffJ0_ApjzH-Kbw@mail.gmail.com>
On Fri, Sep 04, 2015 at 04:08:53PM -0700, Andy Lutomirski wrote:
> On Fri, Sep 4, 2015 at 3:28 PM, Tycho Andersen
> <tycho.andersen@canonical.com> wrote:
> > On Fri, Sep 04, 2015 at 02:48:03PM -0700, Andy Lutomirski wrote:
> >> On Fri, Sep 4, 2015 at 1:45 PM, Tycho Andersen
> >> <tycho.andersen@canonical.com> wrote:
> >> > On Fri, Sep 04, 2015 at 01:17:30PM -0700, Kees Cook wrote:
> >> >> On Fri, Sep 4, 2015 at 9:04 AM, Tycho Andersen
> >> >> <tycho.andersen@canonical.com> wrote:
> >> >> > This commit adds a way to dump eBPF programs. The initial implementation
> >> >> > doesn't support maps, and therefore only allows dumping seccomp ebpf
> >> >> > programs which themselves don't currently support maps.
> >> >> >
> >> >> > We export the GPL bit as well as a unique ID for the program so that
> >> >>
> >> >> This unique ID appears to be the heap address for the prog. That's a
> >> >> huge leak, and should not be done. We don't want to introduce new
> >> >> kernel address leaks while we're trying to fix the remaining ones.
> >> >> Shouldn't the "unique ID" be the fd itself? I imagine KCMP_FILE
> >> >> could be used, for example.
> >> >
> >> > No; we acquire the fd per process, so if a task installs a filter and
> >> > then forks N times, we'll grab N (+1) copies of the filter from N (+1)
> >> > different file descriptors. Ideally, we'd have some way to figure out
> >> > that these were all the same. Some sort of prog_id is one way,
> >> > although there may be others.
> >>
> >> I disagree a bit. I think we want the actual hierarchy to be a
> >> well-defined thing, because I have plans to make the hierarchy
> >> actually do something. That means that we'll need to have a more
> >> exact way to dump the hierarchy than "these two filters are identical"
> >> or "these two filters are not identical".
> >
> > Can you elaborate on what this would look like? I think with the
> > "these two filters are the same" primitive (the same in the sense that
> > they were inherited during a fork, not just that
> > memcmp(filter1->insns, filter2->insns) == 0) you can infer the entire
> > hierarchy, however clunky it may be to do so.
> >
> > Another issue is that KCMP_FILE won't work in this case, as it
> > effectively compares the struct file *, which will be different since
> > we need to call anon_inode_getfd() for each call of
> > ptrace(PTRACE_SECCOMP_GET_FILTER_FD). We could add a KCMP_BPF (or just
> > a KCMP_FILE_PRIVATE_DATA, since that's effectively what it would be).
> > Does that make sense? [added Cyrill]
> >
>
> I don't really know what it would look like. I think we want a way to
> compare struct seccomp_filter pointers.
Not to complicate things further, but this brings up another
interesting issue. Right now, we require PT_SUSPEND_SECCOMP in order
to restore seccomp and do things afterwards (otherwise the seccomp
filters might kill whatever things the restore process is doing). If
we want the struct seccomp_filter pointers to be identical on restore,
that means we need to restore when we are real root, because bpf()
requires that we be real root. This means that we essentially need to
ptrace the entire restore, which we don't want to do.
In order to work around this, I was thinking we could change the
ancestry check slightly:
diff --git a/kernel/seccomp.c b/kernel/seccomp.c
index 9c6bea6..efc3f36 100644
--- a/kernel/seccomp.c
+++ b/kernel/seccomp.c
@@ -239,7 +239,7 @@ static int is_ancestor(struct seccomp_filter *parent,
if (parent == NULL)
return 1;
for (; child; child = child->prev)
- if (child == parent)
+ if (child->prog == parent->prog)
return 1;
return 0;
}
so that we can do bpf() when we're real root, and just restore seccomp
at the very end. This would mean that the struct bpf_prog pointers are
shared, but the struct seccomp_filter pointers aren't.
Even assuming we have some sort of way to identify shared ancestry, we
still need something like the above in order to be able to restore it.
This sort of sucks; it would be ideal to to share struct
seccomp_filter *s too. We could do something like
seccomp(COPY_FROM_PARENT) or something, but given the struggles Kees
told me he had with getting SECCOMP_FILTER_FLAG_TSYNC right, I suspect
that won't fly.
> FWIW, I *hate* kcmp. It might be worth trying to come up with a less
> awful way to do this. For example, what if we could generate a kcmpfd
> such that each kcmpfd contains (internally) a random symmetric key?
> We could have a function that would return kernel pointers encrypted
> by that key.
We could do what Kees is proposing for struct bpf_prog and just keep a
globally unique id on struct seccomp_filter, and allow asking for that
via some seccomp(GET_ID, fd) over the same fd we're using to dump the
bpf prog. That doesn't solve our restore problem, though.
Tycho
> Of course, then we need to make sure that no one ever tries to keep a
> kcmpfd around long enough that CRIU needs to checkpoint it, because
> that's impossible.
>
> Grr.
>
> --Andy
next prev parent reply other threads:[~2015-09-05 0:27 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-04 16:04 c/r of seccomp filters via underlying eBPF Tycho Andersen
2015-09-04 16:04 ` [PATCH 1/6] ebpf: add a seccomp program type Tycho Andersen
2015-09-04 20:17 ` Alexei Starovoitov
2015-09-04 21:09 ` Tycho Andersen
2015-09-04 20:34 ` Kees Cook
2015-09-04 21:06 ` Tycho Andersen
2015-09-04 21:08 ` Kees Cook
2015-09-09 15:50 ` Tycho Andersen
2015-09-09 16:07 ` Alexei Starovoitov
2015-09-09 16:09 ` Daniel Borkmann
2015-09-09 16:37 ` Kees Cook
2015-09-09 16:52 ` Alexei Starovoitov
2015-09-09 17:27 ` Kees Cook
2015-09-09 17:31 ` Tycho Andersen
2015-09-09 16:07 ` Daniel Borkmann
2015-09-04 21:50 ` Andy Lutomirski
2015-09-09 16:13 ` Daniel Borkmann
2015-09-04 16:04 ` [PATCH 2/6] seccomp: make underlying bpf ref counted as well Tycho Andersen
2015-09-04 21:53 ` Andy Lutomirski
2015-09-04 16:04 ` [PATCH 3/6] ebpf: add a way to dump an eBPF program Tycho Andersen
2015-09-04 20:17 ` Kees Cook
2015-09-04 20:45 ` Tycho Andersen
2015-09-04 20:50 ` Kees Cook
2015-09-04 20:58 ` Alexei Starovoitov
2015-09-04 21:00 ` Tycho Andersen
2015-09-04 21:48 ` Andy Lutomirski
2015-09-04 22:28 ` Tycho Andersen
2015-09-04 23:08 ` Andy Lutomirski
2015-09-05 0:27 ` Tycho Andersen [this message]
2015-09-09 22:34 ` Tycho Andersen
2015-09-09 23:44 ` Andy Lutomirski
2015-09-10 0:13 ` Tycho Andersen
2015-09-10 0:44 ` Andy Lutomirski
2015-09-10 0:58 ` Tycho Andersen
2015-09-04 23:27 ` Kees Cook
2015-09-05 0:08 ` Andy Lutomirski
2015-09-04 20:27 ` Alexei Starovoitov
2015-09-04 20:42 ` Tycho Andersen
2015-09-04 16:04 ` [PATCH 4/6] seccomp: add a way to access filters via bpf fds Tycho Andersen
2015-09-04 20:26 ` Kees Cook
2015-09-04 20:29 ` Alexei Starovoitov
2015-09-04 20:58 ` Tycho Andersen
2015-09-04 16:04 ` [PATCH 5/6] seccomp: add a way to attach a filter via eBPF fd Tycho Andersen
2015-09-04 20:40 ` Alexei Starovoitov
[not found] ` <1441382664-17437-6-git-send-email-tycho.andersen-Z7WLFzj8eWMS+FvcfC7Uqw@public.gmane.org>
2015-09-04 20:41 ` Kees Cook
[not found] ` <CAGXu5jKke44txdYqEgPRrkn8SyWGjJuHxT2qMdq2ztp_16mQyw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-09-05 7:13 ` Michael Kerrisk (man-pages)
[not found] ` <55EA95FE.7000006-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2015-09-08 13:40 ` Tycho Andersen
2015-09-09 0:07 ` Kees Cook
[not found] ` <CAGXu5jKS0yX92XXhL6ZkqMrxkqFpPyyBd7wbsvEEx4rqZ0VG6g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2015-09-09 14:47 ` Tycho Andersen
2015-09-09 15:14 ` Alexei Starovoitov
[not found] ` <20150909151402.GA3429-2RGepAHry04KGsCuBW9QBvb0xQGhdpdCAL8bYrjMMd8@public.gmane.org>
2015-09-09 15:55 ` Tycho Andersen
2015-09-04 16:04 ` [PATCH 6/6] ebpf: allow BPF_REG_X in src_reg conditional jumps Tycho Andersen
2015-09-04 21:06 ` Alexei Starovoitov
2015-09-04 22:43 ` Tycho Andersen
2015-09-05 4:12 ` Alexei Starovoitov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150905002727.GA3890@hopstrocity \
--to=tycho.andersen@canonical.com \
--cc=ast@kernel.org \
--cc=daniel@iogearbox.net \
--cc=gorcunov@parallels.com \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=netdev@vger.kernel.org \
--cc=oleg@redhat.com \
--cc=serge.hallyn@ubuntu.com \
--cc=wad@chromium.org \
--cc=xemul@parallels.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).