6.4. SecurityOne of the basic tenets of the zone design is that no process running within a (non-global) zone, even one with superuser credentials (running with an effective user ID of 0), is allowed to view or affect activity in other zones. This implies that any operation initiated from within a zone must have an effect that is local to that zone. For example, the following activities are not allowed within a non-global zone:
The security model requires that only a subset of the operations normally restricted to superuser will be allowed within a zone, since many of those operations have a global impact. Operations that are not allowed include halting or rebooting the system, creating device nodes, and controlling allocation of global system resources. Processes running in the global zone still have the full set of privileges, allowing them to affect activity in any zone of the system. Effectively, the zone in which a process is running becomes part of its credential information, restricting its capabilities beyond those of processes with identical effective user and group IDs running in other zones. The following example shows the available privileges for the global and local zones. global# ppriv -S $$ 19876: bash flags = <none> E: all I: basic P: all L: all global# zlogin demozone [Connected to zone 'demozone' pts/2] Last login: Sat Feb 18 14:03:34 on pts/2 Sun Microsystems Inc. SunOS 5.10 Generic January 2005 myzone# id uid=0(root) gid=0(root) myzone# ppriv -S $$ 23829: -sh flags = <none> E: zone I: basic P: zone L: zone 6.4.1. Credential HandlingZones adds to the cred_t structure in the kernel, adding a cr_zone field pointing to the zone structure associated with the credential. This field is set for any process entering a zone and is inherited by the credentials used by all descendent processes within the zone. The cr_zone field is examined during privilege checks that use credential information, such as priv_policy(9F), drv_priv(9F), and hasprocperm. The kernel interface crgetzoneid(9F) accesses the zone ID without directly dereferencing the cred_t structure. 6.4.2. Fine-Grained PrivilegesThe Process Rights Management infrastructure (see Chapter 5) added a facility for breaking up the privileges that the kernel previously granted to processes with an effective uid of 0. The notion of "superuser privilege" is replaced by a set of specific privileges, such as the privilege to perform a mount or manipulate processor sets. This means that processes can perform certain privileged operations, but not others. 6.4.2.1. Safe PrivilegesThe privilege framework allows the restrictions on activity within a non-global zone to be expressed as a subset of privileges that are considered "safe" from a zone standpointthat is, those privileges that do not allow the exercising process to violate the security restrictions on a zone. Table 6.1 shows this list, and Table 6.2 shows the list of unsafe privileges that will normally only be available within the global zone. Note that the brief descriptions of privileges here are meant to be illustrative, not comprehensive; see the privileges(5) man page for the full descriptions.
6.4.2.2. Zone Privilege LimitsTo enable the restriction of privileges within a zone, the zone_create(2) system call includes an argument to specify the zone's privilege limit. This is the set of privileges that is used as a mask for all processes entering the zone, including the process that initiates booting the zone. Note that the limit on privileges available within a zone does not eliminate the need for restrictions on the objects a zone can access. Privileges can determine whether a process can perform a given operation, but if the operation is allowed, they do not restrict the objects to which that operation can be applied. (A special case involves objects with an effective user ID of 0, as described below, but the general rule holds.) For example, the PRIV_PROC_MOUNT privilege allows a process to mount file systems; if the process has that privilege, it can mount file systems anywhere in the file system namespace. Zones, on the other hand, primarily restrict the namespace and objects to which operations (even unprivileged operations) can be applied; it is only when such restrictions are not possible that the privileges available within a zone must be limited. In short, privileges and zones are complementary technologies. At present, the set of privileges available within a zone is fixed (to the "safe" set) and cannot be modified by an administrator. The ppriv(1) command has been extended to include an option to report the privileges available within the current zone, and the zone token can be used in strings passed to priv_str_to_set(3c) to refer to the zone's privilege set. The following example shows the output of the new ppriv option. my_zone# ppriv -z file_chown file_chown_self file_dac_execute file_dac_read file_dac_search file_dac_write file_link_any file_owner file_setdac file_setid ipc_dac_read ipc_dac_write ipc_owner net_privaddr net_icmpaccess proc_chroot proc_audit proc_exec proc_fork proc_owner proc_session proc_setid proc_taskid sys_acct sys_admin sys_mount sys_nfs sys_resource This option can also be combined with -v for more verbose output describing each privilege. 6.4.2.3. Privilege EscalationThe problem of privilege escalation represents an additional complication. To prevent a process with a subset of privileges from being able to use those privileges to acquire additional privileges, a number of operations involving root-owned system objects require that the calling process have all privileges. For example, write access to root-owned files by a non-root process requires all privileges, as does establishing control over a process with an effective uid of 0. The intent is to prevent non-root processes with some but not all privileges from using the special treatment of root to escalate privileges; for example, if a non-root process with the PRIV_FILE_DAC_WRITE privilege is allowed to modify the text of kernel modules, it can cause a module to be loaded that awards it all privileges. Since no process in a non-global zone will have all privileges, the requirement of all privileges for operations involving root-owned objects presents a problem. On the other hand, since even root within a zone has a restricted set of privileges, no privilege escalation is possible beyond the set of zone's privilege limit; thus, it seems appropriate to change the restriction to be the privilege limit for the zone (or all privileges in the global zone). Note that certain other operations (for example, loading kernel modules) require all privileges because they can be used to control the entire system. These operations should continue to require all privileges, regardless of the zone in which the process is running. 6.4.3. Role-Based Access ControlLike privileges, the role-based access control (RBAC) facility provides a way of making the superuser model more granular. With RBAC, an administrator can give particular users (or "roles"identities that can be assumed by existing users through su(1M) but cannot be used for external login) the right to perform operations that would otherwise require superuser privileges. These operations are expressed as authorizations; as rights explicitly checked by applications (usually running setuid root); or with profiles, lists of commands that can be executed with pfexec(1) or the "profile shells" (pfsh(1), pfcsh(1), pfksh(1)). Authorizations differ from privileges in that authorizations are enforced by user-level applications (including the profile shells), rather than the kernel. Like privileges, though, they provide fine-grained control over the set of operations a given process can perform, but not over the objects that those operations can affect. As with privileges, this control complements the restrictions imposed by zones. The zone administration commands requiring privilege (zoneadm(1M), zonecfg(1M), and zlogin(1)) use a new "Zone Management" rights profile. 6.4.4. chroot InteractionsThe functionality made available by chroot(2) is similar in some ways to zones, in that both provide ways to restrict the part of the file system hierarchy that a process and its descendants can access. chroot, however, has a number of problems from a security perspective. In particular, any process that is given superuser privileges can easily escape a chroot restriction. The problem is that chroot calls don't "nest" safely. A process inside a chrooted environment can call chroot to change its working directory to something "below" the current working directory, then make successive chdir("..") calls until it reaches the real root directory for the system. This works because the check to determine whether a process is escaping its chroot restriction works by processing a path name and comparing the directory being traversed in each component with the root directory that has been set for the process; if the process has access to a directory "above" its root directory, the check is bypassed.[4]
This issue is addressed for zones in two ways. One is that a process inside a zone (other than the global zone) cannot enter another zone; this prevents a process running as superuser in a zone from escaping the zone's root directory restriction in a manner similar to what is possible with chroot. The other is that the zone's root directory (represented by the zone_rootvp field in the kernel's zone_t structure) is distinct from the root directory set by chroot for processes within a zone (represented by the u_rdir field in the kernel's user_t) structure). Both restrictions are checked when traversing path-name components; this means that chroot can be used within a zone, but a process that escapes from its chroot restriction will still be unable to escape the zone restriction. |