- 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);
- }
+ 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 (mach_vm_range_overflows(user_addr, user_size)) {
+ return EINVAL;
+ }
+ if (user_addr & vm_map_page_mask(user_map)) {
+ /* UNIX SPEC: user address is not page-aligned, return EINVAL */
+ return EINVAL;
+ }
+
+ switch (cryptid) {
+ case CRYPTID_NO_ENCRYPTION:
+ /* not encrypted, just an empty load command */
+ return 0;
+ case CRYPTID_APP_ENCRYPTION:
+ case CRYPTID_MODEL_ENCRYPTION:
+ 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) {
+ vpath = zalloc(ZV_NAMEI);
+
+ len = MAXPATHLEN;
+ ret = vn_getpath(vp, vpath, &len);
+ if (ret) {
+ zfree(ZV_NAMEI, vpath);
+ vnode_put(vp);
+ return ret;
+ }
+
+ vnode_put(vp);
+ } else {
+ return EINVAL;
+ }