tlabel.c revision 5f9878b0212a5bc5924a85d227160bf7f43712f1
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * CDDL HEADER START
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * The contents of this file are subject to the terms of the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Common Development and Distribution License (the "License").
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * You may not use this file except in compliance with the License.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * See the License for the specific language governing permissions
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * and limitations under the License.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * When distributing Covered Code, include this CDDL HEADER in each
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * If applicable, add the following below this CDDL HEADER, with the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * fields enclosed by brackets "[]" replaced with your own identifying
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * information: Portions Copyright [yyyy] [name of copyright owner]
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * CDDL HEADER END
5f9878b0212a5bc5924a85d227160bf7f43712f1ken Powell - Sun Microsystem * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Use is subject to license terms.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Initialize labels infrastructure.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * This is called during startup() time (before vfs_mntroot) by thread_init().
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * It has to be called early so that the is_system_labeled() function returns
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * the right value when called by the networking code on a diskless boot.
f875b4ebb1dd9fdbeb043557cab38ab3bf7f6e01rica * sys_labeling will default to "off" unless it is overridden
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk tslabel_cache = kmem_cache_create("tslabel_cache", sizeof (ts_label_t),
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk l_admin_low = labelalloc(&label, default_doi, KM_SLEEP);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk l_admin_high = labelalloc(&label, default_doi, KM_SLEEP);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Allocate new ts_label_t.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk ts_label_t *lab = kmem_cache_alloc(tslabel_cache, flag);
5f9878b0212a5bc5924a85d227160bf7f43712f1ken Powell - Sun Microsystem * Duplicate an existing ts_label_t to a new one, with only
5f9878b0212a5bc5924a85d227160bf7f43712f1ken Powell - Sun Microsystem * the current reference.
5f9878b0212a5bc5924a85d227160bf7f43712f1ken Powell - Sun Microsystemlabeldup(const ts_label_t *val, int flag)
5f9878b0212a5bc5924a85d227160bf7f43712f1ken Powell - Sun Microsystem ts_label_t *lab = kmem_cache_alloc(tslabel_cache, flag);
5f9878b0212a5bc5924a85d227160bf7f43712f1ken Powell - Sun Microsystem bcopy(val, lab, sizeof (ts_label_t));
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Put a hold on a label structure.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Release previous hold on a label structure. Free it if refcnt == 0.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Compare labels. Return 1 if equal, 0 otherwise.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * There's no protocol today to obtain the label from the server.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * So we rely on conventions: zones, zone names, and zone paths
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * must match across TX servers and their TX clients. Now use
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * the exported name to find the equivalent local zone and its
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * label. Caller is responsible for doing a label_rele of the
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * returned ts_label.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk /* treat path as absolute but it doesn't have leading '/' */
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Skip over zonepath (not including "root"), e.g. /zone/internal
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk /* Check if we now have something like "/zone/public/" */
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk /* LINTED: following cast to ipaddr is OK */
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk } else if (strcmp(knconf->knc_protofmly, NC_INET6) == 0) {
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk /* LINTED: following cast to ipaddr is OK */
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk ipaddr = &((struct sockaddr_in6 *)addr->buf)->sin6_addr;
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk srv_label = labelalloc(server_sl, default_doi, KM_SLEEP);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * getflabel -
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Return pointer to the ts_label associated with the specified file,
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * or returns NULL if error occurs. Caller is responsible for doing
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * a label_rele of the ts_label.
6fc927dcbbe5140bbff7f486b9ffdec8d53475c7gfaden * Traverse lofs mounts and fattach'es to get the real vnode
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk /* rvp/rvfsp now represent the real vnode/vfs we will be using */
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk /* Go elsewhere to handle all nfs files. */
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if (strncmp(vfssw[rvfsp->vfs_fstype].vsw_name, "nfs", 3) == 0)
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Fast path, for objects in a labeled zone: everything except
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * for lofs/nfs will be just the label of that zone.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if ((rvfsp->vfs_zone != NULL) && (rvfsp->vfs_zone != global_zone)) {
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk "lofs") != 0)) {
6fc927dcbbe5140bbff7f486b9ffdec8d53475c7gfaden if (vnodetopath(rootdir, rvp, vpath, sizeof (vpath), kcred) != 0) {
6fc927dcbbe5140bbff7f486b9ffdec8d53475c7gfaden * Sanity check - vpath may be weird for some cases, like devices.
afed4af446df25a67c4d63dc872b57e1fefa11bcrica * If a mountpoint exists, hold the vfs while we reference it.
afed4af446df25a67c4d63dc872b57e1fefa11bcrica * Otherwise if mountpoint is NULL it should not be held (e.g.,
afed4af446df25a67c4d63dc872b57e1fefa11bcrica * a hold/release on spec_vfs would result in an attempted free
afed4af446df25a67c4d63dc872b57e1fefa11bcrica * and panic.)
6fc927dcbbe5140bbff7f486b9ffdec8d53475c7gfaden * If the vnode source zone is properly set to a non-global zone, or
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * any zone if the mount is R/W, then use the label of that zone.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if ((zone != global_zone) || ((vfsp->vfs_flag & VFS_RDONLY) != 0))
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Otherwise, if we're not in the global zone, use the label of
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * our zone.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * We're in the global zone and the mount is R/W ... so the file
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * may actually be in the global zone -- or in the root of any zone.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Always build our own path for the file, to be sure it's simplified
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * (i.e., no ".", "..", "//", and so on).
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if ((curproc->p_zone == global_zone) && (zone == global_zone)) {
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * File is in the global zone - check whether it's admin_high.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * If it's in a filesys that was exported from the global zone,
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * it's admin_low by definition. Otherwise, if it's in a
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * filesys that's NOT exported to any zone, it's admin_high.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * And for these files if there wasn't a valid mount resource,
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * the file must be admin_high (not exported, probably a global
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * zone device).
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk /* force admin_low */
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk const char *rstr;
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Check for a match: does this vfs correspond
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * to our global zone file path? I.e., check
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * if the resource string of this vfs is a
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * prefix of our path.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk /* force admin_low */
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Now that we have the "home" zone for the file, return the slabel
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * of that zone.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if (copyout((caddr_t)label2bslabel(tsl), (caddr_t)label_p,
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk sizeof (*(label_p))) != 0)
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * fgetlabel(2TSOL) - get file label
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * getlabel(2TSOL) - get file label
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk /* Sanity check arguments */
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if ((error = copyinstr(path, spath, MAXPATHLEN, NULL)) != 0) {
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk if (error = lookupname(spath, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp)) {
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (0);
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk return (0);
0398691684c2596072212e4ca9d7033ad7ccfa54jarrett * Used by NFSv3 and NFSv4 server to query label of
0398691684c2596072212e4ca9d7033ad7ccfa54jarrett * a pathname component during lookup/access ops.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * mount traverse has been done by caller
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * before calling this routine.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * v_path not cached. Since we rely on path
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * of an obj to get its label, we need to get
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * path corresponding to the parent vnode.
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * Caller has verified that the file is either
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * exported or visible. So if the path falls in
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * global zone, admin_low is returned; otherwise
45916cd2fec6e79bca5dee0421bd39e3c2910d1ejpk * the zone's label is returned.