1*19c3b8c2SApple OSS Distributions#include <Foundation/Foundation.h> 2*19c3b8c2SApple OSS Distributions#include <darwintest.h> 3*19c3b8c2SApple OSS Distributions#include <darwintest_utils.h> 4*19c3b8c2SApple OSS Distributions#include <mach-o/dyld.h> 5*19c3b8c2SApple OSS Distributions#include <System/sys/codesign.h> 6*19c3b8c2SApple OSS Distributions#include <unistd.h> 7*19c3b8c2SApple OSS Distributions#include <stdlib.h> 8*19c3b8c2SApple OSS Distributions#include <signal.h> 9*19c3b8c2SApple OSS Distributions#include <sys/types.h> 10*19c3b8c2SApple OSS Distributions#include <sys/sysctl.h> 11*19c3b8c2SApple OSS Distributions 12*19c3b8c2SApple OSS Distributions 13*19c3b8c2SApple OSS DistributionsT_GLOBAL_META(T_META_RUN_CONCURRENTLY(true), 14*19c3b8c2SApple OSS Distributions T_META_ASROOT(true)); 15*19c3b8c2SApple OSS Distributions 16*19c3b8c2SApple OSS Distributionsstruct procargs { 17*19c3b8c2SApple OSS Distributions int argc; 18*19c3b8c2SApple OSS Distributions size_t preflightSize; 19*19c3b8c2SApple OSS Distributions NSString *executablePath; 20*19c3b8c2SApple OSS Distributions NSArray *components; 21*19c3b8c2SApple OSS Distributions NSString *legacyExecutablePath; 22*19c3b8c2SApple OSS Distributions void *rawBuffer; 23*19c3b8c2SApple OSS Distributions size_t rawBufferSize; 24*19c3b8c2SApple OSS Distributions}; 25*19c3b8c2SApple OSS Distributions 26*19c3b8c2SApple OSS Distributionsstatic void printHexDump(void* buffer, size_t size); 27*19c3b8c2SApple OSS Distributions 28*19c3b8c2SApple OSS Distributionstypedef struct procargs *procargs_t; 29*19c3b8c2SApple OSS Distributions 30*19c3b8c2SApple OSS Distributions#define TEST_ENVIRONMENT_VARIABLE "TESTENVVARIABLE" 31*19c3b8c2SApple OSS Distributions#define TEST_ENVIRONMENT_VARIABLE_VALUE "TESTENVVARIABLE_VALUE" 32*19c3b8c2SApple OSS Distributions 33*19c3b8c2SApple OSS Distributions 34*19c3b8c2SApple OSS Distributionsstatic size_t argmax; 35*19c3b8c2SApple OSS Distributions 36*19c3b8c2SApple OSS Distributionsstatic procargs_t getProcArgs(int type, pid_t pid, size_t allocSize) 37*19c3b8c2SApple OSS Distributions{ 38*19c3b8c2SApple OSS Distributions int sysctlArgs[3] = {CTL_KERN, type, pid}; 39*19c3b8c2SApple OSS Distributions int argc; 40*19c3b8c2SApple OSS Distributions NSMutableArray *components = [NSMutableArray array]; 41*19c3b8c2SApple OSS Distributions procargs_t args = (procargs_t) malloc(sizeof(struct procargs)); 42*19c3b8c2SApple OSS Distributions size_t currentLen = 0; 43*19c3b8c2SApple OSS Distributions bool legacyPathPresent = false; 44*19c3b8c2SApple OSS Distributions NSString *current = nil; 45*19c3b8c2SApple OSS Distributions NSString *legacyExecutablePath = nil; 46*19c3b8c2SApple OSS Distributions NSString *executablePath = nil; 47*19c3b8c2SApple OSS Distributions size_t bufferSize; 48*19c3b8c2SApple OSS Distributions size_t preflightSize = 0; 49*19c3b8c2SApple OSS Distributions const char *name = type == KERN_PROCARGS ? "KERN_PROCARGS" : "KERN_PROCARGS2"; 50*19c3b8c2SApple OSS Distributions const char *cursor; 51*19c3b8c2SApple OSS Distributions void *buffer; 52*19c3b8c2SApple OSS Distributions 53*19c3b8c2SApple OSS Distributions T_LOG("Get proc args for pid %d, allocSize %lu with %s", pid, allocSize, name); 54*19c3b8c2SApple OSS Distributions 55*19c3b8c2SApple OSS Distributions 56*19c3b8c2SApple OSS Distributions T_ASSERT_TRUE(type == KERN_PROCARGS || type == KERN_PROCARGS2, "type is valid"); 57*19c3b8c2SApple OSS Distributions 58*19c3b8c2SApple OSS Distributions /* Determine how much memory to allocate. If allocSize is 0 we will use the size 59*19c3b8c2SApple OSS Distributions * we get from the sysctl for our buffer. */ 60*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctl(sysctlArgs, 3, NULL, &preflightSize, NULL, 0), "sysctl %s", name); 61*19c3b8c2SApple OSS Distributions T_LOG("procargs data should be %lu bytes", preflightSize); 62*19c3b8c2SApple OSS Distributions 63*19c3b8c2SApple OSS Distributions if (allocSize == 0) { 64*19c3b8c2SApple OSS Distributions allocSize = preflightSize; 65*19c3b8c2SApple OSS Distributions } 66*19c3b8c2SApple OSS Distributions 67*19c3b8c2SApple OSS Distributions buffer = malloc(allocSize); 68*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(buffer, "malloc buffer of size %lu", allocSize); 69*19c3b8c2SApple OSS Distributions bufferSize = allocSize; 70*19c3b8c2SApple OSS Distributions 71*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctl(sysctlArgs, 3, buffer, &bufferSize, NULL, 0), "sysctl %s", name); 72*19c3b8c2SApple OSS Distributions T_ASSERT_LE(bufferSize, allocSize, "returned buffer size should be less than allocated size"); 73*19c3b8c2SApple OSS Distributions T_LOG("sysctl wrote %lu bytes", bufferSize); 74*19c3b8c2SApple OSS Distributions if (allocSize >= bufferSize) { 75*19c3b8c2SApple OSS Distributions /* Allocated buffer is larger than what kernel wrote, so it should match preflightSize */ 76*19c3b8c2SApple OSS Distributions T_ASSERT_EQ(bufferSize, preflightSize, "buffer size should be the same as preflight size"); 77*19c3b8c2SApple OSS Distributions } 78*19c3b8c2SApple OSS Distributions 79*19c3b8c2SApple OSS Distributions printHexDump(buffer, bufferSize); 80*19c3b8c2SApple OSS Distributions 81*19c3b8c2SApple OSS Distributions if (type == KERN_PROCARGS2) { 82*19c3b8c2SApple OSS Distributions argc = *(int *)buffer; 83*19c3b8c2SApple OSS Distributions cursor = (const char *)buffer + sizeof(int); 84*19c3b8c2SApple OSS Distributions } else { 85*19c3b8c2SApple OSS Distributions /* Without KERN_PROCARGS2, we can't tell where argv ends and environ begins. 86*19c3b8c2SApple OSS Distributions * Set argc to -1 to indicate this */ 87*19c3b8c2SApple OSS Distributions argc = -1; 88*19c3b8c2SApple OSS Distributions cursor = buffer; 89*19c3b8c2SApple OSS Distributions } 90*19c3b8c2SApple OSS Distributions 91*19c3b8c2SApple OSS Distributions while ((uintptr_t)cursor < (uintptr_t)buffer + bufferSize) { 92*19c3b8c2SApple OSS Distributions /* Ensure alignment and check if the uint16_t at cursor is the magic value */ 93*19c3b8c2SApple OSS Distributions if (!((uintptr_t)cursor & (sizeof(uint16_t) - 1)) && 94*19c3b8c2SApple OSS Distributions (uintptr_t)buffer + bufferSize - (uintptr_t)cursor > sizeof(uint16_t)) { 95*19c3b8c2SApple OSS Distributions /* Silence -Wcast-align by casting to const void * */ 96*19c3b8c2SApple OSS Distributions uint16_t value = *(const uint16_t *)(const void *)cursor; 97*19c3b8c2SApple OSS Distributions if (value == 0xBFFF) { 98*19c3b8c2SApple OSS Distributions /* Magic value that specifies the end of the argument/environ section */ 99*19c3b8c2SApple OSS Distributions cursor += sizeof(uint16_t) + sizeof(uint32_t); 100*19c3b8c2SApple OSS Distributions legacyPathPresent = true; 101*19c3b8c2SApple OSS Distributions break; 102*19c3b8c2SApple OSS Distributions } 103*19c3b8c2SApple OSS Distributions } 104*19c3b8c2SApple OSS Distributions currentLen = strnlen(cursor, bufferSize - ((uintptr_t)cursor - (uintptr_t)buffer)); 105*19c3b8c2SApple OSS Distributions current = [[NSString alloc] initWithBytes:cursor length:currentLen encoding:NSUTF8StringEncoding]; 106*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(current, "allocated string"); 107*19c3b8c2SApple OSS Distributions cursor += currentLen + 1; 108*19c3b8c2SApple OSS Distributions 109*19c3b8c2SApple OSS Distributions if (executablePath == nil) { 110*19c3b8c2SApple OSS Distributions executablePath = current; 111*19c3b8c2SApple OSS Distributions [executablePath retain]; 112*19c3b8c2SApple OSS Distributions while (*cursor == 0) { 113*19c3b8c2SApple OSS Distributions cursor++; 114*19c3b8c2SApple OSS Distributions } 115*19c3b8c2SApple OSS Distributions } else { 116*19c3b8c2SApple OSS Distributions [components addObject:current]; 117*19c3b8c2SApple OSS Distributions } 118*19c3b8c2SApple OSS Distributions [current release]; 119*19c3b8c2SApple OSS Distributions } 120*19c3b8c2SApple OSS Distributions if (legacyPathPresent) { 121*19c3b8c2SApple OSS Distributions T_ASSERT_EQ(type, KERN_PROCARGS, "Legacy executable path should only be present for KERN_PROCARGS"); 122*19c3b8c2SApple OSS Distributions currentLen = strnlen(cursor, bufferSize - ((uintptr_t)cursor - (uintptr_t)buffer)); 123*19c3b8c2SApple OSS Distributions current = [[NSString alloc] initWithBytes:cursor length:currentLen encoding:NSUTF8StringEncoding]; 124*19c3b8c2SApple OSS Distributions T_QUIET; T_ASSERT_NOTNULL(current, "allocated string"); 125*19c3b8c2SApple OSS Distributions legacyExecutablePath = current; 126*19c3b8c2SApple OSS Distributions } 127*19c3b8c2SApple OSS Distributions args->argc = argc; 128*19c3b8c2SApple OSS Distributions args->executablePath = executablePath; 129*19c3b8c2SApple OSS Distributions args->components = components; 130*19c3b8c2SApple OSS Distributions args->legacyExecutablePath = legacyExecutablePath; 131*19c3b8c2SApple OSS Distributions args->preflightSize = preflightSize; 132*19c3b8c2SApple OSS Distributions args->rawBuffer = buffer; 133*19c3b8c2SApple OSS Distributions args->rawBufferSize = bufferSize; 134*19c3b8c2SApple OSS Distributions return args; 135*19c3b8c2SApple OSS Distributions} 136*19c3b8c2SApple OSS Distributions 137*19c3b8c2SApple OSS Distributionsstatic void printProcArgs(procargs_t procargs) { 138*19c3b8c2SApple OSS Distributions if (procargs->argc == -1) { 139*19c3b8c2SApple OSS Distributions T_LOG("No argument count"); 140*19c3b8c2SApple OSS Distributions } else { 141*19c3b8c2SApple OSS Distributions T_LOG("Argc is %d", procargs->argc); 142*19c3b8c2SApple OSS Distributions } 143*19c3b8c2SApple OSS Distributions T_LOG("Executable path: %s (length %lu)", [procargs->executablePath UTF8String], [procargs->executablePath length]); 144*19c3b8c2SApple OSS Distributions for (size_t i = 0; i < [procargs->components count]; i++) { 145*19c3b8c2SApple OSS Distributions NSString *component = [procargs->components objectAtIndex:i]; 146*19c3b8c2SApple OSS Distributions const char *str = [component UTF8String]; 147*19c3b8c2SApple OSS Distributions size_t len = [component length]; 148*19c3b8c2SApple OSS Distributions if (procargs->argc != -1) { 149*19c3b8c2SApple OSS Distributions T_LOG("%s %zu: %s (length %lu)", i >= (size_t)procargs->argc ? "Env var" : "Argument", i, str, len); 150*19c3b8c2SApple OSS Distributions } else { 151*19c3b8c2SApple OSS Distributions T_LOG("Component %zu: %s (length %lu)", i, str, len); 152*19c3b8c2SApple OSS Distributions } 153*19c3b8c2SApple OSS Distributions } 154*19c3b8c2SApple OSS Distributions if (procargs->legacyExecutablePath) { 155*19c3b8c2SApple OSS Distributions T_LOG("Contains legacy executable path: %s (length %lu)", [procargs->legacyExecutablePath UTF8String], [procargs->legacyExecutablePath length]); 156*19c3b8c2SApple OSS Distributions } 157*19c3b8c2SApple OSS Distributions printHexDump(procargs->rawBuffer, procargs->rawBufferSize); 158*19c3b8c2SApple OSS Distributions} 159*19c3b8c2SApple OSS Distributions 160*19c3b8c2SApple OSS Distributionsstatic void printHexDump(void* buffer, size_t size) { 161*19c3b8c2SApple OSS Distributions #define ROW_LENGTH 24 162*19c3b8c2SApple OSS Distributions T_LOG("Buffer %p, size %zu", buffer, size); 163*19c3b8c2SApple OSS Distributions for (size_t row = 0; row < size; row += ROW_LENGTH) { 164*19c3b8c2SApple OSS Distributions NSMutableString *line = [[NSMutableString alloc] initWithCapacity:0]; 165*19c3b8c2SApple OSS Distributions NSMutableString *text = [[NSMutableString alloc] initWithCapacity:0]; 166*19c3b8c2SApple OSS Distributions [line appendFormat:@" %04zx ", row]; 167*19c3b8c2SApple OSS Distributions for (size_t col = row; col < row + ROW_LENGTH; col++) { 168*19c3b8c2SApple OSS Distributions if (col < size) { 169*19c3b8c2SApple OSS Distributions char c = ((char *)buffer)[col]; 170*19c3b8c2SApple OSS Distributions [line appendFormat:@"%02x ", c]; 171*19c3b8c2SApple OSS Distributions if (isprint(c)) { 172*19c3b8c2SApple OSS Distributions [text appendFormat:@"%c", c]; 173*19c3b8c2SApple OSS Distributions } else { 174*19c3b8c2SApple OSS Distributions [text appendString:@"."]; 175*19c3b8c2SApple OSS Distributions } 176*19c3b8c2SApple OSS Distributions } else { 177*19c3b8c2SApple OSS Distributions [line appendString:@" "]; 178*19c3b8c2SApple OSS Distributions } 179*19c3b8c2SApple OSS Distributions } 180*19c3b8c2SApple OSS Distributions [line appendFormat:@" %@", text]; 181*19c3b8c2SApple OSS Distributions T_LOG("%s", [line UTF8String]); 182*19c3b8c2SApple OSS Distributions [text release]; 183*19c3b8c2SApple OSS Distributions [line release]; 184*19c3b8c2SApple OSS Distributions } 185*19c3b8c2SApple OSS Distributions} 186*19c3b8c2SApple OSS Distributions 187*19c3b8c2SApple OSS Distributionsstatic void deallocProcArgs(procargs_t procargs) 188*19c3b8c2SApple OSS Distributions{ 189*19c3b8c2SApple OSS Distributions [procargs->components release]; 190*19c3b8c2SApple OSS Distributions [procargs->executablePath release]; 191*19c3b8c2SApple OSS Distributions [procargs->legacyExecutablePath release]; 192*19c3b8c2SApple OSS Distributions free(procargs->rawBuffer); 193*19c3b8c2SApple OSS Distributions free(procargs); 194*19c3b8c2SApple OSS Distributions} 195*19c3b8c2SApple OSS Distributions 196*19c3b8c2SApple OSS DistributionsT_HELPER_DECL(child_helper, "Child process helper") 197*19c3b8c2SApple OSS Distributions{ 198*19c3b8c2SApple OSS Distributions while (true) { 199*19c3b8c2SApple OSS Distributions wait(NULL); 200*19c3b8c2SApple OSS Distributions } 201*19c3b8c2SApple OSS Distributions} 202*19c3b8c2SApple OSS Distributions 203*19c3b8c2SApple OSS Distributionsstatic pid_t 204*19c3b8c2SApple OSS Distributionslaunch_child_process(NSArray *args, bool cs_restrict) 205*19c3b8c2SApple OSS Distributions{ 206*19c3b8c2SApple OSS Distributions pid_t pid; 207*19c3b8c2SApple OSS Distributions char path[PATH_MAX]; 208*19c3b8c2SApple OSS Distributions uint32_t path_size = sizeof(path); 209*19c3b8c2SApple OSS Distributions uint32_t csopsStatus = 0; 210*19c3b8c2SApple OSS Distributions const char** dt_args; 211*19c3b8c2SApple OSS Distributions size_t dt_args_count; 212*19c3b8c2SApple OSS Distributions 213*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(_NSGetExecutablePath(path, &path_size), "get executable path"); 214*19c3b8c2SApple OSS Distributions 215*19c3b8c2SApple OSS Distributions /* We need to add 4 arguments to the beginning and NULL at the end */ 216*19c3b8c2SApple OSS Distributions dt_args_count = [args count] + 5; 217*19c3b8c2SApple OSS Distributions dt_args = malloc(sizeof(char *) * dt_args_count); 218*19c3b8c2SApple OSS Distributions dt_args[0] = path; 219*19c3b8c2SApple OSS Distributions dt_args[1] = "-n"; 220*19c3b8c2SApple OSS Distributions dt_args[2] = "child_helper"; 221*19c3b8c2SApple OSS Distributions dt_args[3] = "--"; 222*19c3b8c2SApple OSS Distributions for (size_t i = 0; i < [args count]; i++) { 223*19c3b8c2SApple OSS Distributions NSString *arg = [args objectAtIndex:i]; 224*19c3b8c2SApple OSS Distributions dt_args[i + 4] = [arg UTF8String]; 225*19c3b8c2SApple OSS Distributions } 226*19c3b8c2SApple OSS Distributions dt_args[[args count] + 4] = NULL; 227*19c3b8c2SApple OSS Distributions 228*19c3b8c2SApple OSS Distributions T_LOG("Launching %s", path); 229*19c3b8c2SApple OSS Distributions T_LOG("Arguments: "); 230*19c3b8c2SApple OSS Distributions for (size_t i = 0; i < dt_args_count; i++) { 231*19c3b8c2SApple OSS Distributions T_LOG(" %s", dt_args[i] ? dt_args[i] : "(null)"); 232*19c3b8c2SApple OSS Distributions } 233*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(dt_launch_tool(&pid, (char **)dt_args, false, NULL, NULL), "launched helper"); 234*19c3b8c2SApple OSS Distributions free(dt_args); 235*19c3b8c2SApple OSS Distributions 236*19c3b8c2SApple OSS Distributions if (cs_restrict) { 237*19c3b8c2SApple OSS Distributions csopsStatus |= CS_RESTRICT; 238*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(csops(pid, CS_OPS_SET_STATUS, &csopsStatus, sizeof(csopsStatus)), "set CS_RESTRICT"); 239*19c3b8c2SApple OSS Distributions } 240*19c3b8c2SApple OSS Distributions return pid; 241*19c3b8c2SApple OSS Distributions} 242*19c3b8c2SApple OSS Distributions 243*19c3b8c2SApple OSS DistributionsT_DECL(test_sysctl_kern_procargs_25397314, "Test kern.procargs and kern.procargs2 sysctls") 244*19c3b8c2SApple OSS Distributions{ 245*19c3b8c2SApple OSS Distributions procargs_t procargs; 246*19c3b8c2SApple OSS Distributions size_t argsize = sizeof(argmax); 247*19c3b8c2SApple OSS Distributions NSString *testArgument1 = @"test argument 1"; 248*19c3b8c2SApple OSS Distributions bool containsTestArgument1 = false; 249*19c3b8c2SApple OSS Distributions NSString *testArgument2 = @"test argument 2"; 250*19c3b8c2SApple OSS Distributions bool containsTestArgument2 = false; 251*19c3b8c2SApple OSS Distributions NSString *testEnvironmentVariable = @TEST_ENVIRONMENT_VARIABLE; 252*19c3b8c2SApple OSS Distributions bool containsTestEnvironmentVariable = false; 253*19c3b8c2SApple OSS Distributions bool containsPathEnvironmentVariable = false; 254*19c3b8c2SApple OSS Distributions int development = 0; 255*19c3b8c2SApple OSS Distributions size_t development_size = sizeof(development); 256*19c3b8c2SApple OSS Distributions uint32_t csopsStatus = 0; 257*19c3b8c2SApple OSS Distributions 258*19c3b8c2SApple OSS Distributions 259*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctlbyname("kern.development", &development, &development_size, NULL, 0), "sysctl kern.development"); 260*19c3b8c2SApple OSS Distributions 261*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(sysctlbyname("kern.argmax", &argmax, &argsize, NULL, 0), "sysctl kern.argmax"); 262*19c3b8c2SApple OSS Distributions procargs = getProcArgs(KERN_PROCARGS2, getpid(), argmax); 263*19c3b8c2SApple OSS Distributions T_ASSERT_NOTNULL(procargs->executablePath, "executable path should be non-null"); 264*19c3b8c2SApple OSS Distributions T_ASSERT_GT([procargs->executablePath length], 0, "executable path should not be empty"); 265*19c3b8c2SApple OSS Distributions printProcArgs(procargs); 266*19c3b8c2SApple OSS Distributions deallocProcArgs(procargs); 267*19c3b8c2SApple OSS Distributions 268*19c3b8c2SApple OSS Distributions procargs = getProcArgs(KERN_PROCARGS2, getpid(), 0); 269*19c3b8c2SApple OSS Distributions T_ASSERT_NOTNULL(procargs->executablePath, "executable path should be non-null"); 270*19c3b8c2SApple OSS Distributions T_ASSERT_GT([procargs->executablePath length], 0, "executable path should not be empty"); 271*19c3b8c2SApple OSS Distributions printProcArgs(procargs); 272*19c3b8c2SApple OSS Distributions deallocProcArgs(procargs); 273*19c3b8c2SApple OSS Distributions 274*19c3b8c2SApple OSS Distributions setenv(TEST_ENVIRONMENT_VARIABLE, TEST_ENVIRONMENT_VARIABLE_VALUE, true); 275*19c3b8c2SApple OSS Distributions 276*19c3b8c2SApple OSS Distributions pid_t child = launch_child_process(@[testArgument1, testArgument2], false); 277*19c3b8c2SApple OSS Distributions procargs = getProcArgs(KERN_PROCARGS2, child, argmax); 278*19c3b8c2SApple OSS Distributions T_ASSERT_NOTNULL(procargs->executablePath, "executable path should be non-null"); 279*19c3b8c2SApple OSS Distributions T_ASSERT_GT([procargs->executablePath length], 0, "executable path should not be empty"); 280*19c3b8c2SApple OSS Distributions printProcArgs(procargs); 281*19c3b8c2SApple OSS Distributions 282*19c3b8c2SApple OSS Distributions for (NSString *component in procargs->components) { 283*19c3b8c2SApple OSS Distributions if ([component isEqualToString:testArgument1]) { 284*19c3b8c2SApple OSS Distributions containsTestArgument1 = true; 285*19c3b8c2SApple OSS Distributions } 286*19c3b8c2SApple OSS Distributions if ([component isEqualToString:testArgument2]) { 287*19c3b8c2SApple OSS Distributions containsTestArgument2 = true; 288*19c3b8c2SApple OSS Distributions } 289*19c3b8c2SApple OSS Distributions if ([component containsString:testEnvironmentVariable]) { 290*19c3b8c2SApple OSS Distributions containsTestEnvironmentVariable = true; 291*19c3b8c2SApple OSS Distributions } 292*19c3b8c2SApple OSS Distributions } 293*19c3b8c2SApple OSS Distributions deallocProcArgs(procargs); 294*19c3b8c2SApple OSS Distributions kill(child, SIGKILL); 295*19c3b8c2SApple OSS Distributions T_ASSERT_TRUE(containsTestArgument1, "Found test argument 1"); 296*19c3b8c2SApple OSS Distributions T_ASSERT_TRUE(containsTestArgument2, "Found test argument 2"); 297*19c3b8c2SApple OSS Distributions T_ASSERT_TRUE(containsTestEnvironmentVariable, "Found test environment variable"); 298*19c3b8c2SApple OSS Distributions 299*19c3b8c2SApple OSS Distributions if (development) { 300*19c3b8c2SApple OSS Distributions T_LOG("Skipping test on DEVELOPMENT || DEBUG kernel"); 301*19c3b8c2SApple OSS Distributions } else { 302*19c3b8c2SApple OSS Distributions containsTestArgument1 = false; 303*19c3b8c2SApple OSS Distributions containsTestArgument2 = false; 304*19c3b8c2SApple OSS Distributions containsTestEnvironmentVariable = false; 305*19c3b8c2SApple OSS Distributions 306*19c3b8c2SApple OSS Distributions child = launch_child_process(@[testArgument1, testArgument2], true); 307*19c3b8c2SApple OSS Distributions procargs = getProcArgs(KERN_PROCARGS2, child, argmax); 308*19c3b8c2SApple OSS Distributions T_ASSERT_NOTNULL(procargs->executablePath, "executable path should be non-null"); 309*19c3b8c2SApple OSS Distributions T_ASSERT_GT([procargs->executablePath length], 0, "executable path should not be empty"); 310*19c3b8c2SApple OSS Distributions printProcArgs(procargs); 311*19c3b8c2SApple OSS Distributions for (NSString *component in procargs->components) { 312*19c3b8c2SApple OSS Distributions if ([component isEqualToString:testArgument1]) { 313*19c3b8c2SApple OSS Distributions containsTestArgument1 = true; 314*19c3b8c2SApple OSS Distributions } 315*19c3b8c2SApple OSS Distributions if ([component isEqualToString:testArgument2]) { 316*19c3b8c2SApple OSS Distributions containsTestArgument2 = true; 317*19c3b8c2SApple OSS Distributions } 318*19c3b8c2SApple OSS Distributions if ([component containsString:testEnvironmentVariable]) { 319*19c3b8c2SApple OSS Distributions containsTestEnvironmentVariable = true; 320*19c3b8c2SApple OSS Distributions } 321*19c3b8c2SApple OSS Distributions } 322*19c3b8c2SApple OSS Distributions deallocProcArgs(procargs); 323*19c3b8c2SApple OSS Distributions kill(child, SIGKILL); 324*19c3b8c2SApple OSS Distributions T_ASSERT_TRUE(containsTestArgument1, "Found test argument 1"); 325*19c3b8c2SApple OSS Distributions T_ASSERT_TRUE(containsTestArgument2, "Found test argument 2"); 326*19c3b8c2SApple OSS Distributions T_ASSERT_FALSE(containsTestEnvironmentVariable, "No test environment variable"); 327*19c3b8c2SApple OSS Distributions 328*19c3b8c2SApple OSS Distributions 329*19c3b8c2SApple OSS Distributions csopsStatus |= CS_RESTRICT; 330*19c3b8c2SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(csops(getpid(), CS_OPS_SET_STATUS, &csopsStatus, sizeof(csopsStatus)), "set CS_RESTRICT on self"); 331*19c3b8c2SApple OSS Distributions procargs = getProcArgs(KERN_PROCARGS2, getpid(), argmax); 332*19c3b8c2SApple OSS Distributions T_ASSERT_NOTNULL(procargs->executablePath, "executable path should be non-null"); 333*19c3b8c2SApple OSS Distributions T_ASSERT_GT([procargs->executablePath length], 0, "executable path should not be empty"); 334*19c3b8c2SApple OSS Distributions printProcArgs(procargs); 335*19c3b8c2SApple OSS Distributions for (NSString *component in procargs->components) { 336*19c3b8c2SApple OSS Distributions if ([component containsString:@"PATH"]) { 337*19c3b8c2SApple OSS Distributions containsPathEnvironmentVariable = true; 338*19c3b8c2SApple OSS Distributions } 339*19c3b8c2SApple OSS Distributions } 340*19c3b8c2SApple OSS Distributions deallocProcArgs(procargs); 341*19c3b8c2SApple OSS Distributions T_ASSERT_TRUE(containsPathEnvironmentVariable, "Found $PATH environment variable"); 342*19c3b8c2SApple OSS Distributions } 343*19c3b8c2SApple OSS Distributions} 344