[lxc-devel] [PATCH RFC] seccomp: introduce v2 policy

Serge Hallyn serge.hallyn at ubuntu.com
Wed Feb 12 16:05:21 UTC 2014


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?

> > 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 :)

-serge


More information about the lxc-devel mailing list