- if (!cs_enforcement_enable || csr_state.funcs == NULL)
- return ENOTSUP;
-
- lck_rw_lock_exclusive(SigPUPLock);
-
- if (kauth_cred_issuser(kauth_cred_get()) == 0) {
- error = EPERM;
- goto cleanup;
- }
-
- if (cs_debug > 10)
- printf("sigpup install\n");
-
- if (csr_state.csr_map_base != 0 || csr_state.inuse) {
- error = EPERM;
- goto cleanup;
- }
-
- if (USER_ADDR_NULL == argsp) {
- error = EINVAL;
- goto cleanup;
- }
- if ((error = copyin(argsp, &args, sizeof(args))) != 0)
- goto cleanup;
-
- if (cs_debug > 10)
- printf("sigpup install with args\n");
-
- MALLOC(buf, char *, MAXPATHLEN, M_TEMP, M_WAITOK);
- if (buf == NULL) {
- error = ENOMEM;
- goto cleanup;
- }
- if ((error = copyinstr((user_addr_t)args.path, buf, MAXPATHLEN, &len)) != 0)
- goto cleanup;
-
- if ((vfs = vfs_context_create(NULL)) == NULL) {
- error = ENOMEM;
- goto cleanup;
- }
-
- if ((error = vnode_lookup(buf, VNODE_LOOKUP_NOFOLLOW, &vp, vfs)) != 0)
- goto cleanup;
-
- if (cs_debug > 10)
- printf("sigpup found file: %s\n", buf);
-
- /* make sure vnode is on the process's root volume */
- if (rootvnode->v_mount != vp->v_mount) {
- if (cs_debug) printf("sigpup csr no on root volume\n");
- error = EPERM;
- goto cleanup;
- }
-
- /* make sure vnode is owned by "root" */
- VATTR_INIT(&va);
- VATTR_WANTED(&va, va_uid);
- error = vnode_getattr(vp, &va, vfs);
- if (error)
- goto cleanup;
-
- if (va.va_uid != 0) {
- if (cs_debug) printf("sigpup: csr file not owned by root\n");
- error = EPERM;
- goto cleanup;
- }
-
- error = vnsize(vfs, vp, &size);
- if (error)
- goto cleanup;
-
- control = ubc_getobject(vp, 0);
- if (control == MEMORY_OBJECT_CONTROL_NULL) {
- error = EINVAL;
- goto cleanup;
- }
-
- csr_state.csr_map_size = mach_vm_round_page(size);
-
- if (cs_debug > 10)
- printf("mmap!\n");
-
- result = vm_map_enter_mem_object_control(kernel_map,
- &csr_state.csr_map_base,
- csr_state.csr_map_size,
- 0, VM_FLAGS_ANYWHERE,
- control, 0 /* file offset */,
- 0 /* cow */,
- VM_PROT_READ,
- VM_PROT_READ,
- VM_INHERIT_DEFAULT);
- if (result != KERN_SUCCESS) {
- error = EINVAL;
- goto cleanup;
- }
-
- error = csr_state.funcs->csr_validate_header((const uint8_t *)csr_state.csr_map_base,
- csr_state.csr_map_size);
- if (error) {
- if (cs_debug > 10)
- printf("sigpup header invalid, dropping mapping");
- sigpup_drop();
- goto cleanup;
- }
-
- if (cs_debug > 10)
- printf("table loaded %ld bytes\n", (long)csr_state.csr_map_size);
-
-cleanup:
- lck_rw_unlock_exclusive(SigPUPLock);
-
- if (buf)
- FREE(buf, M_TEMP);
- if (vp)
- (void)vnode_put(vp);
- if (vfs)
- (void)vfs_context_rele(vfs);
-
- if (error)
- printf("sigpup: load failed with error: %d\n", error);
-