]> git.saurik.com Git - apple/xnu.git/blobdiff - libsyscall/wrappers/terminate_with_reason.c
xnu-7195.81.3.tar.gz
[apple/xnu.git] / libsyscall / wrappers / terminate_with_reason.c
index 05fdb78482b59887d9236fa9fc53671fefb0c994..9b46ed9403abdb0c8528477b2f380e6aa377e212 100644 (file)
 #include <sys/types.h>
 #include <stdint.h>
 #include <signal.h>
+#include <os/reason_private.h>
 #include <unistd.h>
 
+/* Crash simulation */
+
+extern int pthread_current_stack_contains_np(const void *, unsigned long);
+int
+__darwin_check_fd_set_overflow(int n, const void *fd_set, int unlimited_select)
+{
+       if (n < 0) {
+               os_fault_with_payload(OS_REASON_LIBSYSTEM, OS_REASON_LIBSYSTEM_CODE_FAULT,
+                   &n, sizeof(n), "FD_SET underflow", 0);
+               return 0;
+       }
+
+       if (n >= __DARWIN_FD_SETSIZE) {
+               if (pthread_current_stack_contains_np((const void *) fd_set, sizeof(struct fd_set))) {
+                       if (!unlimited_select) {
+                               os_fault_with_payload(OS_REASON_LIBSYSTEM, OS_REASON_LIBSYSTEM_CODE_FAULT,
+                                   &n, sizeof(n), "FD_SET overflow", 0);
+                               return 0;
+                       } else {
+                               return 1;
+                       }
+               } else {
+                       return 1;
+               }
+       }
+
+       return 1;
+}
+
 /* System call entry points */
 int __terminate_with_payload(int pid, uint32_t reason_namespace, uint64_t reason_code,
-                               void *payload, uint32_t payload_size, const char *reason_string,
-                               uint64_t reason_flags);
+    void *payload, uint32_t payload_size, const char *reason_string,
+    uint64_t reason_flags);
 
 void __abort_with_payload(uint32_t reason_namespace, uint64_t reason_code,
-                               void *payload, uint32_t payload_size, const char *reason_string,
-                               uint64_t reason_flags);
+    void *payload, uint32_t payload_size, const char *reason_string,
+    uint64_t reason_flags);
 
 static void abort_with_payload_wrapper_internal(uint32_t reason_namespace, uint64_t reason_code,
-                               void *payload, uint32_t payload_size, const char *reason_string,
-                               uint64_t reason_flags) __attribute__((noreturn));
+    void *payload, uint32_t payload_size, const char *reason_string,
+    uint64_t reason_flags) __attribute__((noreturn, cold));
 
 /* System call wrappers */
 int
 terminate_with_reason(int pid, uint32_t reason_namespace, uint64_t reason_code,
-                       const char *reason_string, uint64_t reason_flags)
+    const char *reason_string, uint64_t reason_flags)
 {
        return __terminate_with_payload(pid, reason_namespace, reason_code, 0, 0,
-                                       reason_string, reason_flags);
+                  reason_string, reason_flags);
 }
 
 int
 terminate_with_payload(int pid, uint32_t reason_namespace, uint64_t reason_code,
-                       void *payload, uint32_t payload_size,
-                        const char *reason_string, uint64_t reason_flags)
+    void *payload, uint32_t payload_size,
+    const char *reason_string, uint64_t reason_flags)
 {
        return __terminate_with_payload(pid, reason_namespace, reason_code, payload,
-                                       payload_size, reason_string, reason_flags);
+                  payload_size, reason_string, reason_flags);
 }
 
-static void abort_with_payload_wrapper_internal(uint32_t reason_namespace, uint64_t reason_code,
-                               void *payload, uint32_t payload_size, const char *reason_string,
-                               uint64_t reason_flags)
+static void
+abort_with_payload_wrapper_internal(uint32_t reason_namespace, uint64_t reason_code,
+    void *payload, uint32_t payload_size, const char *reason_string,
+    uint64_t reason_flags)
 {
        sigset_t unmask_signal;
 
@@ -69,34 +100,27 @@ static void abort_with_payload_wrapper_internal(uint32_t reason_namespace, uint6
        sigprocmask(SIG_UNBLOCK, &unmask_signal, NULL);
 
        __abort_with_payload(reason_namespace, reason_code, payload, payload_size,
-                       reason_string, reason_flags);
+           reason_string, reason_flags);
 
-       /* If sending a SIGABRT failed, we try to fall back to SIGKILL */
+       /* If sending a SIGABRT failed, we fall back to SIGKILL */
        terminate_with_payload(getpid(), reason_namespace, reason_code, payload, payload_size,
-                       reason_string, reason_flags);
-
-       /* Last resort, let's use SIGTRAP (SIGILL on i386) */
-       sigemptyset(&unmask_signal);
-       sigaddset(&unmask_signal, SIGTRAP);
-       sigaddset(&unmask_signal, SIGILL);
-       sigprocmask(SIG_UNBLOCK, &unmask_signal, NULL);
+           reason_string, reason_flags | OS_REASON_FLAG_ABORT);
 
-       __builtin_trap();
+       __builtin_unreachable();
 }
 
 void
 abort_with_reason(uint32_t reason_namespace, uint64_t reason_code, const char *reason_string,
-                       uint64_t reason_flags)
+    uint64_t reason_flags)
 {
        abort_with_payload_wrapper_internal(reason_namespace, reason_code, 0, 0, reason_string, reason_flags);
 }
 
 void
 abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, void *payload,
-                       uint32_t payload_size, const char *reason_string,
-                        uint64_t reason_flags)
+    uint32_t payload_size, const char *reason_string,
+    uint64_t reason_flags)
 {
        abort_with_payload_wrapper_internal(reason_namespace, reason_code, payload, payload_size,
-                       reason_string, reason_flags);
+           reason_string, reason_flags);
 }
-