Configurable Privileges for Zones
David.Comay@Sun.COM

ident	"@(#)limitpriv	1.4	06/03/08 SMI"

A. Introduction

This case proposes a new facility for zones[1]: the ability to specify
the set of privileges[2] that all of the processes in a zone are
limited to.  Patch binding is requested for this facility.  The
stability of the interface is "Evolving."

B. Motivation

As specified in the original Zones case, when a zone is created in the
kernel there is a default set of "safe" privileges which are used as a
mask for all processes that run inside the zone.  These privileges are
"safe" in the sense that a privileged process in the zone cannot affect
processes in other non-global zones on the system or in the global
zone.  Many of the "unsafe" privileges are ones which affect a global
resource, such as the system clock or physical memory.

A number of customers[3] have requested the ability to augment this
default set of privileges with the understanding that changes in the
zone's privilege set may open up a security window or allow processes
in one zone to be able to affect processes in other zones by being able
to control a global resource.  For example, many customers have
requested the ability to use DTrace[4] within a non-global zone or to
effectively use Dynamic ISM memory by locking memory segments.

In addition, there have been some requests to be able to create zones
with even fewer privileges than usual.  An example here might be the
ability to create a zone without the privilege to send raw ICMP
packets.

C. Advice Concerning Privileges

During the development of the original Zones project and this proposed
case, it became clear that certain privileges require extra scrutiny
when it comes to zones.  When new privileges are proposed, careful
consideration should be made concerning what the privilege means for
the name space, security and failure isolation boundary that zones
provide.  Proposed privileges should be scrutinized to verify that are
not too broad in nature.  A determination should be made as to whether
they are required in all zones, whether they're optional, whether they
should be part of the safe, default zone privilege set or whether use
of the privilege within a non-global zone should be prohibited.

Finally, when new subsystems or frameworks are introduced which intend
to leverage an existing privilege, there should be consideration given
to creating a new privilege so that the existing privilege does not
become too broad.

D. Configurable Privileges Details

This case proposes to leave the default set of privileges for a
non-global zone unchanged.  In order to specify a different privilege
mask, a zonecfg(1M) global property is introduced, "limitpriv", which
is modeled after the key of the same name in the user_attr(4)
database.  The property value should be a comma-separated privilege set
as specified by priv_str_to_set(3C).

Privileges are added by the global zone administrator by specifying
their name (either with or without the leading "priv_") or excluded by
preceding their names with a dash (-) or exclamation mark (!).  The
special privilege sets of "none", "all", and "basic" all expand to
their normal definitions.  Since zone configuration takes place from
within the global zone, the special privilege set "zone" is problematic
as it is equivalent to "all" in this context.  Therefore, this token
will be detected and flagged as an error if it occurs in the property.

Since a common situation would be to augment the default privilege set
by adding or removing a few privileges, a special "default" token is
introduced which maps to the default, safe set of privileges.  When it
appears at the beginning of the "limitpriv" property, it expands to
this default set.

As with all zonecfg(1M) properties and attributes, changes to the
"limitpriv" property will not affect the processes in a running zone
but will take affect the next time the zone is (re)booted or placed in
the "ready" state.

The privilege framework supports the ability for device drivers to
deliver their own privileges.  Since device administration (including
the adding of drivers) take place in the global zone, any extensible
privileges are also administered in the global zone when adding or
removing drivers.  After this takes place, those privileges may be
specified in the "limitpriv" property along with corresponding "device"
resources for the zone.

Some examples of using this new property follow:

 	global# zonecfg -z twilight
 	zonecfg:twilight> set limitpriv="default,sys_time,!net_icmpaccess"

 	(adds the ability to set the system clock and removes the
 	 ability to send raw ICMP packets)

 	global# zonecfg -z twilight
 	zonecfg:twilight> set limitpriv="basic,sys_mount"

 	(sets the privilege set to the basic set of privileges as well
 	 as the ability to mount and unmount file systems)

E. Zones and Certain Privileges

