]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/i386/bsd_i386.c
xnu-7195.101.1.tar.gz
[apple/xnu.git] / osfmk / i386 / bsd_i386.c
index a1d3b4965cf0ca1a8d860f12baa3d0bbd85ce57c..b25d0f5d6b5f4853e2ff2c2ab2cf0afc554f0c43 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2016 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  *
@@ -34,7 +34,6 @@
 #include <mach/thread_status.h>
 #include <mach/vm_param.h>
 
-#include <kern/counters.h>
 #include <kern/cpu_data.h>
 #include <kern/mach_param.h>
 #include <kern/task.h>
@@ -73,6 +72,10 @@ extern void     mach_kauth_cred_uthread_update(void);
 extern void throttle_lowpri_io(int);
 #endif
 
+#if CONFIG_MACF
+#include <security/mac_mach_internal.h>
+#endif
+
 void * find_user_regs(thread_t);
 
 unsigned int get_msr_exportmask(void);
@@ -92,7 +95,7 @@ thread_userstack(
        __unused thread_t   thread,
        int                 flavor,
        thread_state_t      tstate,
-       __unused unsigned int        count,
+       unsigned int        count,
        mach_vm_offset_t    *user_stack,
        int                 *customstack,
        __unused boolean_t  is64bit
@@ -107,6 +110,10 @@ thread_userstack(
        {
                x86_thread_state32_t *state25;
 
+               if (__improbable(count != x86_THREAD_STATE32_COUNT)) {
+                       return KERN_INVALID_ARGUMENT;
+               }
+
                state25 = (x86_thread_state32_t *) tstate;
 
                if (state25->esp) {
@@ -124,11 +131,37 @@ thread_userstack(
        }
 
        case x86_THREAD_FULL_STATE64:
-       /* FALL THROUGH */
+       {
+               x86_thread_full_state64_t *state25;
+
+               if (__improbable(count != x86_THREAD_FULL_STATE64_COUNT)) {
+                       return KERN_INVALID_ARGUMENT;
+               }
+
+               state25 = (x86_thread_full_state64_t *) tstate;
+
+               if (state25->ss64.rsp) {
+                       *user_stack = state25->ss64.rsp;
+                       if (customstack) {
+                               *customstack = 1;
+                       }
+               } else {
+                       *user_stack = VM_USRSTACK64;
+                       if (customstack) {
+                               *customstack = 0;
+                       }
+               }
+               break;
+       }
+
        case x86_THREAD_STATE64:
        {
                x86_thread_state64_t *state25;
 
+               if (__improbable(count != x86_THREAD_STATE64_COUNT)) {
+                       return KERN_INVALID_ARGUMENT;
+               }
+
                state25 = (x86_thread_state64_t *) tstate;
 
                if (state25->rsp) {
@@ -176,7 +209,7 @@ thread_entrypoint(
        __unused thread_t   thread,
        int                 flavor,
        thread_state_t      tstate,
-       __unused unsigned int        count,
+       unsigned int        count,
        mach_vm_offset_t    *entry_point
        )
 {
@@ -192,6 +225,10 @@ thread_entrypoint(
        {
                x86_thread_state32_t *state25;
 
+               if (count != x86_THREAD_STATE32_COUNT) {
+                       return KERN_INVALID_ARGUMENT;
+               }
+
                state25 = (i386_thread_state_t *) tstate;
                *entry_point = state25->eip ? state25->eip : VM_MIN_ADDRESS;
                break;
@@ -201,6 +238,10 @@ thread_entrypoint(
        {
                x86_thread_state64_t *state25;
 
+               if (count != x86_THREAD_STATE64_COUNT) {
+                       return KERN_INVALID_ARGUMENT;
+               }
+
                state25 = (x86_thread_state64_t *) tstate;
                *entry_point = state25->rip ? state25->rip : VM_MIN_ADDRESS64;
                break;
@@ -441,7 +482,7 @@ mach_call_arg_munger32(uint32_t sp, struct mach_call_args *args, const mach_trap
 
 __private_extern__ void mach_call_munger(x86_saved_state_t *state);
 
-extern const char *mach_syscall_name_table[];
+extern const char *const mach_syscall_name_table[];
 
 __attribute__((noreturn))
 void
@@ -451,7 +492,17 @@ mach_call_munger(x86_saved_state_t *state)
        int call_number;
        mach_call_t mach_call;
        kern_return_t retval;
-       struct mach_call_args args = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+       struct mach_call_args args = {
+               .arg1 = 0,
+               .arg2 = 0,
+               .arg3 = 0,
+               .arg4 = 0,
+               .arg5 = 0,
+               .arg6 = 0,
+               .arg7 = 0,
+               .arg8 = 0,
+               .arg9 = 0
+       };
        x86_saved_state32_t     *regs;
 
        struct uthread *ut = get_bsdthread_info(current_thread());
@@ -504,8 +555,30 @@ mach_call_munger(x86_saved_state_t *state)
            MACHDBG_CODE(DBG_MACH_EXCP_SC, (call_number)) | DBG_FUNC_START,
            args.arg1, args.arg2, args.arg3, args.arg4, 0);
 
+#if CONFIG_MACF
+       /* Check mach trap filter mask, if exists. */
+       task_t task = current_task();
+       uint8_t *filter_mask = task->mach_trap_filter_mask;
+
+       if (__improbable(filter_mask != NULL &&
+           !bitstr_test(filter_mask, call_number))) {
+               /* Not in filter mask, evaluate policy. */
+               if (mac_task_mach_trap_evaluate != NULL) {
+                       retval = mac_task_mach_trap_evaluate(get_bsdtask_info(task),
+                           call_number);
+                       if (retval) {
+                               goto skip_machcall;
+                       }
+               }
+       }
+#endif /* CONFIG_MACF */
+
        retval = mach_call(&args);
 
+#if CONFIG_MACF
+skip_machcall:
+#endif
+
        DEBUG_KPRINT_SYSCALL_MACH("mach_call_munger: retval=0x%x\n", retval);
 
        KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
@@ -542,7 +615,17 @@ mach_call_munger64(x86_saved_state_t *state)
        int call_number;
        int argc;
        mach_call_t mach_call;
-       struct mach_call_args args = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+       struct mach_call_args args = {
+               .arg1 = 0,
+               .arg2 = 0,
+               .arg3 = 0,
+               .arg4 = 0,
+               .arg5 = 0,
+               .arg6 = 0,
+               .arg7 = 0,
+               .arg8 = 0,
+               .arg9 = 0
+       };
        x86_saved_state64_t     *regs;
 
        struct uthread *ut = get_bsdthread_info(current_thread());
@@ -574,8 +657,7 @@ mach_call_munger64(x86_saved_state_t *state)
        argc = mach_trap_table[call_number].mach_trap_arg_count;
        if (argc) {
                int args_in_regs = MIN(6, argc);
-
-               memcpy(&args.arg1, &regs->rdi, args_in_regs * sizeof(syscall_arg_t));
+               __nochk_memcpy(&args.arg1, &regs->rdi, args_in_regs * sizeof(syscall_arg_t));
 
                if (argc > 6) {
                        int copyin_count;
@@ -596,8 +678,30 @@ mach_call_munger64(x86_saved_state_t *state)
        mach_kauth_cred_uthread_update();
 #endif
 
+#if CONFIG_MACF
+       /* Check syscall filter mask, if exists. */
+       task_t task = current_task();
+       uint8_t *filter_mask = task->mach_trap_filter_mask;
+
+       if (__improbable(filter_mask != NULL &&
+           !bitstr_test(filter_mask, call_number))) {
+               /* Not in filter mask, evaluate policy. */
+               if (mac_task_mach_trap_evaluate != NULL) {
+                       regs->rax = mac_task_mach_trap_evaluate(get_bsdtask_info(task),
+                           call_number);
+                       if (regs->rax) {
+                               goto skip_machcall;
+                       }
+               }
+       }
+#endif /* CONFIG_MACF */
+
        regs->rax = (uint64_t)mach_call((void *)&args);
 
+#if CONFIG_MACF
+skip_machcall:
+#endif
+
        DEBUG_KPRINT_SYSCALL_MACH( "mach_call_munger64: retval=0x%llx\n", regs->rax);
 
        KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
@@ -656,7 +760,7 @@ thread_setuserstack(
  * Returns the adjusted user stack pointer from the machine
  * dependent thread state info.  Used for small (<2G) deltas.
  */
-uint64_t
+user_addr_t
 thread_adjuserstack(
        thread_t        thread,
        int             adjust)