[lxc-devel] [PATCH RFC] seccomp: introduce v2 policy
Stéphane Graber
stgraber at ubuntu.com
Wed Feb 12 16:19:34 UTC 2014
On Wed, Feb 12, 2014 at 10:05:21AM -0600, Serge Hallyn wrote:
> Quoting Stéphane Graber (stgraber at ubuntu.com):
> > On Wed, Feb 12, 2014 at 12:24:22AM -0600, Serge Hallyn wrote:
> > > v2 allows specifying system calls by name, and specifying
> > > architecture. A policy might look like:
> > >
> > > 2
> > > whitelist
> > > # native architecture is x86_64; we could put
> > > # [x86-64] here but don't need to
> > > open
> > > read
> > > write
> > > close
> > > mount
> > > # let's also allow some 32-bit syscalls
> > > [x86]
> > > open
> > > read
> >
> > Nice! That's already a huge step up from the v1 config.
> > Just wondering, does v2 also support blacklisting or do we still need to
> > list the whole list of possible syscalls minus the one we want to block?
>
> Hm. It does not, but I'll add it and send a new patch.
>
> > > Also use SCMP_ACT_KILL rather than SCMP_ACT_ERRNO(31) - which
> > > confusingly returns 'EMLINK' on x86_64.
> >
> > I was wondering, is there a sane way we could make that configurable?
>
> There is, and in particular I want to use that to support 'debugging'.
> But for now I want to just do blacklist and whitelist.
>
> Well, we could add an optional integer after 'whitelist' or 'blacklist'
> to give an errno to return instead of simply killing the task. What
> i don't want to deal with yet is the SCMP_ACT_TRACE behavior
> (see seccomp_init(3)).
>
> > Currently there isn't a big use case for this, but if we ever get
> > syscall blacklisting, then it'd be very interesting to be able to set a
> > default (possibly something like "whitelist errno 31") and then override
> > it on a per-syscall basis.
>
> Yeah we can do that for v2.
>
> > This would allow things like blocking mknod yet have it return as if it
> > succeeded (handy for userns).
>
> Oh hm. now that implies that you want different blacklisted commands
> to have different behaviors?
Correct, I guess we could support something along the lines of:
2
blacklist kill
mknod errno 0
open
close
This would allow all syscalls but those listed below, open and close
would use SCMP_ACT_KILL, mknod would use SCMP_ACT_ERRNO with errno=0.
If that's too difficult to implement, I guess I could live with one
seccomp policy file per action.
> > > Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
> > > ---
> > > src/lxc/seccomp.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++-------
> > > 1 file changed, 144 insertions(+), 20 deletions(-)
> > >
> > > diff --git a/src/lxc/seccomp.c b/src/lxc/seccomp.c
> > > index ea23b3a..c8c232a 100644
> > > --- a/src/lxc/seccomp.c
> > > +++ b/src/lxc/seccomp.c
> > > @@ -34,6 +34,143 @@
> > >
> > > lxc_log_define(lxc_seccomp, lxc);
> > >
> > > +static int parse_config_v1(FILE *f, struct lxc_conf *conf)
> > > +{
> > > + char line[1024];
> > > + int ret;
> > > +
> > > + while (fgets(line, 1024, f)) {
> > > + int nr;
> > > + ret = sscanf(line, "%d", &nr);
> > > + if (ret != 1)
> > > + return -1;
> > > + ret = seccomp_rule_add(
> > > +#if HAVE_SCMP_FILTER_CTX
> > > + conf->seccomp_ctx,
> > > +#endif
> > > + SCMP_ACT_ALLOW, nr, 0);
> > > + if (ret < 0) {
> > > + ERROR("failed loading allow rule for %d", nr);
> > > + return ret;
> > > + }
> > > + }
> > > + return 0;
> > > +}
> > > +
> > > +static void remove_trailing_newlines(char *l)
> > > +{
> > > + char *p = l;
> > > +
> > > + while (*p)
> > > + p++;
> > > + while (--p >= l && *p == '\n')
> > > + *p = '\0';
> > > +}
> > > +
> > > +/*
> > > + * v2 consists of
> > > + * [x86]
> > > + * open
> > > + * read
> > > + * write
> > > + * close
> > > + * # a comment
> > > + * [x86_64]
> > > + * open
> > > + * read
> > > + * write
> > > + * close
> > > + */
> > > +static int parse_config_v2(FILE *f, struct lxc_conf *conf)
> > > +{
> > > +#if HAVE_SCMP_FILTER_CTX
> > > + char line[1024];
> > > + int ret;
> > > + uint32_t arch = SCMP_ARCH_NATIVE;
> > > + scmp_filter_ctx *ctx = NULL;
> > > +
> > > + while (fgets(line, 1024, f)) {
> > > + int nr;
> > > +
> > > + if (line[0] == '#')
> > > + continue;
> > > + if (strlen(line) == 0)
> > > + continue;
> > > + remove_trailing_newlines(line);
> > > + INFO("processing: .%s.", line);
> >
> > ^ This probably ought to be DEBUG, otherwise if I list all the possible
> > syscalls, this is going to spam my log files :)
> >
> > > + if (line[0] == '[') {
> > > + if (strcmp(line, "[x86]") == 0 ||
> > > + strcmp(line, "[X86]") == 0)
> > > + arch = SCMP_ARCH_X86;
> > > + else if (strcmp(line, "[X86_64]") == 0 ||
> > > + strcmp(line, "[x86_64]") == 0)
> > > + arch = SCMP_ARCH_X86_64;
> > > + else if (strcmp(line, "[arm]") == 0 ||
> > > + strcmp(line, "[ARM]") == 0)
> > > + arch = SCMP_ARCH_ARM;
> >
> > Is that all architectures supported by seccomp or did you just put the
> > most common ones?
> >
> > I'm specifically wondering about arm64, powerpc and ppc64el all of which
> > Ubuntu supports now.
> >
> > In theory, the following should be valid:
> >
> > 2
> > whitelist
> > open
> > read
> > [arm]
> > open
> > read
> >
> > (armhf on arm64)
> >
> > So ideally, we'd support:
> > - amd64 (including i386 on amd64)
> > - i386
> > - armhf
> > - arm64 (including armhf on arm64)
> > - powerpc
> > - ppc64el
>
> Seccomp currently only supports 'arm' (32-bit I assume), x86 and x86_64.
> I did see a patch for mips hit the m-l today :)
Ok, then. I suspect those will be addded eventually but then it'll just
be a few lines patch to introduce those.
>
> -serge
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
--
Stéphane Graber
Ubuntu developer
http://www.ubuntu.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20140212/e5a4d6a1/attachment.pgp>
More information about the lxc-devel
mailing list