+static int
+vnguard_sysc_getguardattr(proc_t p, struct vnguard_getattr *vga)
+{
+ const int fd = vga->vga_fd;
+
+ if (0 == vga->vga_guard) {
+ return EINVAL;
+ }
+
+ int error;
+ struct fileproc *fp;
+ if (0 != (error = fp_lookup(p, fd, &fp, 0))) {
+ return error;
+ }
+ do {
+ struct fileglob *fg = fp->f_fglob;
+ if (FILEGLOB_DTYPE(fg) != DTYPE_VNODE) {
+ error = EBADF;
+ break;
+ }
+ struct vnode *vp = fg->fg_data;
+ if (!vnode_isreg(vp) || NULL == vp->v_mount) {
+ error = EBADF;
+ break;
+ }
+ error = vnode_getwithref(vp);
+ if (0 != error) {
+ break;
+ }
+
+ vga->vga_attrs = 0;
+
+ lck_rw_lock_shared(&llock);
+
+ if (NULL != vp->v_label) {
+ const struct vng_info *vgi = vng_lbl_get(vp->v_label);
+ if (NULL != vgi) {
+ if (vgi->vgi_guard != vga->vga_guard) {
+ error = EPERM;
+ } else {
+ vga->vga_attrs = vgi->vgi_attrs;
+ }
+ }
+ }
+
+ lck_rw_unlock_shared(&llock);
+ vnode_put(vp);
+ } while (0);
+
+ fp_drop(p, fd, fp, 0);
+ return error;
+}
+