+/* **************************************************************************************************************
+ * Test KASLR-related functionality
+ * **************************************************************************************************************
+ */
+int kaslr_test( void * the_argp )
+{
+ int result = 0;
+ uint64_t slide = 0;
+ size_t size;
+ int slide_enabled;
+
+ size = sizeof(slide_enabled);
+ result = sysctlbyname("kern.slide", &slide_enabled, &size, NULL, 0);
+ if (result != 0) {
+ printf("sysctlbyname(\"kern.slide\") failed with errno %d\n", errno);
+ goto test_failed_exit;
+ }
+
+ /* Test positive case first */
+ size = sizeof(slide);
+ result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size);
+ if (result == 0) {
+ /* syscall supported, slide must be non-zero if running latest xnu and KASLR is enabled */
+ if (slide_enabled && (slide == 0)) {
+ printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported slide of 0x%016llx\n", slide);
+ goto test_failed_exit;
+ }
+ if (size != sizeof(slide)) {
+ printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported size of %lu\n", size);
+ goto test_failed_exit;
+ }
+ } else {
+ /* Only ENOTSUP is allowed. If so, assume all calls will be unsupported */
+ if (errno == ENOTSUP) {
+ return 0;
+ } else {
+ printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) returned unexpected errno (errno %d)\n", errno);
+ goto test_failed_exit;
+ }
+ }
+
+ /* Negative cases for expected failures */
+ size = sizeof(slide);
+ result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, &size);
+ if ((result == 0) || (errno != EFAULT)) {
+ printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno);
+ goto test_failed_exit;
+ }
+
+ size = sizeof(slide) + 1; /* EINVAL */
+ result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size);
+ if ((result == 0) || (errno != EINVAL)) {
+ printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size+1) returned unexpected success or errno (result %d errno %d)\n", result, errno);
+ goto test_failed_exit;
+ }
+
+ result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, NULL /* EFAULT */);
+ if ((result == 0) || (errno != EFAULT)) {
+ printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, NULL) returned unexpected success or errno (result %d errno %d)\n", result, errno);
+ goto test_failed_exit;
+ }
+
+ size = sizeof(slide);
+ result = kas_info(KAS_INFO_MAX_SELECTOR /* EINVAL */, &slide, &size);
+ if ((result == 0) || (errno != EINVAL)) {
+ printf("kas_info(KAS_INFO_MAX_SELECTOR, &slide, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno);
+ goto test_failed_exit;
+ }
+
+ return 0;
+
+test_failed_exit:
+ return -1;
+}