#include <sys/sysproto.h>
#include <sys/kauth.h>
#include <sys/systm.h>
+#include <sys/bitstring.h>
#include <security/audit/audit.h>
#include <machine/pal_routines.h>
+#if CONFIG_MACF
+#include <security/mac_framework.h>
+#endif
+
#if CONFIG_DTRACE
extern int32_t dtrace_systrace_syscall(struct proc *, void *, int *);
extern void dtrace_systrace_syscall_return(unsigned short, int, int *);
{
thread_t thread;
void *vt;
- unsigned int code;
+ unsigned int code, syscode;
struct sysent *callp;
int error;
p = (struct proc *)get_bsdtask_info(current_task());
}
- code = regs->eax & I386_SYSCALL_NUMBER_MASK;
+ code = regs->eax & I386_SYSCALL_NUMBER_MASK;
+ syscode = (code < nsysent) ? code : SYS_invalid;
DEBUG_KPRINT_SYSCALL_UNIX("unix_syscall: code=%d(%s) eip=%u\n",
- code, syscallnames[code >= nsysent ? SYS_invalid : code], (uint32_t)regs->eip);
+ code, syscallnames[syscode], (uint32_t)regs->eip);
params = (vm_offset_t) (regs->uesp + sizeof(int));
regs->efl &= ~(EFL_CF);
- callp = (code >= nsysent) ? &sysent[SYS_invalid] : &sysent[code];
+ callp = &sysent[syscode];
if (__improbable(callp == sysent)) {
code = fuword(params);
params += sizeof(int);
- callp = (code >= nsysent) ? &sysent[SYS_invalid] : &sysent[code];
+ syscode = (code < nsysent) ? code : SYS_invalid;
+ callp = &sysent[syscode];
}
vt = (void *)uthread->uu_arg;
}
if (__probable(!code_is_kdebug_trace(code))) {
- int *ip = (int *)vt;
-
- KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
- BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
- *ip, *(ip + 1), *(ip + 2), *(ip + 3), 0);
+ uint32_t *uip = vt;
+ KDBG_RELEASE(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
+ uip[0], uip[1], uip[2], uip[3]);
}
#if CONFIG_REQUIRES_U32_MUNGING
}
#endif
} else {
- KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
- BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
- 0, 0, 0, 0, 0);
+ KDBG_RELEASE(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START);
}
/*
uthread->uu_vpindex = 0;
#endif
+#if CONFIG_MACF
+ if (__improbable(p->syscall_filter_mask != NULL && !bitstr_test(p->syscall_filter_mask, syscode))) {
+ error = mac_proc_check_syscall_unix(p, syscode);
+ if (error) {
+ goto skip_syscall;
+ }
+ }
+#endif /* CONFIG_MACF */
+
AUDIT_SYSCALL_ENTER(code, p, uthread);
error = (*(callp->sy_call))((void *) p, (void *) vt, &(uthread->uu_rval[0]));
AUDIT_SYSCALL_EXIT(code, p, uthread, error);
+#if CONFIG_MACF
+skip_syscall:
+#endif /* CONFIG_MACF */
+
#ifdef JOE_DEBUG
if (uthread->uu_iocount) {
printf("system call returned with uu_iocount != 0\n");
throttle_lowpri_io(1);
}
if (__probable(!code_is_kdebug_trace(code))) {
- KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
- BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
- error, uthread->uu_rval[0], uthread->uu_rval[1], pid, 0);
+ KDBG_RELEASE(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
+ error, uthread->uu_rval[0], uthread->uu_rval[1], pid);
}
if (__improbable(!is_vfork && callp->sy_call == (sy_call_t *)execve && !error)) {
{
thread_t thread;
void *vt;
- unsigned int code;
+ unsigned int code, syscode;
struct sysent *callp;
int args_in_regs;
boolean_t args_start_at_rdi;
/* NOTREACHED */
}
- code = regs->rax & SYSCALL_NUMBER_MASK;
+ code = regs->rax & SYSCALL_NUMBER_MASK;
+ syscode = (code < nsysent) ? code : SYS_invalid;
DEBUG_KPRINT_SYSCALL_UNIX(
"unix_syscall64: code=%d(%s) rip=%llx\n",
- code, syscallnames[code >= nsysent ? SYS_invalid : code], regs->isf.rip);
- callp = (code >= nsysent) ? &sysent[SYS_invalid] : &sysent[code];
+ code, syscallnames[syscode], regs->isf.rip);
+ callp = &sysent[syscode];
vt = (void *)uthread->uu_arg;
* indirect system call... system call number
* passed as 'arg0'
*/
- code = regs->rdi;
- callp = (code >= nsysent) ? &sysent[SYS_invalid] : &sysent[code];
+ code = regs->rdi;
+ syscode = (code < nsysent) ? code : SYS_invalid;
+ callp = &sysent[syscode];
args_start_at_rdi = FALSE;
args_in_regs = 5;
} else {
args_in_regs = MIN(args_in_regs, callp->sy_narg);
memcpy(vt, args_start_at_rdi ? ®s->rdi : ®s->rsi, args_in_regs * sizeof(syscall_arg_t));
-
if (!code_is_kdebug_trace(code)) {
- uint64_t *ip = (uint64_t *)vt;
+ uint64_t *uip = vt;
- KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
- BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
- (int)(*ip), (int)(*(ip + 1)), (int)(*(ip + 2)), (int)(*(ip + 3)), 0);
+ KDBG_RELEASE(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
+ uip[0], uip[1], uip[2], uip[3]);
}
if (__improbable(callp->sy_narg > args_in_regs)) {
}
}
} else {
- KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
- BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
- 0, 0, 0, 0, 0);
+ KDBG_RELEASE(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START);
}
/*
uthread->uu_vpindex = 0;
#endif
+#if CONFIG_MACF
+ if (__improbable(p->syscall_filter_mask != NULL && !bitstr_test(p->syscall_filter_mask, syscode))) {
+ error = mac_proc_check_syscall_unix(p, syscode);
+ if (error) {
+ goto skip_syscall;
+ }
+ }
+#endif /* CONFIG_MACF */
+
AUDIT_SYSCALL_ENTER(code, p, uthread);
error = (*(callp->sy_call))((void *) p, vt, &(uthread->uu_rval[0]));
AUDIT_SYSCALL_EXIT(code, p, uthread, error);
+#if CONFIG_MACF
+skip_syscall:
+#endif /* CONFIG_MACF */
+
#ifdef JOE_DEBUG
if (uthread->uu_iocount) {
printf("system call returned with uu_iocount != 0\n");
throttle_lowpri_io(1);
}
if (__probable(!code_is_kdebug_trace(code))) {
- KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
- BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
- error, uthread->uu_rval[0], uthread->uu_rval[1], pid, 0);
+ KDBG_RELEASE(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
+ error, uthread->uu_rval[0], uthread->uu_rval[1], pid);
}
#if PROC_REF_DEBUG
throttle_lowpri_io(1);
}
if (!code_is_kdebug_trace(code)) {
- KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
- BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
- error, uthread->uu_rval[0], uthread->uu_rval[1], p->p_pid, 0);
+ KDBG_RELEASE(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
+ error, uthread->uu_rval[0], uthread->uu_rval[1], p->p_pid);
}
thread_exception_return();