static int sysctl_integriforce_so(SYSCTL_HANDLER_ARGS) { integriforce_so_check_t *integriforce_so; secadm_prison_entry_t *entry; secadm_rule_t r, *rule; struct nameidata nd; struct vattr vap; secadm_key_t key; int err; if (!(req->newptr) || req->newlen != sizeof(integriforce_so_check_t)) return (EINVAL); if (!(req->oldptr) || req->oldlen != sizeof(integriforce_so_check_t)) return (EINVAL); integriforce_so = malloc(sizeof(integriforce_so_check_t), M_SECADM, M_WAITOK); err = SYSCTL_IN(req, integriforce_so, sizeof(integriforce_so_check_t)); if (err) { free(integriforce_so, M_SECADM); return (err); } NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, integriforce_so->isc_path, req->td); err = namei(&nd); if (err) { free(integriforce_so, M_SECADM); NDFREE(&nd, 0); return (err); } if ((err = vn_lock(nd.ni_vp, LK_SHARED | LK_RETRY)) != 0) { free(integriforce_so, M_SECADM); NDFREE(&nd, 0); return (err); } err = VOP_GETATTR(nd.ni_vp, &vap, req->td->td_ucred); if (err) { free(integriforce_so, M_SECADM); NDFREE(&nd, 0); return (err); } VOP_UNLOCK(nd.ni_vp, 0); key.sk_jid = req->td->td_ucred->cr_prison->pr_id; key.sk_type = secadm_integriforce_rule; key.sk_fileid = vap.va_fileid; strncpy(key.sk_mntonname, nd.ni_vp->v_mount->mnt_stat.f_mntonname, MNAMELEN); r.sr_key = fnv_32_buf(&key, sizeof(secadm_key_t), FNV1_32_INIT); entry = get_prison_list_entry( req->td->td_ucred->cr_prison->pr_id); PE_RLOCK(entry); rule = RB_FIND(secadm_rules_tree, &(entry->sp_rules), &r); if (rule) { integriforce_so->isc_result = do_integriforce_check(rule, &vap, nd.ni_vp, req->td->td_ucred); } PE_RUNLOCK(entry); SYSCTL_OUT(req, integriforce_so, sizeof(integriforce_so_check_t)); free(integriforce_so, M_SECADM); NDFREE(&nd, 0); return (0); }
int secadm_vnode_check_exec(struct ucred *ucred, struct vnode *vp, struct label *vplabel, struct image_params *imgp, struct label *execlabel) { struct rm_priotracker tracker; struct secadm_prison_entry *entry; secadm_rule_t *rule; struct vattr vap; size_t i; int err=0, flags=0; entry = get_prison_list_entry(ucred->cr_prison->pr_name, 0); if (entry == NULL) return (0); err = VOP_GETATTR(imgp->vp, &vap, ucred); if (err) return (err); SPL_RLOCK(entry, tracker); for (rule = entry->spl_rules; rule != NULL; rule = rule->sr_next) { if (vap.va_fileid != rule->sr_inode) continue; if (strcmp(imgp->vp->v_mount->mnt_stat.f_mntonname, rule->sr_mount)) continue; for (i=0; i < rule->sr_nfeatures; i++) { switch(rule->sr_features[i].sf_type) { case pageexec_enabled: flags |= PAX_NOTE_PAGEEXEC; break; case pageexec_disabled: flags |= PAX_NOTE_NOPAGEEXEC; break; case mprotect_enabled: flags |= PAX_NOTE_MPROTECT; break; case mprotect_disabled: flags |= PAX_NOTE_NOMPROTECT; break; case segvguard_enabled: flags |= PAX_NOTE_SEGVGUARD; break; case segvguard_disabled: flags |= PAX_NOTE_NOSEGVGUARD; break; case aslr_enabled: flags |= PAX_NOTE_ASLR; break; case aslr_disabled: flags |= PAX_NOTE_NOASLR; break; case integriforce: err = do_integriforce_check(rule, &vap, imgp->vp, ucred); break; #if __HardenedBSD_version > 21 case shlibrandom_enabled: flags |= PAX_NOTE_SHLIBRANDOM; break; case shlibrandom_disabled: flags |= PAX_NOTE_NOSHLIBRANDOM; break; #endif default: break; } } break; } SPL_RUNLOCK(entry, tracker); if (err == 0 && flags) err = pax_elf(imgp, flags); return (err); }