Esempio n. 1
0
int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
{
	struct vm_area_struct * vma;
	int result = -ENOENT;
	struct task_struct *task = proc_task(inode);
	struct mm_struct * mm = get_task_mm(task);

	if (!mm)
		goto out;
	down_read(&mm->mmap_sem);

	vma = mm->mmap;
	while (vma) {
		if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
			break;
		vma = vma->vm_next;
	}

	if (vma) {
		*mnt = mntget(vma->vm_file->f_vfsmnt);
		*dentry = dget(vma->vm_file->f_dentry);
		result = 0;
	}

	up_read(&mm->mmap_sem);
	mmput(mm);
out:
	return result;
}
Esempio n. 2
0
static struct proc *
mac_task_get_proc(struct task *task)
{
	if (task == current_task())
		return proc_self();

	/*
	 * Tasks don't really hold a reference on a proc unless the
	 * calling thread belongs to the task in question.
	 */
	int pid = task_pid(task);
	struct proc *p = proc_find(pid);

	if (p != NULL) {
		if (proc_task(p) == task)
			return p;
		proc_rele(p);
	}
	return NULL;
}
Esempio n. 3
0
int
mremap_encrypted(__unused struct proc *p, struct mremap_encrypted_args *uap, __unused int32_t *retval)
{
    mach_vm_offset_t	user_addr;
    mach_vm_size_t	user_size;
    kern_return_t	result;
    vm_map_t	user_map;
    uint32_t	cryptid;
    cpu_type_t	cputype;
    cpu_subtype_t	cpusubtype;
    pager_crypt_info_t	crypt_info;
    const char * cryptname = 0;
    char *vpath;
    int len, ret;
    struct proc_regioninfo_internal pinfo;
    vnode_t vp;
    uintptr_t vnodeaddr;
    uint32_t vid;
    
    AUDIT_ARG(addr, uap->addr);
    AUDIT_ARG(len, uap->len);
    
    user_map = current_map();
    user_addr = (mach_vm_offset_t) uap->addr;
    user_size = (mach_vm_size_t) uap->len;
    
    cryptid = uap->cryptid;
    cputype = uap->cputype;
    cpusubtype = uap->cpusubtype;
    
    if (user_addr & vm_map_page_mask(user_map)) {
        /* UNIX SPEC: user address is not page-aligned, return EINVAL */
        return EINVAL;
    }
    
    switch(cryptid) {
        case 0:
            /* not encrypted, just an empty load command */
            return 0;
        case 1:
            cryptname="com.apple.unfree";
            break;
        case 0x10:
            /* some random cryptid that you could manually put into
             * your binary if you want NULL */
            cryptname="com.apple.null";
            break;
        default:
            return EINVAL;
    }
    
    if (NULL == text_crypter_create) return ENOTSUP;
    
    ret = fill_procregioninfo_onlymappedvnodes( proc_task(p), user_addr, &pinfo, &vnodeaddr, &vid);
    if (ret == 0 || !vnodeaddr) {
        /* No really, this returns 0 if the memory address is not backed by a file */
        return (EINVAL);
    }
    
    vp = (vnode_t)vnodeaddr;
    if ((vnode_getwithvid(vp, vid)) == 0) {
        MALLOC_ZONE(vpath, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);
        if(vpath == NULL) {
            vnode_put(vp);
            return (ENOMEM);
        }
        
        len = MAXPATHLEN;
        ret = vn_getpath(vp, vpath, &len);
        if(ret) {
            FREE_ZONE(vpath, MAXPATHLEN, M_NAMEI);
            vnode_put(vp);
            return (ret);
        }
        
        vnode_put(vp);
    } else {
        return (EINVAL);
    }

#if 0
    kprintf("%s vpath %s cryptid 0x%08x cputype 0x%08x cpusubtype 0x%08x range 0x%016llx size 0x%016llx\n",
            __FUNCTION__, vpath, cryptid, cputype, cpusubtype, (uint64_t)user_addr, (uint64_t)user_size);
#endif

    /* set up decrypter first */
    crypt_file_data_t crypt_data = {
        .filename = vpath,
        .cputype = cputype,
        .cpusubtype = cpusubtype };
    result = text_crypter_create(&crypt_info, cryptname, (void*)&crypt_data);
#if VM_MAP_DEBUG_APPLE_PROTECT
    if (vm_map_debug_apple_protect) {
	    printf("APPLE_PROTECT: %d[%s] map %p [0x%llx:0x%llx] %s(%s) -> 0x%x\n",
		   p->p_pid, p->p_comm,
		   user_map,
		   (uint64_t) user_addr,
		   (uint64_t) (user_addr + user_size),
		   __FUNCTION__, vpath, result);
    }
#endif /* VM_MAP_DEBUG_APPLE_PROTECT */
    FREE_ZONE(vpath, MAXPATHLEN, M_NAMEI);
    
    if(result) {
        printf("%s: unable to create decrypter %s, kr=%d\n",
               __FUNCTION__, cryptname, result);
        if (result == kIOReturnNotPrivileged) {
            /* text encryption returned decryption failure */
            return (EPERM);
        } else {
            return (ENOMEM);
        }
    }
    
    /* now remap using the decrypter */
    vm_object_offset_t crypto_backing_offset;
    crypto_backing_offset = -1;	/* i.e. use map entry's offset */
    result = vm_map_apple_protected(user_map,
				    user_addr,
				    user_addr+user_size,
				    crypto_backing_offset,
				    &crypt_info);
    if (result) {
        printf("%s: mapping failed with %d\n", __FUNCTION__, result);
    }
   
    if (result) {
        return (EPERM);
    }
    return 0;
}