From: serue@us.ibm.com (Serge E. Hallyn)
Date: Wed, 3 Dec 2008 14:37:50 -0600
Subject: [refpolicy] container policy interface
Message-ID: <20081203203750.GA19949@us.ibm.com>
To: refpolicy@oss.tresys.com
List-Id: refpolicy.oss.tresys.com
Hi,
I've been playing a bit with creating LSM-protected containers.
Attached here are first stabs at an SELinux policy module (against
the refpolicy source with fedora 10) defining an interface
to create containers. The .te and .fc files use the interface
to create two containers, under /vs1 and /vs2. I've been
testing with liblxc (*1) creating debian-based containers
using debootstrap, on a fedora 10 host. It should work
equally well for libvirt though. Quite simply, $1_exec_t
is assigned to the container's /sbin/init, and used to
transition to the container's own type. (So far I'm lazily
using the devices whitelist cgroup to protect against device
access)
This interface is geared toward containers which have their
own private chroot. Containers can also be made minimalist
sharing read-only bind mounts of most of the fs. Such
containers should probably have their own interface, but
in any case I'm ignoring them for now.
Perhaps for starters, I don't know if there is a precedent
for this kind of interface. Would we want just the .if in
the base policy, with the user writing custom .te and .fc
files, based on the if, which they compile under /usr/share/selinux/?
Anyway, I'm posting this to see how far we can go toward
making something actually useful for the refpolicy.
-serge
*1: Install using
cvs -d:pserver:anonymous at lxc.cvs.sourceforge.net:/cvsroot/lxc login
cvs -z3 -d:pserver:anonymous at lxc.cvs.sourceforge.net:/cvsroot/lxc co -P lxc
cd lxc
./bootstrap && ./configure && make && make install
and use as
lxc-debian create (use vs1 as container name for instance)
lxc-start -n vs1
I can give more details on how to set everything up, but
am not sure whether that's necessary to hold a discussion
about the policy module.
-------------- next part --------------
# installation paths
SHAREDIR := /usr/share/selinux
AWK ?= gawk
NAME ?= $(strip $(shell $(AWK) -F= '/^SELINUXTYPE/{ print $$2 }' /etc/selinux/config))
MLSENABLED := $(shell cat /selinux/mls)
ifeq ($(MLSENABLED),)
MLSENABLED := 1
endif
ifeq ($(MLSENABLED),1)
NTYPE = mcs
endif
ifeq ($(NAME),mls)
NTYPE = mls
endif
TYPE ?= $(NTYPE)
HEADERDIR := $(SHAREDIR)/devel/include
include $(HEADERDIR)/Makefile
-------------- next part --------------
## Interface for creating SELinux-protected containers.
###############################################################################
##
## Copyright (c) International Business Machines Corp., 2008
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##
################################################################################
#######################################
##
## Create necessary types and rules for a container.
##
##
##
## base name for the container. For instance, if container name is
## vs1, then most container data will be of type vs1_t.
##
##
interface(`container',`
gen_require(`
type proc_t;
role system_r;
role unconfined_r;
type unconfined_t;
type unconfined_devpts_t;
type staff_t;
type staff_devpts_t;
type fs_t;
type devpts_t;
type sysfs_t;
type inaddr_any_node_t;
type clock_device_t;
');
type $1_t;
type $1_exec_t;
domain_type($1_t);
role system_r types $1_t;
role unconfined_r types $1_t;
type $1_file_t;
files_type($1_file_t);
domain_entry_file($1_t, $1_exec_t);
domain_auto_trans(unconfined_t,$1_exec_t,$1_t)
domain_auto_trans(staff_t,$1_exec_t,$1_t)
allow unconfined_t $1_exec_t:file {read execute};
allow $1_t $1_exec_t:file {read execute entrypoint};
allow unconfined_t $1_t:dir create_dir_perms;
corecmd_exec_bin($1_t)
corecmd_exec_shell($1_t)
libs_exec_lib_files($1_t)
libs_use_ld_so($1_t)
term_create_pty($1_t,$1_file_t)
allow $1_t unconfined_devpts_t:chr_file {setattr rw_term_perms};
allow $1_t console_device_t:chr_file {setattr rw_chr_file_perms};
allow $1_t staff_devpts_t:chr_file rw_chr_file_perms;
allow $1_t self:capability sys_admin;
allow $1_t proc_t:filesystem mount;
allow $1_t device_t:filesystem mount;
allow $1_t device_t:dir { write setattr mounton add_name };
allow $1_t device_t:fifo_file { create rw_fifo_file_perms };
allow $1_t devpts_t:filesystem mount;
allow $1_t clock_device_t:chr_file read_chr_file_perms;
allow $1_t $1_file_t:file *;
allow $1_t $1_file_t:lnk_file *;
allow $1_t $1_file_t:chr_file *;
allow $1_t $1_file_t:blk_file *;
allow $1_t $1_file_t:sock_file *;
allow $1_t $1_file_t:fifo_file *;
allow $1_t $1_t:fifo_file *;
allow $1_t $1_file_t:socket *;
allow $1_t $1_file_t:dir *;
allow $1_t $1_t:process ~{setcurrent};
allow $1_t $1_t:capability ~{audit_write audit_control sys_module};
allow $1_t $1_t:fd *;
allow $1_t $1_t:socket *;
allow $1_t $1_t:tcp_socket *;
allow $1_t $1_t:udp_socket *;
# from audit2allow
storage_getattr_fixed_disk_dev($1_t)
corenet_tcp_bind_http_port($1_t)
corenet_tcp_connect_http_port($1_t)
corenet_tcp_sendrecv_http_port($1_t)
corenet_tcp_sendrecv_unspec_node($1_t)
corenet_tcp_bind_unspec_node($1_t)
kernel_read_ring_buffer($1_t)
kernel_read_network_state($1_t)
allow $1_t self:unix_dgram_socket create;
kernel_read_device_sysctls($1_t);
kernel_read_net_sysctls($1_t);
kernel_rw_net_sysctls($1_t);
kernel_read_system_state($1_t);
kernel_read_hotplug_sysctls($1_t);
kernel_read_kernel_sysctls($1_t);
logging_send_syslog_msg($1_t)
allow $1_t sysfs_t:filesystem mount;
dev_read_urand($1_t)
fs_mount_tmpfs($1_t)
fs_unmount_tmpfs($1_t)
fs_remount_tmpfs($1_t)
fs_list_tmpfs($1_t)
allow $1_t tmpfs_t:file rw_file_perms;
dev_mount_usbfs($1_t)
files_mount_all_file_type_fs($1_t)
files_unmount_all_file_type_fs($1_t)
files_mounton_all_mountpoints($1_t)
fs_remount_xattr_fs($1_t)
corenet_tcp_sendrecv_inaddr_any_node($1_t)
corenet_udp_sendrecv_inaddr_any_node($1_t)
corenet_raw_sendrecv_inaddr_any_node($1_t)
corenet_tcp_bind_inaddr_any_node($1_t)
corenet_udp_bind_inaddr_any_node($1_t)
corenet_tcp_bind_ssh_port($1_t)
corenet_tcp_connect_ssh_port($1_t)
corenet_tcp_sendrecv_ssh_port($1_t)
term_use_all_terms($1_t)
dev_getattr_sysfs_dirs($1_t)
dev_getattr_usbfs_dirs($1_t)
dev_read_rand($1_t)
dev_read_urand($1_t)
kernel_sendrecv_unlabeled_association($1_t);
allow $1_t self:unix_dgram_socket {create read write ioctl sendto connect };
allow $1_t self:shm create_shm_perms;
allow $1_t self:sem create_sem_perms;
allow $1_t self:msgq create_msgq_perms;
allow $1_t device_t:fifo_file rw_fifo_file_perms;
allow $1_t unlabeled_t:packet recv;
')
-------------- next part --------------
/vs1/rootfs/sbin/init -- gen_context(system_u:object_r:vs1_exec_t,s0)
/vs1/rootfs -d gen_context(system_u:object_r:vs1_file_t,s0)
/vs1/rootfs/.+ gen_context(system_u:object_r:vs1_file_t,s0)
/vs2/rootfs/sbin/init -- gen_context(system_u:object_r:vs2_exec_t,s0)
/vs2/rootfs -d gen_context(system_u:object_r:vs2_file_t,s0)
/vs2/rootfs/.+ gen_context(system_u:object_r:vs2_file_t,s0)
-------------- next part --------------
policy_module(vs_gen,1.0.0)
container(vs1)
container(vs2)