A number of the privileges currently are not quite as fine-grained as
others and are too broad as defined to allow use within a non-global
zone.  One reason for this is that the subsystem or resource they
govern has not been virtualized on a per-zone basis or the privilege in
question covers multiple subsystems or resources.  Another set of
privileges are so fundamental to a zone's operation that removing them
from the privilege set must not be allowed.  Appendix B lists all of
the current Solaris privileges and whether or not there are any
restrictions around their use in the "limitpriv" property.

If the zone's privilege set contains a disallowed privilege or is
missing a required privilege or includes an unknown privilege name, an
attempt to "verify", "ready" or "boot" the zone will fail with a
message indicating the nature of the issue:

 	global# zonecfg -z twilight
 	zonecfg:twilight> set limitpriv="basic"
 	zonecfg:twilight> ^D
 	global# zoneadm -z twilight boot
 	required privilege "sys_mount" is missing from the zone's privilege set
 	zoneadm: zone twilight failed to verify


Appendix A. References

1. PSARC 2002/174 - Virtualization and Namespace Isolation in the Solaris
   Operating System
2. PSARC 2002/188 - Solaris Least Privilege
3. http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4966416
4. http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4970596

Appendix B. Zone Privilege Restrictions

The table below lists all of the Solaris privileges and the status of
the privilege with respect to zones.  Optional privileges are not part
of the default set of privileges but can be specified through the
"limitpriv" property.  Required privileges must be included and
prohibited privileges absent from the resulting privilege set.

Privilege		Status		Notes
=========		======		=====
cpc_cpu			optional	Access to certain cpc(3CPC) counters
dtrace_proc		optional	fasttrap & pid providers; plockstat(1M)
dtrace_user		optional	profile and syscall providers
gart_access		optional	ioctl(2) access to agpgart_io(7I)
gart_map		optional	mmap(2) access to agpgart_io(7I)
net_rawaccess		optional	Raw PF_INET/PF_INET6 packet access
proc_clock_highres	optional	Use of high resolution timers
proc_lock_memory	optional	Locking memory; shmctl(2) and mlock(3C)
proc_priocntl		optional	Scheduling control; priocntl(1)
sys_ipc_config		optional	Raising IPC message queue buffer size
sys_time		optional	System time manipulation; xntp(1M), etc

proc_exec		required	Needed to get init(1M) online
proc_fork		required	Needed to get init(1M) online
sys_mount		required	Needed to mount required file systems

dtrace_kernel		prohibited	Insufficient virtualization
proc_zone		prohibited	Permits access to other zones
sys_config		prohibited	Insufficient virtualization, too broad
sys_devices		prohibited	Global zone boundary can be violated
sys_linkdir		prohibited	Potential file system corruption
sys_net_config		prohibited	Insufficient virtualization, too broad
sys_res_config		prohibited	Insufficient virtualization
sys_suser_compat	prohibited	Not applicable

contract_event		default		Used by contract file system
contract_observer	default		Contract observation regardless of uid
file_chown		default		File ownership changes
file_chown_self		default		Owner/group changes for own files
file_dac_execute	default		Execute access regardless of mode/ACL
file_dac_read		default		Read access regardless of mode/ACL
file_dac_search		default		Search access regardless of mode/ACL
file_dac_write		default		Write access regardless of mode/ACL
file_link_any		default		Link access regardless of owner
file_owner		default		Other access regardless of owner
file_setid		default		Permission changes for set[gu]id files
ipc_dac_read		default		IPC read access regardless of mode
ipc_dac_write		default		IPC write access regardless of mode
ipc_owner		default		IPC other access regardless of owner
net_icmpaccess		default		ICMP packet access; ping(1M), etc
net_privaddr		default		Binding to privileged ports
proc_audit		default		Generation of audit records
proc_chroot		default		Changing of root directory
proc_info		default		Process examination
proc_owner		default		Process control regardless of owner
proc_session		default		Process control regardless of session
proc_setid		default		Setting of user/group IDs at will
proc_taskid		default		Assigning of task IDs to caller
sys_acct		default		Management of accounting
sys_admin		default		Simple system administration tasks
sys_audit		default		Management of auditing
sys_nfs			default		NFS support
sys_resource		default		Resource limit manipulation
