void mac_vnode_init(struct vnode *vp) { if (mac_labeled & MPC_OBJECT_VNODE) vp->v_label = mac_vnode_label_alloc(); else vp->v_label = NULL; }
void mac_execve_interpreter_enter(struct vnode *interpvp, struct label **interpvplabel) { if (mac_labeled & MPC_OBJECT_VNODE) { *interpvplabel = mac_vnode_label_alloc(); mac_vnode_copy_label(interpvp->v_label, *interpvplabel); } else *interpvplabel = NULL; }
/* * Caller holds I/O reference on vnode */ int vnode_label(struct mount *mp, struct vnode *dvp, struct vnode *vp, struct componentname *cnp, int flags, vfs_context_t ctx) { int error = 0; /* fast path checks... */ /* are we labeling vnodes? If not still notify of create */ if (mac_label_vnodes == 0) { if (flags & VNODE_LABEL_CREATE) error = mac_vnode_notify_create(ctx, mp, dvp, vp, cnp); return 0; } /* if already VL_LABELED */ if (vp->v_lflag & VL_LABELED) return (0); vnode_lock_spin(vp); /* * must revalidate state once we hold the lock * since we could have blocked and someone else * has since labeled this vnode */ if (vp->v_lflag & VL_LABELED) { vnode_unlock(vp); return (0); } if ((vp->v_lflag & VL_LABEL) == 0) { vp->v_lflag |= VL_LABEL; /* Could sleep on disk I/O, drop lock. */ vnode_unlock(vp); if (vp->v_label == NULL) vp->v_label = mac_vnode_label_alloc(); if (flags & VNODE_LABEL_CREATE) error = mac_vnode_notify_create(ctx, mp, dvp, vp, cnp); else error = mac_vnode_label_associate(mp, vp, ctx); vnode_lock_spin(vp); if ((error == 0) && (vp->v_flag & VNCACHEABLE)) vp->v_lflag |= VL_LABELED; vp->v_lflag &= ~VL_LABEL; if (vp->v_lflag & VL_LABELWAIT) { vp->v_lflag &= ~VL_LABELWAIT; wakeup(&vp->v_label); } } else { struct timespec ts; ts.tv_sec = 10; ts.tv_nsec = 0; while (vp->v_lflag & VL_LABEL) { vp->v_lflag |= VL_LABELWAIT; error = msleep(&vp->v_label, &vp->v_lock, PVFS|PDROP, "vnode_label", &ts); vnode_lock_spin(vp); if (error == EWOULDBLOCK) { vprint("vnode label timeout", vp); break; } } /* XXX: what should be done if labeling failed (above)? */ } vnode_unlock(vp); return (error); }