X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0a7de7458d150b5d4dffc935ba399be265ef0a1a..a991bd8d3e7fe02dbca0644054bab73c5b75324a:/bsd/kern/kern_core.c?ds=sidebyside diff --git a/bsd/kern/kern_core.c b/bsd/kern/kern_core.c index 77c38ccbe..a4a3ee6cf 100644 --- a/bsd/kern/kern_core.c +++ b/bsd/kern/kern_core.c @@ -66,10 +66,9 @@ #include -#if CONFIG_CSR -#include -#include -#endif +#if CONFIG_MACF +#include +#endif /* CONFIG_MACF */ typedef struct { int flavor; /* the number for this flavor */ @@ -105,10 +104,10 @@ int mynum_flavors = 2; typedef struct { vm_offset_t header; - int hoffset; + size_t hoffset; mythread_state_flavor_t *flavors; - int tstate_size; - int flavor_count; + size_t tstate_size; + size_t flavor_count; } tir_t; extern int freespace_mb(vnode_t vp); @@ -174,7 +173,7 @@ static void collectth_state(thread_t th_act, void *tirp) { vm_offset_t header; - int hoffset, i; + size_t hoffset, i; mythread_state_flavor_t *flavors; struct thread_command *tc; tir_t *t = (tir_t *)tirp; @@ -188,8 +187,8 @@ collectth_state(thread_t th_act, void *tirp) tc = (struct thread_command *) (header + hoffset); tc->cmd = LC_THREAD; - tc->cmdsize = sizeof(struct thread_command) - + t->tstate_size; + tc->cmdsize = (uint32_t)(sizeof(struct thread_command) + + t->tstate_size); hoffset += sizeof(struct thread_command); /* * Follow with a struct thread_state_flavor and @@ -221,7 +220,7 @@ collectth_state(thread_t th_act, void *tirp) * coredump_flags Extra options (ignore rlimit, run fsync) * * Returns: 0 Success - * EFAULT Failed + * !0 Failure errno * * IMPORTANT: This function can only be called on the current process, due * to assumptions below; see variable declaration section for @@ -239,9 +238,9 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags) kauth_cred_t cred = vfs_context_ucred(ctx); int error = 0; struct vnode_attr va; - int thread_count, segment_count; - int command_size, header_size, tstate_size; - int hoffset; + size_t thread_count, segment_count; + size_t command_size, header_size, tstate_size; + size_t hoffset; off_t foffset; mach_vm_offset_t vmoffset; vm_offset_t header; @@ -252,10 +251,10 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags) int error1 = 0; char stack_name[MAXCOMLEN + 6]; char *alloced_name = NULL; - char *name; + char *name = NULL; mythread_state_flavor_t flavors[MAX_TSTATE_FLAVORS]; vm_size_t mapsize; - int i; + size_t i; uint32_t nesting_depth = 0; kern_return_t kret; struct vm_region_submap_info_64 vbr; @@ -276,23 +275,14 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags) ((sugid_coredump == 0) && /* Not dumping SUID/SGID binaries */ ((kauth_cred_getsvuid(cred) != kauth_cred_getruid(cred)) || (kauth_cred_getsvgid(cred) != kauth_cred_getrgid(cred))))) { -#if CONFIG_AUDIT - audit_proc_coredump(core_proc, NULL, EFAULT); -#endif - return EFAULT; + error = EFAULT; + goto out2; } -#if CONFIG_CSR - /* If the process is restricted, CSR isn't configured to allow - * restricted processes to be debugged, and CSR isn't configured in - * AppleInternal mode, then don't dump core. */ - if (cs_restricted(core_proc) && - csr_check(CSR_ALLOW_TASK_FOR_PID) && - csr_check(CSR_ALLOW_APPLE_INTERNAL)) { -#if CONFIG_AUDIT - audit_proc_coredump(core_proc, NULL, EFAULT); -#endif - return EFAULT; +#if CONFIG_MACF + error = mac_proc_check_dump_core(core_proc); + if (error != 0) { + goto out2; } #endif @@ -305,8 +295,9 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags) mapsize = get_vmmap_size(map); if (((coredump_flags & COREDUMP_IGNORE_ULIMIT) == 0) && - (mapsize >= core_proc->p_rlimit[RLIMIT_CORE].rlim_cur)) { - return EFAULT; + (mapsize >= proc_limitgetcur(core_proc, RLIMIT_CORE, FALSE))) { + error = EFAULT; + goto out2; } (void) task_suspend_internal(task); @@ -367,11 +358,34 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags) tstate_size += sizeof(mythread_state_flavor_t) + (flavors[i].count * sizeof(int)); } - command_size = segment_count * segment_command_sz + - thread_count * sizeof(struct thread_command) + - tstate_size * thread_count; - header_size = command_size + mach_header_sz; + { + size_t lhs; + size_t rhs; + + /* lhs = segment_count * segment_command_sz */ + if (os_mul_overflow(segment_count, segment_command_sz, &lhs)) { + error = ENOMEM; + goto out; + } + + /* rhs = (tstate_size + sizeof(struct thread_command)) * thread_count */ + if (os_add_and_mul_overflow(tstate_size, sizeof(struct thread_command), thread_count, &rhs)) { + error = ENOMEM; + goto out; + } + + /* command_size = lhs + rhs */ + if (os_add_overflow(lhs, rhs, &command_size)) { + error = ENOMEM; + goto out; + } + } + + if (os_add_overflow(command_size, mach_header_sz, &header_size)) { + error = ENOMEM; + goto out; + } if (kmem_alloc(kernel_map, &header, (vm_size_t)header_size, VM_KERN_MEMORY_DIAG) != KERN_SUCCESS) { error = ENOMEM; @@ -387,8 +401,8 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags) mh64->cputype = process_cpu_type(core_proc); mh64->cpusubtype = process_cpu_subtype(core_proc); mh64->filetype = MH_CORE; - mh64->ncmds = segment_count + thread_count; - mh64->sizeofcmds = command_size; + mh64->ncmds = (uint32_t)(segment_count + thread_count); + mh64->sizeofcmds = (uint32_t)command_size; mh64->reserved = 0; /* 8 byte alignment */ } else { mh = (struct mach_header *)header; @@ -396,8 +410,8 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags) mh->cputype = process_cpu_type(core_proc); mh->cpusubtype = process_cpu_subtype(core_proc); mh->filetype = MH_CORE; - mh->ncmds = segment_count + thread_count; - mh->sizeofcmds = command_size; + mh->ncmds = (uint32_t)(segment_count + thread_count); + mh->sizeofcmds = (uint32_t)command_size; } hoffset = mach_header_sz; /* offset into header */ @@ -472,8 +486,8 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags) sc->cmdsize = sizeof(struct segment_command); /* segment name is zeroed by kmem_alloc */ sc->segname[0] = 0; - sc->vmaddr = CAST_DOWN_EXPLICIT(vm_offset_t, vmoffset); - sc->vmsize = CAST_DOWN_EXPLICIT(vm_size_t, vmsize); + sc->vmaddr = CAST_DOWN_EXPLICIT(uint32_t, vmoffset); + sc->vmsize = CAST_DOWN_EXPLICIT(uint32_t, vmsize); sc->fileoff = CAST_DOWN_EXPLICIT(uint32_t, foffset); /* will never truncate */ sc->filesize = CAST_DOWN_EXPLICIT(uint32_t, vmsize); /* will never truncate */ sc->maxprot = maxprot; @@ -534,7 +548,7 @@ coredump(proc_t core_proc, uint32_t reserve_mb, int coredump_flags) * Write out the Mach header at the beginning of the * file. OK to use a 32 bit write for this. */ - error = vn_rdwr(UIO_WRITE, vp, (caddr_t)header, header_size, (off_t)0, + error = vn_rdwr(UIO_WRITE, vp, (caddr_t)header, (int)MIN(header_size, INT_MAX), (off_t)0, UIO_SYSSPACE, IO_NOCACHE | IO_NODELOCKED | IO_UNIT, cred, (int *) 0, core_proc); kmem_free(kernel_map, header, header_size);