[lxc-devel] [PATCH 1/1] apparmor: auto-generate the blacklist rules (v2)
Stéphane Graber
stgraber at ubuntu.com
Tue Apr 1 17:50:22 UTC 2014
On Fri, Mar 28, 2014 at 09:05:31PM -0500, Serge Hallyn wrote:
> This uses the generate-apparmor-rules.py script I sent out some time
> ago to auto-generate apparmor rules based on a higher level set of
> block/allow rules.
>
> Add apparmor policy testcase to make sure that some of the paths we
> expect to be denied (and allowed) write access to are in fact in
> effect in the final policy.
>
> With this policy, libvirt in a container is able to start its
> default network, which previously it could not.
>
> v2: address feedback from stgraber
> . put lxc-generate-aa-rules.py into EXTRA_DIST
> . add lxc-test-apparmor, container-base and container-rules to .gitignore
> . take lxc-test-apparmor out of EXTRA_DIST
> . make lxc-generate-aa-rules.py pep8-compliant
> . don't automatically generate apparmor rules
> This is only bc we can't be guaranteed that python3 will be
> available.
>
> Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
Acked-by: Stéphane Graber <stgraber at ubuntu.com>
> ---
> .gitignore | 1 +
> config/apparmor/Makefile.am | 3 +-
> config/apparmor/README | 12 ++
> config/apparmor/abstractions/container-base | 51 ++++++-
> config/apparmor/abstractions/container-base.in | 45 ++++++
> config/apparmor/container-rules | 43 ++++++
> config/apparmor/container-rules.base | 10 ++
> config/apparmor/lxc-generate-aa-rules.py | 135 ++++++++++++++++++
> src/tests/Makefile.am | 4 +-
> src/tests/aa.c | 190 +++++++++++++++++++++++++
> 10 files changed, 485 insertions(+), 9 deletions(-)
> create mode 100644 config/apparmor/README
> create mode 100644 config/apparmor/abstractions/container-base.in
> create mode 100644 config/apparmor/container-rules
> create mode 100644 config/apparmor/container-rules.base
> create mode 100755 config/apparmor/lxc-generate-aa-rules.py
> create mode 100644 src/tests/aa.c
>
> diff --git a/.gitignore b/.gitignore
> index df55240..2ee10b1 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -79,6 +79,7 @@ src/python-lxc/lxc/__pycache__/
>
> src/tests/lxc-test-device-add-remove
> src/tests/lxc-test-attach
> +src/tests/lxc-test-aparmor
> src/tests/lxc-test-cgpath
> src/tests/lxc-test-clonetest
> src/tests/lxc-test-concurrent
> diff --git a/config/apparmor/Makefile.am b/config/apparmor/Makefile.am
> index 801866d..7ac2bd2 100644
> --- a/config/apparmor/Makefile.am
> +++ b/config/apparmor/Makefile.am
> @@ -5,7 +5,8 @@ EXTRA_DIST = \
> profiles/lxc-default-with-mounting \
> profiles/lxc-default-with-nesting \
> lxc-containers \
> - usr.bin.lxc-start
> + usr.bin.lxc-start \
> + lxc-generate-aa-rules.py
>
> if ENABLE_APPARMOR
> install-apparmor:
> diff --git a/config/apparmor/README b/config/apparmor/README
> new file mode 100644
> index 0000000..432956b
> --- /dev/null
> +++ b/config/apparmor/README
> @@ -0,0 +1,12 @@
> +The abstractions/container-base file is partially automatically
> +generated. The two source files are container-rules.base and
> +abstractions/container-base.in. If these file are updated,
> +then
> +
> +1. Generate a new container-rules file using
> +
> +./lxc-generate-aa-rules.py container-rules.base > container-rules
> +
> +2. Concatenate container-base.in with container-rules using
> +
> +cat abstractions/container-base.in container-rules > abstractions/container-base
> diff --git a/config/apparmor/abstractions/container-base b/config/apparmor/abstractions/container-base
> index d1cd84a..d094aab 100644
> --- a/config/apparmor/abstractions/container-base
> +++ b/config/apparmor/abstractions/container-base
> @@ -30,8 +30,6 @@
> deny @{PROC}/sysrq-trigger rwklx,
> deny @{PROC}/mem rwklx,
> deny @{PROC}/kmem rwklx,
> - deny @{PROC}/sys/kernel/[^s][^h][^m]* wklx,
> - deny @{PROC}/sys/kernel/*/** wklx,
>
> # deny writes in /sys except for /sys/fs/cgroup, also allow
> # fusectl, securityfs and debugfs to be mounted there (read-only)
> @@ -41,11 +39,50 @@
> deny mount fstype=debugfs -> /var/lib/ureadahead/debugfs/,
> mount fstype=proc -> /proc/,
> mount fstype=sysfs -> /sys/,
> - deny /sys/[^f]*/** wklx,
> - deny /sys/f[^s]*/** wklx,
> - deny /sys/fs/[^c]*/** wklx,
> - deny /sys/fs/c[^g]*/** wklx,
> - deny /sys/fs/cg[^r]*/** wklx,
> deny /sys/firmware/efi/efivars/** rwklx,
> deny /sys/kernel/security/** rwklx,
> mount options=(move) /sys/fs/cgroup/cgmanager/ -> /sys/fs/cgroup/cgmanager.lower/,
> +
> + # generated by: lxc-generate-aa-rules.py container-rules.base
> + deny /proc/sys/kernel/[^s]*{,/**} wklx,
> + deny /proc/sys/kernel/s[^h]*{,/**} wklx,
> + deny /proc/sys/kernel/sh[^m]*{,/**} wklx,
> + deny /proc/sys/kernel/shm*/** wklx,
> + deny /sys/[^fdc]*{,/**} wklx,
> + deny /sys/c[^l]*{,/**} wklx,
> + deny /sys/cl[^a]*{,/**} wklx,
> + deny /sys/cla[^s]*{,/**} wklx,
> + deny /sys/clas[^s]*{,/**} wklx,
> + deny /sys/class/[^n]*{,/**} wklx,
> + deny /sys/class/n[^e]*{,/**} wklx,
> + deny /sys/class/ne[^t]*{,/**} wklx,
> + deny /sys/class/net?*{,/**} wklx,
> + deny /sys/class?*{,/**} wklx,
> + deny /sys/d[^e]*{,/**} wklx,
> + deny /sys/de[^v]*{,/**} wklx,
> + deny /sys/dev[^i]*{,/**} wklx,
> + deny /sys/devi[^c]*{,/**} wklx,
> + deny /sys/devic[^e]*{,/**} wklx,
> + deny /sys/device[^s]*{,/**} wklx,
> + deny /sys/devices/[^v]*{,/**} wklx,
> + deny /sys/devices/v[^i]*{,/**} wklx,
> + deny /sys/devices/vi[^r]*{,/**} wklx,
> + deny /sys/devices/vir[^t]*{,/**} wklx,
> + deny /sys/devices/virt[^u]*{,/**} wklx,
> + deny /sys/devices/virtu[^a]*{,/**} wklx,
> + deny /sys/devices/virtua[^l]*{,/**} wklx,
> + deny /sys/devices/virtual/[^n]*{,/**} wklx,
> + deny /sys/devices/virtual/n[^e]*{,/**} wklx,
> + deny /sys/devices/virtual/ne[^t]*{,/**} wklx,
> + deny /sys/devices/virtual/net?*{,/**} wklx,
> + deny /sys/devices/virtual?*{,/**} wklx,
> + deny /sys/devices?*{,/**} wklx,
> + deny /sys/f[^s]*{,/**} wklx,
> + deny /sys/fs/[^c]*{,/**} wklx,
> + deny /sys/fs/c[^g]*{,/**} wklx,
> + deny /sys/fs/cg[^r]*{,/**} wklx,
> + deny /sys/fs/cgr[^o]*{,/**} wklx,
> + deny /sys/fs/cgro[^u]*{,/**} wklx,
> + deny /sys/fs/cgrou[^p]*{,/**} wklx,
> + deny /sys/fs/cgroup?*{,/**} wklx,
> + deny /sys/fs?*{,/**} wklx,
> diff --git a/config/apparmor/abstractions/container-base.in b/config/apparmor/abstractions/container-base.in
> new file mode 100644
> index 0000000..84eadd0
> --- /dev/null
> +++ b/config/apparmor/abstractions/container-base.in
> @@ -0,0 +1,45 @@
> + network,
> + capability,
> + file,
> + umount,
> + dbus,
> +
> + # ignore DENIED message on / remount
> + deny mount options=(ro, remount) -> /,
> +
> + # allow tmpfs mounts everywhere
> + mount fstype=tmpfs,
> +
> + # allow mqueue mounts everywhere
> + mount fstype=mqueue,
> +
> + # allow fuse mounts everywhere
> + mount fstype=fuse.*,
> +
> + # allow bind mount of /lib/init/fstab for lxcguest
> + mount options=(rw, bind) /lib/init/fstab.lxc/ -> /lib/init/fstab/,
> +
> + # deny writes in /proc/sys/fs but allow binfmt_misc to be mounted
> + mount fstype=binfmt_misc -> /proc/sys/fs/binfmt_misc/,
> + deny @{PROC}/sys/fs/** wklx,
> +
> + # allow efivars to be mounted, writing to it will be blocked though
> + mount fstype=efivarfs -> /sys/firmware/efi/efivars/,
> +
> + # block some other dangerous paths
> + deny @{PROC}/sysrq-trigger rwklx,
> + deny @{PROC}/mem rwklx,
> + deny @{PROC}/kmem rwklx,
> +
> + # deny writes in /sys except for /sys/fs/cgroup, also allow
> + # fusectl, securityfs and debugfs to be mounted there (read-only)
> + mount fstype=fusectl -> /sys/fs/fuse/connections/,
> + mount fstype=securityfs -> /sys/kernel/security/,
> + mount fstype=debugfs -> /sys/kernel/debug/,
> + deny mount fstype=debugfs -> /var/lib/ureadahead/debugfs/,
> + mount fstype=proc -> /proc/,
> + mount fstype=sysfs -> /sys/,
> + deny /sys/firmware/efi/efivars/** rwklx,
> + deny /sys/kernel/security/** rwklx,
> + mount options=(move) /sys/fs/cgroup/cgmanager/ -> /sys/fs/cgroup/cgmanager.lower/,
> +
> diff --git a/config/apparmor/container-rules b/config/apparmor/container-rules
> new file mode 100644
> index 0000000..47dd4c2
> --- /dev/null
> +++ b/config/apparmor/container-rules
> @@ -0,0 +1,43 @@
> + # generated by: lxc-generate-aa-rules.py container-rules.base
> + deny /proc/sys/kernel/[^s]*{,/**} wklx,
> + deny /proc/sys/kernel/s[^h]*{,/**} wklx,
> + deny /proc/sys/kernel/sh[^m]*{,/**} wklx,
> + deny /proc/sys/kernel/shm*/** wklx,
> + deny /sys/[^fdc]*{,/**} wklx,
> + deny /sys/c[^l]*{,/**} wklx,
> + deny /sys/cl[^a]*{,/**} wklx,
> + deny /sys/cla[^s]*{,/**} wklx,
> + deny /sys/clas[^s]*{,/**} wklx,
> + deny /sys/class/[^n]*{,/**} wklx,
> + deny /sys/class/n[^e]*{,/**} wklx,
> + deny /sys/class/ne[^t]*{,/**} wklx,
> + deny /sys/class/net?*{,/**} wklx,
> + deny /sys/class?*{,/**} wklx,
> + deny /sys/d[^e]*{,/**} wklx,
> + deny /sys/de[^v]*{,/**} wklx,
> + deny /sys/dev[^i]*{,/**} wklx,
> + deny /sys/devi[^c]*{,/**} wklx,
> + deny /sys/devic[^e]*{,/**} wklx,
> + deny /sys/device[^s]*{,/**} wklx,
> + deny /sys/devices/[^v]*{,/**} wklx,
> + deny /sys/devices/v[^i]*{,/**} wklx,
> + deny /sys/devices/vi[^r]*{,/**} wklx,
> + deny /sys/devices/vir[^t]*{,/**} wklx,
> + deny /sys/devices/virt[^u]*{,/**} wklx,
> + deny /sys/devices/virtu[^a]*{,/**} wklx,
> + deny /sys/devices/virtua[^l]*{,/**} wklx,
> + deny /sys/devices/virtual/[^n]*{,/**} wklx,
> + deny /sys/devices/virtual/n[^e]*{,/**} wklx,
> + deny /sys/devices/virtual/ne[^t]*{,/**} wklx,
> + deny /sys/devices/virtual/net?*{,/**} wklx,
> + deny /sys/devices/virtual?*{,/**} wklx,
> + deny /sys/devices?*{,/**} wklx,
> + deny /sys/f[^s]*{,/**} wklx,
> + deny /sys/fs/[^c]*{,/**} wklx,
> + deny /sys/fs/c[^g]*{,/**} wklx,
> + deny /sys/fs/cg[^r]*{,/**} wklx,
> + deny /sys/fs/cgr[^o]*{,/**} wklx,
> + deny /sys/fs/cgro[^u]*{,/**} wklx,
> + deny /sys/fs/cgrou[^p]*{,/**} wklx,
> + deny /sys/fs/cgroup?*{,/**} wklx,
> + deny /sys/fs?*{,/**} wklx,
> diff --git a/config/apparmor/container-rules.base b/config/apparmor/container-rules.base
> new file mode 100644
> index 0000000..e16d874
> --- /dev/null
> +++ b/config/apparmor/container-rules.base
> @@ -0,0 +1,10 @@
> +# Run lxc-generate-aa-rules.py on this file after any modification, to generate
> +# the container-rules file which is appended to container-base.in to create the
> +# final abstractions/container-base.
> +
> +block /sys
> +allow /sys/fs/cgroup/**
> +allow /sys/devices/virtual/net/**
> +allow /sys/class/net/**
> +block /proc/sys/kernel
> +allow /proc/sys/kernel/shm*
> diff --git a/config/apparmor/lxc-generate-aa-rules.py b/config/apparmor/lxc-generate-aa-rules.py
> new file mode 100755
> index 0000000..619b3bc
> --- /dev/null
> +++ b/config/apparmor/lxc-generate-aa-rules.py
> @@ -0,0 +1,135 @@
> +#!/usr/bin/python3
> +
> +import sys
> +
> +blocks = []
> +
> +#
> +# blocks is an array of paths under which we want to block by
> +# default.
> +#
> +# blocks[0] = ['path' = '/sys', 'children' = [A,B] ]
> +# blocks[1] = ['path' = '/proc/sys', 'children' = [ E ] ]
> +# A = [ 'path' = 'fs', children = [C] ]
> +# C = [ 'path' = 'cgroup', children = [F] ]
> +# B = [ 'path' = 'class', children = [D] ]
> +# D = [ 'path' = 'net', children = [F] ]
> +# E = [ 'path' = 'shm*' ]
> +# F = [ 'path' = '**' ]
> +
> +
> +def add_block(path):
> + for b in blocks:
> + if b['path'] == path:
> + # duplicate
> + return
> + blocks.append({'path': path.strip(), 'children': []})
> +
> +
> +def child_get(prev, path):
> + for p in prev:
> + if p['path'] == path:
> + return p
> + return None
> +
> +
> +def add_allow(path):
> + # find which block we belong to
> + found = None
> + for b in blocks:
> + l = len(b['path'])
> + if len(path) <= l:
> + continue
> + if path[0:l] == b['path']:
> + found = b
> + break
> + if found is None:
> + print("allow with no previous block at %s" % path)
> + sys.exit(1)
> + p = path[l:].strip()
> + while p[:1] == "/":
> + p = p[1:]
> + prev = b['children']
> + for s in p.split('/'):
> + n = {'path': s.strip(), 'children': []}
> + tmp = child_get(prev, n['path'])
> + if tmp is not None:
> + prev = tmp
> + else:
> + prev.append(n)
> + prev = n['children']
> +
> +config = "config"
> +if len(sys.argv) > 1:
> + config = sys.argv[1]
> +with open(config) as f:
> + for x in f.readlines():
> + x.strip()
> + if x[:1] == '#':
> + continue
> + try:
> + (cmd, path) = x.split(' ')
> + except: # blank line
> + continue
> + if cmd == "block":
> + add_block(path)
> + elif cmd == "allow":
> + add_allow(path)
> + else:
> + print("Unknown command: %s" % cmd)
> + sys.exit(1)
> +
> +denies = []
> +
> +
> +def collect_chars(children, ref, index):
> + r = ""
> + for c in children:
> + if index >= len(c['path']):
> + continue
> + if ref[0:index] != c['path'][0:index]:
> + continue
> + if c['path'][index] not in r:
> + r = r + c['path'][index]
> + return r
> +
> +
> +def append_deny(s):
> + s = "%s wklx," % s
> + if s not in denies:
> + denies.append(s)
> +
> +
> +def gen_denies(pathsofar, children):
> + for c in children:
> + for char in range(len(c['path'])):
> + if char == len(c['path'])-1 and c['path'][char] == '*':
> + continue
> + if char == len(c['path'])-2:
> + if c['path'][char:char+2] == '**':
> + continue
> + x = collect_chars(children, c['path'], char)
> + newdeny = "deny %s/%s[^%s]*{,/**}" % (pathsofar,
> + c['path'][0:char], x)
> + append_deny(newdeny)
> + if c['path'] != '**' and c['path'][len(c['path'])-1] != '*':
> + newdeny = "deny %s/%s?*{,/**}" % (pathsofar, c['path'])
> + append_deny(newdeny)
> + elif c['path'] != '**':
> + newdeny = "deny %s/%s/**" % (pathsofar, c['path'])
> + append_deny(newdeny)
> + if len(c['children']) != 0:
> + newpath = "%s/%s" % (pathsofar, c['path'])
> + gen_denies(newpath, c['children'])
> +
> +for b in blocks:
> + gen_denies(b['path'], b['children'])
> +
> +denies.sort()
> +
> +genby = " # generated by: lxc-generate-aa-rules.py"
> +for a in sys.argv[1:]:
> + genby += " %s" % a
> +print(genby)
> +for d in denies:
> + print(" %s" % d)
> diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am
> index 9ca68ba..6b4fceb 100644
> --- a/src/tests/Makefile.am
> +++ b/src/tests/Makefile.am
> @@ -22,6 +22,7 @@ lxc_test_reboot_SOURCES = reboot.c
> lxc_test_list_SOURCES = list.c
> lxc_test_attach_SOURCES = attach.c
> lxc_test_device_add_remove_SOURCES = device_add_remove.c
> +lxc_test_apparmor_SOURCES = aa.c
>
> AM_CFLAGS=-I$(top_srcdir)/src \
> -DLXCROOTFSMOUNT=\"$(LXCROOTFSMOUNT)\" \
> @@ -44,7 +45,8 @@ bin_PROGRAMS = lxc-test-containertests lxc-test-locktests lxc-test-startone \
> lxc-test-shutdowntest lxc-test-get_item lxc-test-getkeys lxc-test-lxcpath \
> lxc-test-cgpath lxc-test-clonetest lxc-test-console \
> lxc-test-snapshot lxc-test-concurrent lxc-test-may-control \
> - lxc-test-reboot lxc-test-list lxc-test-attach lxc-test-device-add-remove
> + lxc-test-reboot lxc-test-list lxc-test-attach lxc-test-device-add-remove \
> + lxc-test-apparmor
>
> bin_SCRIPTS = lxc-test-autostart
>
> diff --git a/src/tests/aa.c b/src/tests/aa.c
> new file mode 100644
> index 0000000..a8ff691
> --- /dev/null
> +++ b/src/tests/aa.c
> @@ -0,0 +1,190 @@
> +/* liblxcapi
> + *
> + * Copyright © 2014 Serge Hallyn <serge.hallyn at ubuntu.com>.
> + * Copyright © 2014 Canonical Ltd.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2, as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +/* Test apparmor rules */
> +#include <lxc/lxccontainer.h>
> +#include "lxc/utils.h"
> +
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <string.h>
> +
> +#define MYNAME "test-aa"
> +
> +static void try_to_remove(void)
> +{
> + struct lxc_container *c;
> + c = lxc_container_new(MYNAME, NULL);
> + if (c) {
> + if (c->is_defined(c))
> + c->destroy(c);
> + lxc_container_put(c);
> + }
> +}
> +
> +static int test_attach_write_file(void* payload)
> +{
> + char *fnam = payload;
> + FILE *f;
> +
> + f = fopen(fnam, "w");
> + if (f) {
> + printf("yes\n");
> + fclose(f);
> + return 1;
> + }
> + printf("no\n");
> + return 0;
> +}
> +
> +/*
> + * try opening a file attached to a container. Return 0 on open fail. Return
> + * 1 if the file open succeeded. Return -1 if attach itself failed - perhas an
> + * older kernel.
> + */
> +static int do_test_file_open(struct lxc_container *c, char *fnam)
> +{
> + int fret = -1;
> + int ret;
> + pid_t pid;
> + int pipefd[2];
> + char result[1024];
> + lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
> +
> + ret = pipe(pipefd);
> + if (ret < 0) {
> + fprintf(stderr, "pipe failed %d", ret);
> + return fret;
> + }
> + attach_options.stdout_fd = pipefd[1];
> + attach_options.attach_flags &= ~(LXC_ATTACH_LSM_EXEC|LXC_ATTACH_DROP_CAPABILITIES);
> + attach_options.attach_flags |= LXC_ATTACH_LSM_NOW;
> + ret = c->attach(c, test_attach_write_file, fnam, &attach_options, &pid);
> + if (ret < 0) {
> + fprintf(stderr, "attach failed");
> + goto err1;
> + }
> +
> + ret = read(pipefd[0], result, sizeof(result)-1);
> + if (ret < 0) {
> + fprintf(stderr, "read failed %d", ret);
> + goto err2;
> + }
> +
> + fret = 1;
> + if (strncmp(result, "no", 2) == 0)
> + fret = 0;
> +
> +err2:
> + wait_for_pid(pid);
> +err1:
> + close(pipefd[0]);
> + close(pipefd[1]);
> + return fret;
> +}
> +
> +char *files_to_allow[] = { "/sys/class/net/lo/ifalias",
> + "/proc/sys/kernel/shmmax",
> + NULL };
> +
> +char *files_to_deny[] = { "/proc/mem", "/proc/kmem",
> + "/sys/kernel/uevent_helper",
> + "/proc/sys/fs/file-nr",
> + "/sys/kernel/mm/ksm/pages_to_scan",
> + "/proc/sys/kernel/sysrq",
> + NULL };
> +
> +static bool test_aa_policy(struct lxc_container *c)
> +{
> + int i, ret;
> +
> + for (i = 0; files_to_deny[i]; i++) {
> + ret = do_test_file_open(c, files_to_deny[i]);
> + if (ret < 0) {
> + fprintf(stderr, "attach failed; skipping test");
> + return true;
> + }
> + if (ret > 0) {
> + fprintf(stderr, "failed - opened %s\n",
> + files_to_deny[i]);
> + return false;
> + }
> + fprintf(stderr, "passed with %s\n", files_to_deny[i]);
> + }
> +
> + for (i = 0; files_to_allow[i]; i++) {
> + ret = do_test_file_open(c, files_to_allow[i]);
> + if (ret < 0) {
> + fprintf(stderr, "attach failed; skipping test");
> + return true;
> + }
> + if (ret == 0) {
> + fprintf(stderr, "failed - could not open %s\n",
> + files_to_allow[i]);
> + return false;
> + }
> + fprintf(stderr, "passed with %s\n", files_to_allow[i]);
> + }
> +
> + return true;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + struct lxc_container *c;
> + try_to_remove();
> + c = lxc_container_new(MYNAME, NULL);
> + if (!c) {
> + fprintf(stderr, "%s: %d: failed to load first container\n", __FILE__, __LINE__);
> + exit(1);
> + }
> +
> + if (c->is_defined(c)) {
> + fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
> + goto err;
> + }
> + if (!c->set_config_item(c, "lxc.network.type", "empty")) {
> + fprintf(stderr, "%s: %d: failed to set network type\n", __FILE__, __LINE__);
> + goto err;
> + }
> + c->save_config(c, NULL);
> + if (!c->createl(c, "download", NULL, NULL, 0, "-d", "ubuntu", "-r", "trusty", "-a", "amd64", NULL)) {
> + fprintf(stderr, "%s: %d: failed to create container\n", __FILE__, __LINE__);
> + goto err;
> + }
> + c->want_daemonize(c, true);
> + if (!c->startl(c, 0, NULL)) {
> + fprintf(stderr, "Error starting container");
> + goto err;
> + }
> +
> + if (!test_aa_policy(c)) {
> + c->stop(c);
> + goto err;
> + }
> +
> + c->stop(c);
> +
> + try_to_remove();
> + exit(0);
> +
> +err:
> + try_to_remove();
> + exit(1);
> +}
> --
> 1.9.1
>
> _______________________________________________
> 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/20140401/75f1f512/attachment-0001.pgp>
More information about the lxc-devel
mailing list