1 #include <stdio.h> 2 #include <mach/mach_vm.h> 3 #include <mach/mach_port.h> 4 #include <mach/mach_error.h> 5 #include <sys/sysctl.h> 6 #include <sys/wait.h> 7 #include <unistd.h> 8 9 #ifdef T_NAMESPACE 10 #undef T_NAMESPACE 11 #endif 12 13 #include <darwintest.h> 14 #include <darwintest_utils.h> 15 16 T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true), 17 T_META_NAMESPACE("xnu.ipc"), 18 T_META_RADAR_COMPONENT_NAME("xnu"), 19 T_META_RADAR_COMPONENT_VERSION("IPC"), 20 T_META_TAG_VM_PREFERRED); 21 22 T_DECL(test_task_filter_msg_flag, "Set the filter msg flag on the task and check if the forked child inherits it", 23 T_META_ASROOT(true), T_META_CHECK_LEAKS(false)) 24 { 25 int ret, dev; 26 size_t sysctl_size; 27 28 T_SETUPBEGIN; 29 30 dev = 0; 31 sysctl_size = sizeof(dev); 32 ret = sysctlbyname("kern.development", &dev, &sysctl_size, NULL, 0); 33 T_QUIET; T_ASSERT_POSIX_SUCCESS(ret, "sysctl kern.development failed"); 34 if (dev == 0) { 35 T_SKIP("Skipping test on release kernel"); 36 } 37 38 T_SETUPEND; 39 40 int cur_filter_flag = 0; 41 int new_filter_flag = 1; 42 ret = sysctlbyname("kern.task_set_filter_msg_flag", NULL, 0, &new_filter_flag, sizeof(new_filter_flag)); 43 T_ASSERT_POSIX_SUCCESS(ret, "sysctlbyname"); 44 ret = sysctlbyname("kern.task_set_filter_msg_flag", &cur_filter_flag, &sysctl_size, NULL, 0); 45 T_ASSERT_POSIX_SUCCESS(ret, "sysctlbyname"); 46 T_ASSERT_EQ(cur_filter_flag, 1, "Task should have filtering on"); 47 48 pid_t pid = fork(); 49 if (pid == 0) { 50 cur_filter_flag = 0; 51 ret = sysctlbyname("kern.task_set_filter_msg_flag", &cur_filter_flag, &sysctl_size, NULL, 0); 52 if (ret == 0) { 53 if (cur_filter_flag == 1) { 54 exit(0); 55 } 56 } 57 exit(1); 58 } 59 60 int status; 61 ret = waitpid(pid, &status, 0); 62 T_ASSERT_POSIX_SUCCESS(ret, "waitpid"); 63 64 if (WIFEXITED(status)) { 65 const int exit_code = WEXITSTATUS(status); 66 T_ASSERT_EQ(exit_code, 0, "Child inherited the filter msg flag"); 67 } 68 69 /* Turn off task msg filtering */ 70 cur_filter_flag = 1; 71 new_filter_flag = 0; 72 ret = sysctlbyname("kern.task_set_filter_msg_flag", &cur_filter_flag, &sysctl_size, &new_filter_flag, sizeof(new_filter_flag)); 73 T_ASSERT_POSIX_SUCCESS(ret, "sysctlbyname"); 74 T_ASSERT_EQ(cur_filter_flag, 1, "Task should have filtering on"); 75 76 T_END; 77 } 78