198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn/* liblxcapi
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn *
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * Copyright � 2014 Serge Hallyn <serge.hallyn@ubuntu.com>.
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * Copyright � 2014 Canonical Ltd.
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn *
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * This program is free software; you can redistribute it and/or modify
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * it under the terms of the GNU General Public License version 2, as
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * published by the Free Software Foundation.
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn *
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * This program is distributed in the hope that it will be useful,
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * but WITHOUT ANY WARRANTY; without even the implied warranty of
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * GNU General Public License for more details.
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn *
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * You should have received a copy of the GNU General Public License along
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * with this program; if not, write to the Free Software Foundation, Inc.,
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn/* Test apparmor rules */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn#include <lxc/lxccontainer.h>
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn#include "lxc/utils.h"
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn#include <fcntl.h>
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn#include <unistd.h>
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn#include <string.h>
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn#define MYNAME "test-aa"
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynstatic void try_to_remove(void)
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn{
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn struct lxc_container *c;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn c = lxc_container_new(MYNAME, NULL);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (c) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (c->is_defined(c))
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn c->destroy(c);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn lxc_container_put(c);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn}
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynstatic int test_attach_write_file(void* payload)
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn{
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn char *fnam = payload;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn FILE *f;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn f = fopen(fnam, "w");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (f) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn printf("yes\n");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fclose(f);
fad5004627bebe251228450a8a086500d803b9e4Serge Hallyn fflush(NULL);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn return 1;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn printf("no\n");
fad5004627bebe251228450a8a086500d803b9e4Serge Hallyn fflush(NULL);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn return 0;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn}
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn/*
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * try opening a file attached to a container. Return 0 on open fail. Return
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * 1 if the file open succeeded. Return -1 if attach itself failed - perhas an
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn * older kernel.
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn */
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynstatic int do_test_file_open(struct lxc_container *c, char *fnam)
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn{
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn int fret = -1;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn int ret;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn pid_t pid;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn int pipefd[2];
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn char result[1024];
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn lxc_attach_options_t attach_options = LXC_ATTACH_OPTIONS_DEFAULT;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn ret = pipe(pipefd);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (ret < 0) {
91e7b27880bc0ecb1e221bf7bd6ac25830c1b56aStéphane Graber fprintf(stderr, "pipe failed %d\n", ret);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn return fret;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn attach_options.stdout_fd = pipefd[1];
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn attach_options.attach_flags &= ~(LXC_ATTACH_LSM_EXEC|LXC_ATTACH_DROP_CAPABILITIES);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn attach_options.attach_flags |= LXC_ATTACH_LSM_NOW;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn ret = c->attach(c, test_attach_write_file, fnam, &attach_options, &pid);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (ret < 0) {
91e7b27880bc0ecb1e221bf7bd6ac25830c1b56aStéphane Graber fprintf(stderr, "attach failed\n");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn goto err1;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn ret = read(pipefd[0], result, sizeof(result)-1);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (ret < 0) {
91e7b27880bc0ecb1e221bf7bd6ac25830c1b56aStéphane Graber fprintf(stderr, "read failed %d\n", ret);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn goto err2;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fret = 1;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (strncmp(result, "no", 2) == 0)
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fret = 0;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynerr2:
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn wait_for_pid(pid);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynerr1:
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn close(pipefd[0]);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn close(pipefd[1]);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn return fret;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn}
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynchar *files_to_allow[] = { "/sys/class/net/lo/ifalias",
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn "/proc/sys/kernel/shmmax",
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn NULL };
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynchar *files_to_deny[] = { "/proc/mem", "/proc/kmem",
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn "/sys/kernel/uevent_helper",
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn "/proc/sys/fs/file-nr",
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn "/sys/kernel/mm/ksm/pages_to_scan",
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn "/proc/sys/kernel/sysrq",
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn NULL };
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynstatic bool test_aa_policy(struct lxc_container *c)
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn{
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn int i, ret;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn for (i = 0; files_to_deny[i]; i++) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn ret = do_test_file_open(c, files_to_deny[i]);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (ret < 0) {
91e7b27880bc0ecb1e221bf7bd6ac25830c1b56aStéphane Graber fprintf(stderr, "attach failed; skipping test\n");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn return true;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (ret > 0) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fprintf(stderr, "failed - opened %s\n",
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn files_to_deny[i]);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn return false;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fprintf(stderr, "passed with %s\n", files_to_deny[i]);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn for (i = 0; files_to_allow[i]; i++) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn ret = do_test_file_open(c, files_to_allow[i]);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (ret < 0) {
91e7b27880bc0ecb1e221bf7bd6ac25830c1b56aStéphane Graber fprintf(stderr, "attach failed; skipping test\n");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn return true;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (ret == 0) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fprintf(stderr, "failed - could not open %s\n",
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn files_to_allow[i]);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn return false;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fprintf(stderr, "passed with %s\n", files_to_allow[i]);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn return true;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn}
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynint main(int argc, char *argv[])
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn{
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn struct lxc_container *c;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn try_to_remove();
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn c = lxc_container_new(MYNAME, NULL);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (!c) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fprintf(stderr, "%s: %d: failed to load first container\n", __FILE__, __LINE__);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn exit(1);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (c->is_defined(c)) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fprintf(stderr, "%d: %s thought it was defined\n", __LINE__, MYNAME);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn goto err;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (!c->set_config_item(c, "lxc.network.type", "empty")) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fprintf(stderr, "%s: %d: failed to set network type\n", __FILE__, __LINE__);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn goto err;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn c->save_config(c, NULL);
f69fd24ea3e26095a7c63edb153ccb69fda54716Stéphane Graber if (!c->createl(c, "busybox", NULL, NULL, 0, NULL)) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn fprintf(stderr, "%s: %d: failed to create container\n", __FILE__, __LINE__);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn goto err;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
f69fd24ea3e26095a7c63edb153ccb69fda54716Stéphane Graber
f69fd24ea3e26095a7c63edb153ccb69fda54716Stéphane Graber c->clear_config_item(c, "lxc.mount.auto");
f69fd24ea3e26095a7c63edb153ccb69fda54716Stéphane Graber c->set_config_item(c, "lxc.mount.entry", "proc proc proc");
f69fd24ea3e26095a7c63edb153ccb69fda54716Stéphane Graber c->set_config_item(c, "lxc.mount.entry", "sysfs sys sysfs");
f69fd24ea3e26095a7c63edb153ccb69fda54716Stéphane Graber c->save_config(c, NULL);
f69fd24ea3e26095a7c63edb153ccb69fda54716Stéphane Graber
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn c->want_daemonize(c, true);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (!c->startl(c, 0, NULL)) {
91e7b27880bc0ecb1e221bf7bd6ac25830c1b56aStéphane Graber fprintf(stderr, "Error starting container\n");
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn goto err;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn if (!test_aa_policy(c)) {
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn c->stop(c);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn goto err;
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn }
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn c->stop(c);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn try_to_remove();
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn exit(0);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallynerr:
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn try_to_remove();
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn exit(1);
198b363fff1de9afcee2f26b9aa847316f589afeSerge Hallyn}