1/* 2 * tests.c 3 * xnu_quick_test 4 * 5 * Created by Jerry Cottingham on 3/25/05. 6 * Copyright 2008 Apple Inc. All rights reserved. 7 * 8 */ 9 10#include "tests.h" 11#include <sys/ipc.h> /* for message queue tests */ 12#include <sys/msg.h> /* for message queue tests */ 13#include <sys/syscall.h> /* for get / settid */ 14#include <sys/sysctl.h> /* for determining hw */ 15#include <sys/kas_info.h> /* for kas_info() */ 16#include <AvailabilityMacros.h> /* for determination of Mac OS X version (tiger, leopard, etc.) */ 17#include <libkern/OSByteOrder.h> /* for OSSwap32() */ 18#include <mach/mach.h> 19 20 21extern char g_target_path[ PATH_MAX ]; 22extern int g_skip_setuid_tests; 23extern int g_is_single_user; 24 25 26void print_acct_debug_strings( char * my_ac_comm ); 27 28 29#if TEST_SYSTEM_CALLS /* system calls to do */ 30 "reboot", /* 55 = reboot */ 31 "revoke", /* 56 = revoke */ 32 "sbrk", /* 69 = sbrk */ 33 "sstk", /* 70 = sstk */ 34 "mount", /* 167 = mount */ 35 "unmount", /* 159 = unmount */ 36 "undelete", /* 205 = undelete */ 37 "watchevent", /* 231 = watchevent */ 38 "waitevent", /* 232 = waitevent */ 39 "modwatch", /* 233 = modwatch */ 40 "fsctl", /* 242 = fsctl */ 41 "initgroups", /* 243 = initgroups */ 42 "semsys", /* 251 = semsys */ 43 "semconfig", /* 257 = semconfig */ 44 "msgsys", /* 252 = msgsys */ 45 "shmsys", /* 253 = shmsys */ 46 "load_shared_file", /* 296 = load_shared_file */ 47 "reset_shared_file", /* 297 = reset_shared_file */ 48 "new_system_shared_regions", /* 298 = new_system_shared_regions */ 49 "shared_region_map_file_np", /* 299 = shared_region_map_file_np */ 50 "shared_region_make_private_np", /* 300 = shared_region_make_private_np */ 51 "__pthread_kill", /* 328 = __pthread_kill */ 52 "pthread_sigmask", /* 329 = pthread_sigmask */ 53 "__disable_threadsignal", /* 331 = __disable_threadsignal */ 54 "__pthread_markcancel", /* 332 = __pthread_markcancel */ 55 "__pthread_canceled", /* 333 = __pthread_canceled */ 56 "__semwait_signal", /* 334 = __semwait_signal */ 57 "audit", /* 350 = audit */ 58 "auditon", /* 351 = auditon */ 59 "getaudit", /* 355 = getaudit */ 60 "setaudit", /* 356 = setaudit */ 61 "getaudit_addr", /* 357 = getaudit_addr */ 62 "setaudit_addr", /* 358 = setaudit_addr */ 63 "auditctl", /* 359 = auditctl */ 64#endif 65 66/* ************************************************************************************************************** 67 * Test the syscall system call. 68 * ************************************************************************************************************** 69 */ 70int syscall_test( void * the_argp ) 71{ 72 int my_err; 73 int my_fd = -1; 74 char * my_pathp; 75 kern_return_t my_kr; 76 77 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 78 if(my_kr != KERN_SUCCESS){ 79 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 80 goto test_failed_exit; 81 } 82 83 *my_pathp = 0x00; 84 strcpy( my_pathp, &g_target_path[0] ); 85 strcat( my_pathp, "/" ); 86 87 /* create a test file */ 88 my_err = create_random_name( my_pathp, 1 ); 89 if ( my_err != 0 ) { 90 goto test_failed_exit; 91 } 92 93 /* use an indirect system call to open our test file. 94 * I picked open since it uses a path pointer which grows to 64 bits in an LP64 environment. 95 */ 96 my_fd = syscall( SYS_open, my_pathp, (O_RDWR | O_EXCL), 0 ); 97 if ( my_fd == -1 ) { 98 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 99 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp ); 100 goto test_failed_exit; 101 } 102 103 my_err = 0; 104 goto test_passed_exit; 105 106test_failed_exit: 107 my_err = -1; 108 109test_passed_exit: 110 if ( my_fd != -1 ) 111 close( my_fd ); 112 if ( my_pathp != NULL ) { 113 remove( my_pathp ); 114 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 115 } 116 return( my_err ); 117} 118 119/* ************************************************************************************************************** 120 * Test fork wait4, and exit system calls. 121 * ************************************************************************************************************** 122 */ 123int fork_wait4_exit_test( void * the_argp ) 124{ 125 int my_err, my_status; 126 pid_t my_pid, my_wait_pid; 127 struct rusage my_usage; 128 129 /* spin off another process */ 130 my_pid = fork( ); 131 if ( my_pid == -1 ) { 132 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 133 return( -1 ); 134 } 135 else if ( my_pid == 0 ) { 136 struct stat my_sb; 137 138 /* child process does very little then exits */ 139 my_err = stat( &g_target_path[0], &my_sb ); 140 if ( my_err != 0 ) { 141 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 142 printf( "\t path we stated \"%s\" \n", &g_target_path[0] ); 143 exit( -1 ); 144 } 145 exit( 44 ); 146 } 147 148 /* parent process waits for child to exit */ 149 my_wait_pid = wait4( my_pid, &my_status, 0, &my_usage ); 150 if ( my_wait_pid == -1 ) { 151 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 152 return( -1 ); 153 } 154 155 /* wait4 should return our child's pid when it exits */ 156 if ( my_wait_pid != my_pid ) { 157 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid ); 158 return( -1 ); 159 } 160 161 /* kind of just guessing on these values so if this fails we should take a closer 162 * look at the returned rusage structure. 163 */ 164 if ( my_usage.ru_utime.tv_sec > 1 || my_usage.ru_stime.tv_sec > 1 || 165 my_usage.ru_majflt > 1000 || my_usage.ru_msgsnd > 100 ) { 166 printf( "wait4 returned an odd looking rusage structure \n" ); 167 return( -1 ); 168 } 169 170 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) == 44 ) { 171 } 172 else { 173 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status ); 174 return( -1 ); 175 } 176 177 return( 0 ); 178} 179 180/* ************************************************************************************************************** 181 * Test fsync, ftruncate, lseek, pread, pwrite, read, readv, truncate, write, writev system calls. 182 * ************************************************************************************************************** 183 */ 184int read_write_test( void * the_argp ) 185{ 186 int my_fd = -1; 187 int my_err; 188 char * my_pathp = NULL; 189 char * my_bufp = NULL; 190 ssize_t my_result; 191 off_t my_current_offset; 192 struct iovec my_iovs[2]; 193 struct stat my_sb; 194 kern_return_t my_kr; 195 196 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 197 if(my_kr != KERN_SUCCESS){ 198 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 199 goto test_failed_exit; 200 } 201 202 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, MY_BUFFER_SIZE, VM_FLAGS_ANYWHERE); 203 if(my_kr != KERN_SUCCESS){ 204 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 205 goto test_failed_exit; 206 } 207 208 *my_pathp = 0x00; 209 strcat( my_pathp, &g_target_path[0] ); 210 strcat( my_pathp, "/" ); 211 212 /* create a test file */ 213 my_err = create_random_name( my_pathp, 1 ); 214 if ( my_err != 0 ) { 215 goto test_failed_exit; 216 } 217 218 my_fd = open( my_pathp, O_RDONLY, 0 ); 219 if ( my_fd == -1 ) { 220 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 221 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp ); 222 goto test_failed_exit; 223 } 224 225 /* should get EOF since the file is empty at this point */ 226 my_result = read( my_fd, my_bufp, 10); 227 if ( my_result == -1 ) { 228 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 229 goto test_failed_exit; 230 } 231 if ( my_result != 0 ) { 232 if ( sizeof( ssize_t ) > sizeof( int ) ) { 233 printf( "read call failed - should have read 0 bytes on empty file - read %ld \n", (long int) my_result ); 234 } 235 else { 236 printf( "read call failed - should have read 0 bytes on empty file - read %d \n", (int) my_result ); 237 } 238 goto test_failed_exit; 239 } 240 241 /* this write should fail since we opened for read only */ 242 my_result = write( my_fd, my_bufp, 10 ); 243 my_err = errno; 244 if ( my_result != -1 ) { 245 if ( sizeof( ssize_t ) > sizeof( int ) ) { 246 printf( "write should have failed for read only fd - %ld \n", (long int) my_result ); 247 } 248 else { 249 printf( "write should have failed for read only fd - %d \n", (int) my_result ); 250 } 251 goto test_failed_exit; 252 } 253 if ( my_err != EBADF ) { 254 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 255 printf( "should have failed with EBADF error %d \n", EBADF ); 256 goto test_failed_exit; 257 } 258 259 /* now really write some data */ 260 close( my_fd ); 261 my_fd = open( my_pathp, O_RDWR, 0 ); 262 if ( my_fd == -1 ) { 263 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 264 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp ); 265 goto test_failed_exit; 266 } 267 268 memset( my_bufp, 'j', MY_BUFFER_SIZE ); 269 my_result = write( my_fd, my_bufp, MY_BUFFER_SIZE ); 270 if ( my_result == -1 ) { 271 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 272 goto test_failed_exit; 273 } 274 if ( my_result != MY_BUFFER_SIZE ) { 275 printf( "write failed to write out all the data \n" ); 276 goto test_failed_exit; 277 } 278 279 /* push data to disk */ 280 my_err = fsync( my_fd ); 281 if ( my_err == -1 ) { 282 printf( "fsync failed with errno %d - %s \n", errno, strerror( errno ) ); 283 goto test_failed_exit; 284 } 285 286 /* now verify the write worked OK using readv */ 287 lseek( my_fd, 0, SEEK_SET ); 288 bzero( (void *)my_bufp, MY_BUFFER_SIZE ); 289 my_iovs[0].iov_base = my_bufp; 290 my_iovs[0].iov_len = 16; 291 my_iovs[1].iov_base = (my_bufp + MY_BUFFER_SIZE - 16) ; 292 my_iovs[1].iov_len = 16; 293 294 my_result = readv( my_fd, &my_iovs[0], 2 ); 295 if ( my_result == -1 ) { 296 printf( "readv call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 297 goto test_failed_exit; 298 } 299 if ( my_result != 32 ) { 300 printf( "readv failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE, (int) my_result ); 301 goto test_failed_exit; 302 } 303 if ( *my_bufp != 'j' || *(my_bufp + (MY_BUFFER_SIZE - 1)) != 'j' ) { 304 printf( "readv failed to get correct data \n" ); 305 goto test_failed_exit; 306 } 307 308 /* test ftruncate */ 309 my_err = ftruncate( my_fd, 0 ); 310 if ( my_err == -1 ) { 311 printf( "ftruncate call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 312 goto test_failed_exit; 313 } 314 315 my_err = fstat( my_fd, &my_sb ); 316 if ( my_err == -1 ) { 317 printf( "fstat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 318 goto test_failed_exit; 319 } 320 if ( my_sb.st_size != 0 ) { 321 printf( "ftruncate call failed - file size is wrong \n" ); 322 goto test_failed_exit; 323 } 324 325 /* test writev */ 326 lseek( my_fd, 0, SEEK_SET ); 327 memset( my_bufp, 'z', MY_BUFFER_SIZE ); 328 my_iovs[0].iov_base = my_bufp; 329 my_iovs[0].iov_len = 8; 330 my_iovs[1].iov_base = (my_bufp + MY_BUFFER_SIZE - 8) ; 331 my_iovs[1].iov_len = 8; 332 my_result = writev( my_fd, &my_iovs[0], 2 ); 333 if ( my_result == -1 ) { 334 printf( "writev call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 335 goto test_failed_exit; 336 } 337 if ( my_result != 16 ) { 338 printf( "writev failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE, (int) my_result ); 339 goto test_failed_exit; 340 } 341 342 /* now verify the writev worked OK */ 343 lseek( my_fd, 0, SEEK_SET ); 344 bzero( (void *)my_bufp, MY_BUFFER_SIZE ); 345 my_iovs[0].iov_base = my_bufp; 346 my_iovs[0].iov_len = 8; 347 my_iovs[1].iov_base = (my_bufp + MY_BUFFER_SIZE - 8) ; 348 my_iovs[1].iov_len = 8; 349 350 my_result = readv( my_fd, &my_iovs[0], 2 ); 351 if ( my_result == -1 ) { 352 printf( "readv call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 353 goto test_failed_exit; 354 } 355 if ( my_result != 16 ) { 356 printf( "readv failed to get all the data - asked for %d got back %d\n", MY_BUFFER_SIZE, (int) my_result ); 357 goto test_failed_exit; 358 } 359 if ( *my_bufp != 'z' || *(my_bufp + (MY_BUFFER_SIZE - 1)) != 'z' ) { 360 printf( "readv failed to get correct data \n" ); 361 goto test_failed_exit; 362 } 363 364 /* test pread and pwrite */ 365 my_current_offset = lseek( my_fd, 0, SEEK_CUR ); 366 if ( my_current_offset == -1 ) { 367 printf( "lseek call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 368 goto test_failed_exit; 369 } 370 371 my_result = pwrite( my_fd, "jer", 3, my_current_offset ); 372 if ( my_result == -1 ) { 373 printf( "pwrite call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 374 goto test_failed_exit; 375 } 376 if ( my_result != 3 ) { 377 printf( "pwrite failed to write all the data \n" ); 378 goto test_failed_exit; 379 } 380 381 /* make sure file position did not advance */ 382 if ( my_current_offset != lseek( my_fd, 0, SEEK_CUR ) ) { 383 printf( "pwrite advanced file positiion \n" ); 384 goto test_failed_exit; 385 } 386 387 bzero( (void *)my_bufp, MY_BUFFER_SIZE ); 388 my_result = pread( my_fd, my_bufp, 3, my_current_offset ); 389 if ( my_result == -1 ) { 390 printf( "pread call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 391 goto test_failed_exit; 392 } 393 if ( my_result != 3 ) { 394 printf( "pread failed to write all the data \n" ); 395 goto test_failed_exit; 396 } 397 398 /* make sure file position did not advance */ 399 if ( my_current_offset != lseek( my_fd, 0, SEEK_CUR ) ) { 400 printf( "pread advanced file positiion \n" ); 401 goto test_failed_exit; 402 } 403 404 /* make sure pread and pwrite transferred correct data */ 405 if ( strcmp( my_bufp, "jer" ) != 0 ) { 406 printf( "pread or pwrite failed to read / write correct data \n" ); 407 goto test_failed_exit; 408 } 409 410 /* test truncate */ 411 my_err = truncate( my_pathp, 0 ); 412 if ( my_err == -1 ) { 413 printf( "truncate call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 414 goto test_failed_exit; 415 } 416 417 my_err = stat( my_pathp, &my_sb ); 418 if ( my_err == -1 ) { 419 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 420 goto test_failed_exit; 421 } 422 if ( my_sb.st_size != 0 ) { 423 printf( "truncate call failed - file size is wrong \n" ); 424 goto test_failed_exit; 425 } 426 427 my_err = 0; 428 goto test_passed_exit; 429 430test_failed_exit: 431 my_err = -1; 432 433test_passed_exit: 434 if ( my_fd != -1 ) 435 close( my_fd ); 436 if ( my_pathp != NULL ) { 437 remove( my_pathp ); 438 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 439 } 440 if ( my_bufp != NULL ) 441 vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, MY_BUFFER_SIZE); 442 return( my_err ); 443} 444 445/* ************************************************************************************************************** 446 * Test close, fpathconf, fstat, open, pathconf system calls. 447 * ************************************************************************************************************** 448 */ 449int open_close_test( void * the_argp ) 450{ 451 int my_err; 452 int my_fd = -1; 453 char * my_pathp = NULL; 454 ssize_t my_result; 455 long my_pconf_result; 456 struct stat my_sb; 457 char my_buffer[32]; 458 kern_return_t my_kr; 459 460 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 461 if(my_kr != KERN_SUCCESS){ 462 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 463 goto test_failed_exit; 464 } 465 466 *my_pathp = 0x00; 467 strcat( my_pathp, &g_target_path[0] ); 468 strcat( my_pathp, "/" ); 469 470 /* create a test file */ 471 my_err = create_random_name( my_pathp, 1 ); 472 if ( my_err != 0 ) { 473 goto test_failed_exit; 474 } 475 476 /* test O_WRONLY case */ 477 my_fd = open( my_pathp, O_WRONLY, 0 ); 478 if ( my_fd == -1 ) { 479 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 480 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp ); 481 goto test_failed_exit; 482 } 483 484 /* test pathconf and fpathconf */ 485 my_pconf_result = pathconf( my_pathp, _PC_PATH_MAX ); 486 if ( my_pconf_result == -1 ) { 487 printf( "pathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 488 goto test_failed_exit; 489 } 490// printf( "_PC_PATH_MAX %ld \n", my_pconf_result ); 491 /* results look OK? */ 492 if ( my_pconf_result < PATH_MAX ) { 493 printf( "pathconf - _PC_PATH_MAX - looks like wrong results \n" ); 494 goto test_failed_exit; 495 } 496 497 my_pconf_result = fpathconf( my_fd, _PC_NAME_MAX ); 498 if ( my_pconf_result == -1 ) { 499 printf( "fpathconf - _PC_PATH_MAX - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 500 goto test_failed_exit; 501 } 502// printf( "_PC_NAME_MAX %ld \n", my_pconf_result ); 503 /* results look OK? */ 504 if ( my_pconf_result < 6 ) { 505 printf( "fpathconf - _PC_NAME_MAX - looks like wrong results \n" ); 506 goto test_failed_exit; 507 } 508 509 /* write some data then try to read it */ 510 my_result = write( my_fd, "kat", 3 ); 511 my_err = errno; 512 if ( my_result != 3 ) { 513 if ( sizeof( ssize_t ) > sizeof( int ) ) { 514 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result ); 515 } 516 else { 517 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result ); 518 } 519 goto test_failed_exit; 520 } 521 522 /* Try to read - this should fail since we opened file with O_WRONLY */ 523 my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) ); 524 my_err = errno; 525 if ( my_result != -1 ) { 526 printf( "read call should have failed with errno 9 (EBADF) \n" ); 527 goto test_failed_exit; 528 } 529 else if ( my_err != EBADF ) { 530 printf( "read call should have failed with errno 9 (EBADF). actually failed with %d - \"%s\" \n", my_err, strerror( my_err) ); 531 goto test_failed_exit; 532 } 533 534 close( my_fd ); 535 536 /* test O_TRUNC and O_APPEND case */ 537 my_fd = open( my_pathp, (O_RDWR | O_TRUNC | O_APPEND), 0 ); 538 if ( my_fd == -1 ) { 539 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 540 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp ); 541 goto test_failed_exit; 542 } 543 544 my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) ); 545 if ( my_result == -1 ) { 546 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 547 goto test_failed_exit; 548 } 549 if ( my_result != 0 ) { 550 printf( "read failed - should have read 0 bytes. \n" ); 551 goto test_failed_exit; 552 } 553 554 my_result = write( my_fd, "kat", 3 ); 555 my_err = errno; 556 if ( my_result != 3 ) { 557 if ( sizeof( ssize_t ) > sizeof( int ) ) { 558 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result ); 559 } 560 else { 561 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result ); 562 } 563 goto test_failed_exit; 564 } 565 566 /* add some more data to the test file - this should be appended */ 567 lseek( my_fd, 0, SEEK_SET ); 568 my_result = write( my_fd, "zzz", 3 ); 569 my_err = errno; 570 if ( my_result != 3 ) { 571 if ( sizeof( ssize_t ) > sizeof( int ) ) { 572 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result ); 573 } 574 else { 575 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result ); 576 } 577 goto test_failed_exit; 578 } 579 580 /* now verify the writes */ 581 bzero( (void *)&my_buffer[0], sizeof(my_buffer) ); 582 lseek( my_fd, 0, SEEK_SET ); 583 my_result = read( my_fd, &my_buffer[0], sizeof(my_buffer) ); 584 if ( my_result == -1 ) { 585 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 586 goto test_failed_exit; 587 } 588 if ( my_buffer[0] != 'k' || my_buffer[5] != 'z' ) { 589 printf( "read failed to get correct data \n" ); 590 goto test_failed_exit; 591 } 592 593 /* test fstat */ 594 my_err = fstat( my_fd, &my_sb ); 595 if ( my_err == -1 ) { 596 printf( "fstat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 597 goto test_failed_exit; 598 } 599 if ( my_sb.st_size != 6 ) { 600 printf( "fstat call failed - st_size is wrong \n" ); 601 goto test_failed_exit; 602 } 603 if ( !S_ISREG( my_sb.st_mode ) ) { 604 printf( "fstat call failed - st_mode does not indicate regular file \n" ); 605 goto test_failed_exit; 606 } 607 608 my_err = 0; 609 goto test_passed_exit; 610 611test_failed_exit: 612 my_err = -1; 613 614test_passed_exit: 615 if ( my_fd != -1 ) 616 close( my_fd ); 617 if ( my_pathp != NULL ) { 618 remove( my_pathp ); 619 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 620 } 621 return( my_err ); 622} 623 624/* ************************************************************************************************************** 625 * Test link, stat and unlink system calls. 626 * ************************************************************************************************************** 627 */ 628int link_stat_unlink_test( void * the_argp ) 629{ 630 int my_err; 631 int my_fd = -1; 632 char * my_pathp = NULL; 633 char * my_path2p = NULL; 634 nlink_t my_link_count; 635 ssize_t my_result; 636 struct stat my_sb; 637 kern_return_t my_kr; 638 639 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 640 if(my_kr != KERN_SUCCESS){ 641 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 642 goto test_failed_exit; 643 } 644 645 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_path2p, PATH_MAX, VM_FLAGS_ANYWHERE); 646 if(my_kr != KERN_SUCCESS){ 647 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 648 goto test_failed_exit; 649 } 650 651 *my_pathp = 0x00; 652 *my_path2p = 0x00; 653 strcat( my_pathp, &g_target_path[0] ); 654 strcat( my_pathp, "/" ); 655 656 /* create a test file */ 657 my_err = create_random_name( my_pathp, 1 ); 658 if ( my_err != 0 ) { 659 goto test_failed_exit; 660 } 661 662 /* now create a name for the link file */ 663 strcat( my_path2p, my_pathp ); 664 strcat( my_path2p, "link" ); 665 666 /* get the current link count */ 667 my_err = stat( my_pathp, &my_sb ); 668 if ( my_err != 0 ) { 669 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 670 goto test_failed_exit; 671 } 672 my_link_count = my_sb.st_nlink; 673 674 /* check file size (should be 0) */ 675 if ( my_sb.st_size != 0 ) { 676 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp ); 677 printf( "st_size is not 0 \n" ); 678 goto test_failed_exit; 679 } 680 681 /* change file size */ 682 my_fd = open( my_pathp, O_RDWR, 0 ); 683 if ( my_fd == -1 ) { 684 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 685 printf( "\t file we attempted to open -> \"%s\" \n", my_pathp ); 686 goto test_failed_exit; 687 } 688 my_result = write( my_fd, "kat", 3 ); 689 my_err = errno; 690 if ( my_result != 3 ) { 691 if ( sizeof( ssize_t ) > sizeof( int ) ) { 692 printf( "write failed. should have written 3 bytes actually wrote - %ld \n", (long int) my_result ); 693 } 694 else { 695 printf( "write failed. should have written 3 bytes actually wrote - %d \n", (int) my_result ); 696 } 697 goto test_failed_exit; 698 } 699 close( my_fd ); 700 my_fd = -1; 701 702 /* now link another file to our test file and recheck link count */ 703 my_err = link( my_pathp, my_path2p ); 704 if ( my_err != 0 ) { 705 printf( "link call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 706 goto test_failed_exit; 707 } 708 my_err = stat( my_pathp, &my_sb ); 709 if ( my_err != 0 ) { 710 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 711 goto test_failed_exit; 712 } 713 if ( (my_link_count + 1) != my_sb.st_nlink ) { 714 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp ); 715 printf( "incorrect st_nlink \n" ); 716 goto test_failed_exit; 717 } 718 719 /* check file size (should be 3) */ 720 if ( my_sb.st_size != 3 ) { 721 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp ); 722 printf( "st_size is not 3 \n" ); 723 goto test_failed_exit; 724 } 725 726 /* now make sure unlink works OK */ 727 my_err = unlink( my_path2p ); 728 if ( my_err != 0 ) { 729 printf( "unlink call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 730 goto test_failed_exit; 731 } 732 my_err = stat( my_pathp, &my_sb ); 733 if ( my_err != 0 ) { 734 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 735 goto test_failed_exit; 736 } 737 if ( my_link_count != my_sb.st_nlink ) { 738 printf( "stat structure looks bogus for test file \"%s\" \n", my_pathp ); 739 printf( "incorrect st_nlink \n" ); 740 goto test_failed_exit; 741 } 742 743 my_err = 0; 744 goto test_passed_exit; 745 746test_failed_exit: 747 my_err = -1; 748 749test_passed_exit: 750 if ( my_fd != -1 ) 751 close( my_fd ); 752 if ( my_pathp != NULL ) { 753 remove( my_pathp ); 754 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 755 } 756 if ( my_path2p != NULL ) { 757 remove( my_path2p ); 758 vm_deallocate(mach_task_self(), (vm_address_t)my_path2p, PATH_MAX); 759 } 760 return( my_err ); 761} 762 763/* ************************************************************************************************************** 764 * Test chdir and fchdir system calls. 765 * ************************************************************************************************************** 766 */ 767int chdir_fchdir_test( void * the_argp ) 768{ 769 int my_err; 770 int my_fd = -1; 771 char * my_pathp = NULL; 772 char * my_file_namep; 773 struct stat my_sb; 774 struct stat my_sb2; 775 kern_return_t my_kr; 776 777 char *cwd = getwd(NULL); /* Save current working directory so we can restore later */ 778 779 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 780 if(my_kr != KERN_SUCCESS){ 781 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 782 goto test_failed_exit; 783 } 784 785 *my_pathp = 0x00; 786 strcat( my_pathp, &g_target_path[0] ); 787 strcat( my_pathp, "/" ); 788 789 /* create a test file */ 790 my_err = create_random_name( my_pathp, 1 ); 791 if ( my_err != 0 ) { 792 goto test_failed_exit; 793 } 794 795 /* test by doing a stat on the test file using a full path and a partial path. 796 * get full path first. 797 */ 798 my_err = stat( my_pathp, &my_sb ); 799 if ( my_err != 0 ) { 800 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 801 goto test_failed_exit; 802 } 803 804 /* now do the chdir to our test directory and then do the stat relative to that location */ 805 my_err = chdir( &g_target_path[0] ); 806 if ( my_err != 0 ) { 807 printf( "chdir call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 808 goto test_failed_exit; 809 } 810 811 my_file_namep = strrchr( my_pathp, '/' ); 812 my_file_namep++; 813 my_err = stat( my_file_namep, &my_sb2 ); 814 if ( my_err != 0 ) { 815 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 816 goto test_failed_exit; 817 } 818 819 /* both stat buffers should contain the same data since they should be referencing the same 820 * file. 821 */ 822 if ( my_sb.st_ino != my_sb2.st_ino || my_sb.st_size != my_sb2.st_size || 823 my_sb.st_mtimespec.tv_sec != my_sb2.st_mtimespec.tv_sec || 824 my_sb.st_mtimespec.tv_nsec != my_sb2.st_mtimespec.tv_nsec ) { 825 printf( "chdir call appears to have failed. stat buffer contents do not match! \n" ); 826 goto test_failed_exit; 827 } 828 829 /* now change our current directory to "/" and use fchdir to get back to our test directory */ 830 my_err = chdir( "/" ); 831 if ( my_err != 0 ) { 832 printf( "chdir call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 833 goto test_failed_exit; 834 } 835 836 /* we should not find our test file at the root of the volume */ 837 my_err = stat( my_file_namep, &my_sb2 ); 838 if ( my_err == 0 ) { 839 printf( "chdir to root volume has failed \n" ); 840 goto test_failed_exit; 841 } 842 843 /* get a file descriptor to the test directory for use with fchdir */ 844 my_fd = open( &g_target_path[0], O_RDONLY, 0 ); 845 if ( my_fd == -1 ) { 846 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 847 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] ); 848 goto test_failed_exit; 849 } 850 851 my_err = fchdir( my_fd ); 852 if ( my_err == -1 ) { 853 printf( "fchdir call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 854 goto test_failed_exit; 855 } 856 857 my_err = stat( my_file_namep, &my_sb2 ); 858 if ( my_err != 0 ) { 859 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 860 goto test_failed_exit; 861 } 862 863 /* both stat buffers should contain the same data since they should be referencing the same 864 * file. 865 */ 866 if ( my_sb.st_ino != my_sb2.st_ino || my_sb.st_size != my_sb2.st_size || 867 my_sb.st_mtimespec.tv_sec != my_sb2.st_mtimespec.tv_sec || 868 my_sb.st_mtimespec.tv_nsec != my_sb2.st_mtimespec.tv_nsec ) { 869 printf( "chdir call appears to have failed. stat buffer contents do not match! \n" ); 870 goto test_failed_exit; 871 } 872 873 my_err = 0; 874 goto test_passed_exit; 875 876test_failed_exit: 877 my_err = -1; 878 879test_passed_exit: 880 if ( my_fd != -1 ) 881 close( my_fd ); 882 if ( my_pathp != NULL ) { 883 remove( my_pathp ); 884 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 885 } 886 if ( chdir(cwd) != 0) /* Changes back to original directory, don't screw up the env. */ 887 my_err = -1; 888 return( my_err ); 889} 890 891/* ************************************************************************************************************** 892 * Test access, chmod and fchmod system calls. 893 * ************************************************************************************************************** 894 */ 895int access_chmod_fchmod_test( void * the_argp ) 896{ 897 int error_occurred; 898 int my_err; 899 int my_fd = -1; 900 901 char * my_pathp = NULL; 902 903 uid_t euid,ruid; 904 struct stat my_sb; 905 906 FILE * file_handle; 907 908 kern_return_t my_kr; 909 910 911 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 912 if(my_kr != KERN_SUCCESS){ 913 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 914 goto test_failed_exit; 915 } 916 917 *my_pathp = 0x00; 918 strcat( my_pathp, &g_target_path[0] ); 919 strcat( my_pathp, "/" ); 920 921 /* create a test file */ 922 my_err = create_random_name( my_pathp, 1 ); 923 if ( my_err != 0 ) { 924 goto test_failed_exit; 925 } 926 927 928 /* test chmod */ 929 my_err = chmod( my_pathp, S_IRWXU ); 930 if ( my_err == -1 ) { 931 printf( "chmod call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 932 goto test_failed_exit; 933 } 934 935 my_err = chmod( my_pathp, (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) ); 936 if ( my_err == -1 ) { 937 printf( "chmod call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 938 goto test_failed_exit; 939 } 940 941 /* test access - this should fail */ 942 my_err = access( my_pathp, (X_OK) ); 943 if ( my_err == 0 ) { 944 printf( "access call should have failed, but did not. \n" ); 945 goto test_failed_exit; 946 } 947 else if ( my_err == -1 ) { 948 int tmp = 0; 949 tmp = getuid( ); 950 951 /* special case when running as root - we get back EPERM when running as root */ 952 my_err = errno; 953 if ( ( tmp == 0 && my_err != EPERM) || (tmp != 0 && my_err != EACCES) ) { 954 printf( "access failed with errno %d - %s. \n", my_err, strerror( my_err ) ); 955 goto test_failed_exit; 956 } 957 } 958 959 /* verify correct modes are set */ 960 my_err = stat( my_pathp, &my_sb ); 961 if ( my_err != 0 ) { 962 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 963 goto test_failed_exit; 964 } 965 966 if ( (my_sb.st_mode & (S_IRWXO | S_IXGRP)) != 0 || 967 (my_sb.st_mode & (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == 0 ) { 968 printf( "chmod call appears to have failed. stat shows incorrect values in st_mode! \n" ); 969 goto test_failed_exit; 970 } 971 972 973 /* another test for the access system call -- refer ro radar# 6725311 */ 974 975#if !TARGET_OS_EMBEDDED 976 977 /* 978 * This test makes sure that the access system call does not give the current user extra 979 * permissions on files the current user does not own. From radar #6725311, this could 980 * happen when the current user calls access() on a file owned by the current user in 981 * the same directory as the other files not owned by the current user. 982 * 983 * Note: This test expects that the effective uid (euid) is set to root. 984 * 985 */ 986 987 /* Create a file that root owns */ 988 file_handle = fopen(FILE_NOTME, "w"); 989 fclose(file_handle); 990 991 /* Currently running as root (through setreuid manipulation), switch to running as the current user. */ 992 euid = geteuid(); 993 ruid = getuid(); 994 setreuid(ruid, ruid); 995 996 /* Create a file that the current user owns */ 997 file_handle = fopen(FILE_ME, "w"); 998 fclose(file_handle); 999 1000 error_occurred = 0; 1001 1002 /* Try to remove the file owned by root (this should fail). */ 1003 my_err = unlink(FILE_NOTME); 1004 1005 if (my_err < 0) { 1006 my_err = errno; 1007 } 1008 1009 if (my_err == 0) { 1010 printf("Unresolved: First attempt deleted '" FILE_NOTME "'! \n"); 1011 error_occurred = 1; 1012 } else { 1013 printf("Status: First attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err )); 1014 1015 /* Set _DELETE_OK on a file that the current user owns */ 1016 access(FILE_ME, _DELETE_OK); 1017 1018 /* Try to remove the file owned by root again (should give us: EPERM [13]) */ 1019 my_err = unlink(FILE_NOTME); 1020 1021 if (my_err < 0) { 1022 my_err = errno; 1023 } 1024 1025 if (my_err == 0) { 1026 printf("Failed: Second attempt deleted '" FILE_NOTME "'!\n"); 1027 error_occurred = 1; 1028 } else if (my_err == 13) { 1029 printf("Passed: Second attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err )); 1030 } else { 1031 printf("Failed: Second attempt to delete '" FILE_NOTME "' failed with error %d - %s.\n", my_err, strerror( my_err )); 1032 error_occurred = 1; 1033 } 1034 } 1035 1036 /* Reset to running as root */ 1037 setreuid(ruid, euid); 1038 1039 if(error_occurred == 1) { 1040 goto test_failed_exit; 1041 } 1042 1043#endif 1044 1045 /* end of test*/ 1046 1047 1048 /* test fchmod */ 1049 my_fd = open( my_pathp, O_RDONLY, 0 ); 1050 if ( my_fd == -1 ) { 1051 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1052 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] ); 1053 goto test_failed_exit; 1054 } 1055 1056 my_err = fchmod( my_fd, S_IRWXU ); 1057 if ( my_err == -1 ) { 1058 printf( "fchmod call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1059 goto test_failed_exit; 1060 } 1061 1062 my_err = stat( my_pathp, &my_sb ); 1063 if ( my_err != 0 ) { 1064 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1065 goto test_failed_exit; 1066 } 1067 1068 /* verify correct modes are set */ 1069 if ( (my_sb.st_mode & (S_IRWXG | S_IRWXO)) != 0 || 1070 (my_sb.st_mode & (S_IRWXU)) == 0 ) { 1071 printf( "fchmod call appears to have failed. stat shows incorrect values in st_mode! \n" ); 1072 goto test_failed_exit; 1073 } 1074 1075 my_err = 0; 1076 goto test_passed_exit; 1077 1078test_failed_exit: 1079 my_err = -1; 1080 1081test_passed_exit: 1082 if ( my_fd != -1 ) 1083 close( my_fd ); 1084 if ( my_pathp != NULL ) { 1085 remove( my_pathp ); 1086 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 1087 } 1088 return( my_err ); 1089} 1090 1091#if !TARGET_OS_EMBEDDED 1092static bool _prime_groups(void) 1093{ 1094 /* 1095 * prime groups with a known list to ensure consistent test behavior 1096 */ 1097 1098 gid_t my_exp_groups[] = { getegid(), 20, 61, 12 }; 1099 int my_err; 1100 1101 my_err = setgroups( ( sizeof(my_exp_groups) / sizeof(*my_exp_groups) ), &my_exp_groups[0] ); 1102 if ( my_err == -1 ) { 1103 printf( "initial setgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1104 return false; 1105 } 1106 1107 return true; 1108} 1109#endif 1110 1111/* ************************************************************************************************************** 1112 * Test chown, fchown, lchown, lstat, readlink, symlink system calls. 1113 * ************************************************************************************************************** 1114 */ 1115int chown_fchown_lchown_lstat_symlink_test( void * the_argp ) 1116{ 1117#if !TARGET_OS_EMBEDDED 1118 int my_err, my_group_count, i; 1119 int my_fd = -1; 1120 char * my_pathp = NULL; 1121 char * my_link_pathp = NULL; 1122 uid_t my_orig_uid; 1123 gid_t my_orig_gid, my_new_gid1 = 0, my_new_gid2 = 0; 1124 ssize_t my_result; 1125 struct stat my_sb; 1126 gid_t my_groups[ NGROUPS_MAX ]; 1127 char my_buffer[ 64 ]; 1128 kern_return_t my_kr; 1129 1130 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 1131 if(my_kr != KERN_SUCCESS){ 1132 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1133 goto test_failed_exit; 1134 } 1135 1136 *my_pathp = 0x00; 1137 strcat( my_pathp, &g_target_path[0] ); 1138 strcat( my_pathp, "/" ); 1139 1140 /* create a test file */ 1141 my_err = create_random_name( my_pathp, 1 ); 1142 if ( my_err != 0 ) { 1143 goto test_failed_exit; 1144 } 1145 1146 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_link_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 1147 if(my_kr != KERN_SUCCESS){ 1148 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1149 goto test_failed_exit; 1150 } 1151 1152 *my_link_pathp = 0x00; 1153 strcat( my_link_pathp, &g_target_path[0] ); 1154 strcat( my_link_pathp, "/" ); 1155 1156 /* get a test file name for the link */ 1157 my_err = create_random_name( my_link_pathp, 0 ); 1158 if ( my_err != 0 ) { 1159 goto test_failed_exit; 1160 } 1161 1162 if ( !_prime_groups() ) { 1163 goto test_failed_exit; 1164 } 1165 1166 /* set up by getting a list of groups */ 1167 my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] ); 1168 1169 if ( my_group_count == -1 || my_group_count < 1 ) { 1170 printf( "getgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1171 goto test_failed_exit; 1172 } 1173 1174 my_err = stat( my_pathp, &my_sb ); 1175 if ( my_err != 0 ) { 1176 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1177 goto test_failed_exit; 1178 } 1179 1180 /* now change group owner to something other than current value */ 1181 my_orig_gid = my_sb.st_gid; 1182 my_orig_uid = my_sb.st_uid; 1183 1184 for ( i = 0; i < my_group_count; i++ ) { 1185 if ( my_orig_gid != my_groups[ i ] ) { 1186 if ( my_new_gid1 == 0 ) { 1187 my_new_gid1 = my_groups[ i ]; 1188 } 1189 else { 1190 my_new_gid2 = my_groups[ i ]; 1191 break; 1192 } 1193 } 1194 } 1195 if ( i >= my_group_count ) { 1196 printf( "not enough groups to choose from. st_gid is the same as current groups! \n" ); 1197 goto test_failed_exit; 1198 } 1199 1200 my_err = chown( my_pathp, my_orig_uid, my_new_gid1 ); 1201 if ( my_err != 0 ) { 1202 printf( "chown call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1203 goto test_failed_exit; 1204 } 1205 1206 /* make sure the group owner was changed */ 1207 my_err = stat( my_pathp, &my_sb ); 1208 if ( my_err != 0 ) { 1209 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1210 goto test_failed_exit; 1211 } 1212 if ( my_sb.st_gid == my_orig_gid ) { 1213 printf( "chown call failed. st_gid is not correct! \n" ); 1214 goto test_failed_exit; 1215 } 1216 1217 /* change group owner back using fchown */ 1218 my_fd = open( my_pathp, O_RDWR, 0 ); 1219 if ( my_fd == -1 ) { 1220 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1221 printf( "\t we attempted to open -> \"%s\" \n", &g_target_path[0] ); 1222 goto test_failed_exit; 1223 } 1224 1225 my_err = fchown( my_fd, my_orig_uid, my_new_gid2 ); 1226 if ( my_err != 0 ) { 1227 printf( "fchown call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1228 goto test_failed_exit; 1229 } 1230 1231 /* make sure the group owner was changed back to the original value */ 1232 my_err = stat( my_pathp, &my_sb ); 1233 if ( my_err != 0 ) { 1234 printf( "stat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1235 goto test_failed_exit; 1236 } 1237 if ( my_sb.st_gid == my_new_gid1 ) { 1238 printf( "fchown call failed. st_gid is not correct! \n" ); 1239 goto test_failed_exit; 1240 } 1241 1242 /* create a link file and test lchown */ 1243 my_err = symlink( my_pathp, my_link_pathp ); 1244 if ( my_err != 0 ) { 1245 printf( "symlink call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1246 goto test_failed_exit; 1247 } 1248 1249 my_err = lstat( my_link_pathp, &my_sb ); 1250 if ( my_err != 0 ) { 1251 printf( "lstat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1252 goto test_failed_exit; 1253 } 1254 1255 /* now change group owner to something other than current value */ 1256 my_orig_gid = my_sb.st_gid; 1257 my_orig_uid = my_sb.st_uid; 1258 my_err = lchown( my_link_pathp, my_orig_uid, my_new_gid1 ); 1259 if ( my_err != 0 ) { 1260 printf( "lchown call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1261 goto test_failed_exit; 1262 } 1263 1264 /* make sure the group owner was changed to new value */ 1265 my_err = lstat( my_link_pathp, &my_sb ); 1266 if ( my_err != 0 ) { 1267 printf( "lstat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1268 goto test_failed_exit; 1269 } 1270 if ( my_sb.st_gid == my_new_gid2 ) { 1271 printf( "lchown call failed. st_gid is not correct! \n" ); 1272 goto test_failed_exit; 1273 } 1274 1275 /* make sure we can read the symlink file */ 1276 my_result = readlink( my_link_pathp, &my_buffer[0], sizeof(my_buffer) ); 1277 if ( my_result == -1 ) { 1278 printf( "readlink call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1279 goto test_failed_exit; 1280 } 1281 /* make sure we read some data */ 1282 if ( my_result < 1 ) { 1283 printf( "readlink failed to read any data. \n" ); 1284 goto test_failed_exit; 1285 } 1286 1287 my_err = 0; 1288 goto test_passed_exit; 1289 1290test_failed_exit: 1291 my_err = -1; 1292 1293test_passed_exit: 1294 if ( my_fd != -1 ) 1295 close( my_fd ); 1296 if ( my_pathp != NULL ) { 1297 remove( my_pathp ); 1298 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 1299 } 1300 if ( my_link_pathp != NULL ) { 1301 unlink( my_link_pathp ); 1302 vm_deallocate(mach_task_self(), (vm_address_t)my_link_pathp, PATH_MAX); 1303 } 1304 return( my_err ); 1305#else 1306 printf( "\t--> Test not designed for EMBEDDED TARGET\n" ); 1307 return 0; 1308#endif 1309} 1310 1311/* ************************************************************************************************************** 1312 * Test fstatfs, getattrlist, getfsstat, statfs, getfsstat64, statfs64, fstatfs64 system calls. 1313 * ************************************************************************************************************** 1314 */ 1315 1316#pragma pack(4) 1317struct vol_attr_buf { 1318 u_int32_t length; 1319 off_t volume_size; 1320 u_int32_t io_blksize; 1321}; 1322#pragma pack() 1323typedef struct vol_attr_buf vol_attr_buf; 1324 1325#define STATFS_TEST_PATH "/tmp" 1326 1327int fs_stat_tests( void * the_argp ) 1328{ 1329 int my_err, my_count, i; 1330 int my_buffer_size, my_buffer64_size; 1331 int my_fd = -1; 1332 int is_ufs = 0; 1333 long my_io_size; 1334 fsid_t my_fsid; 1335 struct attrlist my_attrlist; 1336 vol_attr_buf my_attr_buf; 1337 void * my_bufferp = NULL; 1338 struct statfs * my_statfsp; 1339 kern_return_t my_kr; 1340 1341#if !TARGET_OS_EMBEDDED 1342 void * my_buffer64p = NULL; 1343 struct statfs64 * my_statfs64p; 1344 1345 my_buffer64_size = (sizeof(struct statfs64) * 10); 1346 1347 my_kr = vm_allocate((vm_map_t) mach_task_self(),(vm_address_t*) &my_buffer64p, my_buffer64_size, VM_FLAGS_ANYWHERE); 1348 if(my_kr != KERN_SUCCESS){ 1349 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1350 goto test_failed_exit; 1351 } 1352 1353#endif 1354 my_buffer_size = (sizeof(struct statfs) * 10); 1355 1356 my_kr = vm_allocate((vm_map_t) mach_task_self(),(vm_address_t*) &my_bufferp, my_buffer_size, VM_FLAGS_ANYWHERE); 1357 if(my_kr != KERN_SUCCESS){ 1358 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1359 goto test_failed_exit; 1360 } 1361 1362 my_statfsp = (struct statfs *) my_bufferp; 1363 my_err = statfs( STATFS_TEST_PATH, my_statfsp ); 1364 if ( my_err == -1 ) { 1365 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1366 goto test_failed_exit; 1367 } 1368 if ( memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 ) { 1369 is_ufs = 1; 1370 } 1371 1372 my_count = getfsstat( (struct statfs *)my_bufferp, my_buffer_size, MNT_NOWAIT ); 1373 if ( my_count == -1 ) { 1374 printf( "getfsstat call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1375 goto test_failed_exit; 1376 } 1377 1378 /* validate results */ 1379 my_statfsp = (struct statfs *) my_bufferp; 1380 for ( i = 0; i < my_count; i++, my_statfsp++ ) { 1381 if ( memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 || 1382 memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0 || 1383 memcmp( &my_statfsp->f_fstypename[0], "devfs", 5 ) == 0 || 1384 memcmp( &my_statfsp->f_fstypename[0], "volfs", 5 ) == 0 ) { 1385 /* found a valid entry */ 1386 break; 1387 } 1388 } 1389 if ( i >= my_count ) { 1390 printf( "getfsstat call failed. could not find valid f_fstypename! \n" ); 1391 goto test_failed_exit; 1392 } 1393 1394#if !TARGET_OS_EMBEDDED 1395 /* now try statfs64 */ 1396 my_statfs64p = (struct statfs64 *) my_buffer64p; 1397 my_err = statfs64( STATFS_TEST_PATH, my_statfs64p ); 1398 if ( my_err == -1 ) { 1399 printf( "statfs64 call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1400 goto test_failed_exit; 1401 } 1402 if ( my_statfs64p->f_fsid.val[0] != my_statfsp->f_fsid.val[0] || 1403 my_statfs64p->f_fsid.val[1] != my_statfsp->f_fsid.val[1] ) { 1404 printf( "statfs64 call failed. wrong f_fsid! \n" ); 1405 goto test_failed_exit; 1406 } 1407 1408 my_count = getfsstat64( (struct statfs64 *)my_buffer64p, my_buffer64_size, MNT_NOWAIT ); 1409 if ( my_count == -1 ) { 1410 printf( "getfsstat64 call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1411 goto test_failed_exit; 1412 } 1413 1414 /* validate results */ 1415 my_statfs64p = (struct statfs64 *) my_buffer64p; 1416 for ( i = 0; i < my_count; i++, my_statfs64p++ ) { 1417 if ( memcmp( &my_statfs64p->f_fstypename[0], "hfs", 3 ) == 0 || 1418 memcmp( &my_statfs64p->f_fstypename[0], "ufs", 3 ) == 0 || 1419 memcmp( &my_statfs64p->f_fstypename[0], "devfs", 5 ) == 0 || 1420 memcmp( &my_statfs64p->f_fstypename[0], "volfs", 5 ) == 0 ) { 1421 /* found a valid entry */ 1422 break; 1423 } 1424 } 1425 if ( i >= my_count ) { 1426 printf( "getfsstat64 call failed. could not find valid f_fstypename! \n" ); 1427 goto test_failed_exit; 1428 } 1429#endif 1430 1431 /* set up to validate results via multiple sources. we use getattrlist to get volume 1432 * related attributes to verify against results from fstatfs and statfs - but only if 1433 * we are not targeting ufs volume since it doesn't support getattr calls 1434 */ 1435 if ( is_ufs == 0 ) { 1436 memset( &my_attrlist, 0, sizeof(my_attrlist) ); 1437 my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT; 1438 my_attrlist.volattr = (ATTR_VOL_SIZE | ATTR_VOL_IOBLOCKSIZE); 1439 my_err = getattrlist( "/", &my_attrlist, &my_attr_buf, sizeof(my_attr_buf), 0 ); 1440 if ( my_err != 0 ) { 1441 printf( "getattrlist call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1442 goto test_failed_exit; 1443 } 1444 } 1445 1446 /* open to use as test file for fstatfs */ 1447 my_fd = open( STATFS_TEST_PATH, O_RDONLY, 0 ); 1448 if ( my_fd == -1 ) { 1449 printf( "open call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1450 goto test_failed_exit; 1451 } 1452 1453#if !TARGET_OS_EMBEDDED 1454 /* testing fstatfs64 */ 1455 my_statfs64p = (struct statfs64 *) my_buffer64p; 1456 my_err = fstatfs64( my_fd, my_statfs64p ); 1457 if ( my_err == -1 ) { 1458 printf( "fstatfs64 call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1459 goto test_failed_exit; 1460 } 1461 1462 /* validate results - assumes we only boot from hfs or ufs */ 1463 if ( !(memcmp( &my_statfs64p->f_fstypename[0], "hfs", 3 ) == 0 || 1464 memcmp( &my_statfs64p->f_fstypename[0], "ufs", 3 ) == 0) ) { 1465 printf( "fstatfs64 call failed. could not find valid f_fstypename! \n" ); 1466 goto test_failed_exit; 1467 } 1468#endif 1469 1470 /* testing fstatfs */ 1471 my_statfsp = (struct statfs *) my_bufferp; 1472 my_err = fstatfs( my_fd, my_statfsp ); 1473 if ( my_err == -1 ) { 1474 printf( "fstatfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1475 goto test_failed_exit; 1476 } 1477 1478 /* validate results */ 1479 if ( !(memcmp( &my_statfsp->f_fstypename[0], "hfs", 3 ) == 0 || 1480 memcmp( &my_statfsp->f_fstypename[0], "ufs", 3 ) == 0) ) { 1481 printf( "fstatfs call failed. could not find valid f_fstypename! \n" ); 1482 goto test_failed_exit; 1483 } 1484 my_io_size = my_statfsp->f_iosize; 1485 my_fsid = my_statfsp->f_fsid; 1486 if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) { 1487 printf( "fstatfs and getattrlist results do not match for volume block size \n" ); 1488 goto test_failed_exit; 1489 } 1490 1491 /* try again with statfs */ 1492 my_err = statfs( STATFS_TEST_PATH , my_statfsp ); 1493 if ( my_err == -1 ) { 1494 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1495 goto test_failed_exit; 1496 } 1497 1498 /* validate results */ 1499 if ( my_io_size != my_statfsp->f_iosize || my_fsid.val[0] != my_statfsp->f_fsid.val[0] || 1500 my_fsid.val[1] != my_statfsp->f_fsid.val[1] ) { 1501 printf( "statfs call failed. wrong f_iosize or f_fsid! \n" ); 1502 goto test_failed_exit; 1503 } 1504 if ( is_ufs == 0 && my_statfsp->f_iosize != my_attr_buf.io_blksize ) { 1505 printf( "statfs and getattrlist results do not match for volume block size \n" ); 1506 goto test_failed_exit; 1507 } 1508 1509 my_err = 0; 1510 goto test_passed_exit; 1511 1512test_failed_exit: 1513 my_err = -1; 1514 1515test_passed_exit: 1516 if ( my_fd != -1 ) 1517 close( my_fd ); 1518 if ( my_bufferp != NULL ) { 1519 vm_deallocate(mach_task_self(), (vm_address_t)my_bufferp, my_buffer_size); 1520 } 1521#if !TARGET_OS_EMBEDDED 1522 if ( my_buffer64p != NULL ) { 1523 vm_deallocate(mach_task_self(), (vm_address_t)my_buffer64p, my_buffer64_size); 1524 } 1525#endif 1526 1527 return( my_err ); 1528} 1529 1530/* ************************************************************************************************************** 1531 * Test getpid, getppid, and pipe system calls. 1532 * ************************************************************************************************************** 1533 */ 1534int getpid_getppid_pipe_test( void * the_argp ) 1535{ 1536 int my_err, my_status; 1537 pid_t my_pid, my_wait_pid; 1538 ssize_t my_count; 1539 int my_fildes[2] = {-1, -1}; 1540 off_t my_current_offset; 1541 char my_pid_string[64]; 1542 1543 my_err = pipe( &my_fildes[0] ); 1544 if ( my_err != 0 ) { 1545 printf( "pipe call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1546 goto test_failed_exit; 1547 } 1548 1549 /* make sure we can't seek on a pipe */ 1550 my_current_offset = lseek( my_fildes[0], 0, SEEK_CUR ); 1551 if ( my_current_offset != -1 ) { 1552 printf( "lseek on pipe should fail but did not \n" ); 1553 goto test_failed_exit; 1554 } 1555 1556 /* fork here and use pipe to communicate */ 1557 my_pid = fork( ); 1558 if ( my_pid == -1 ) { 1559 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 1560 goto test_failed_exit; 1561 } 1562 else if ( my_pid == 0 ) { 1563 /* child process */ 1564 unsigned long my_ppid; 1565 char my_buffer[64]; 1566 1567 close( my_fildes[1] ); /* close write end of pipe */ 1568 my_fildes[1] = -1; 1569 1570 /* get the parent's pid using getppid and from the parent (using getpid in porent) */ 1571 my_count = read( my_fildes[0], &my_buffer[0], sizeof(my_buffer) ); 1572 if ( my_count == -1 ) { 1573 printf( "read from pipe failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1574 exit(-1); 1575 } 1576 1577 /* parent wrote (to our pipe) its pid as character string */ 1578 my_ppid = strtoul( &my_buffer[0], NULL, 10 ); 1579 if ( my_ppid == 0 ) { 1580 printf( "strtoul failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1581 exit(-1); 1582 } 1583 1584 if ( getppid( ) != my_ppid ) { 1585 printf( "getppid failed. pid we got from parent does not match getppid result. \n" ); 1586 exit(-1); 1587 } 1588 exit(0); 1589 } 1590 1591 /* parent process - get our pid using getpid and send it to child for verification */ 1592 close( my_fildes[0] ); /* close read end of pipe */ 1593 my_fildes[0] = -1; 1594 1595 sprintf( &my_pid_string[0], "%d\n", getpid( ) ); 1596 1597 my_count = write( my_fildes[1], &my_pid_string[0], sizeof(my_pid_string) ); 1598 if ( my_count == -1 ) { 1599 printf( "write to pipe failed. got errno %d - %s. \n", errno, strerror( errno ) ); 1600 goto test_failed_exit; 1601 } 1602 1603 /* wait for child to exit */ 1604 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 1605 if ( my_wait_pid == -1 ) { 1606 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 1607 goto test_failed_exit; 1608 } 1609 1610 /* wait4 should return our child's pid when it exits */ 1611 if ( my_wait_pid != my_pid ) { 1612 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid ); 1613 goto test_failed_exit; 1614 } 1615 1616 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 1617 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status ); 1618 goto test_failed_exit; 1619 } 1620 1621 my_err = 0; 1622 goto test_passed_exit; 1623 1624test_failed_exit: 1625 my_err = -1; 1626 1627test_passed_exit: 1628 if ( my_fildes[0] != -1 ) 1629 close( my_fildes[0] ); 1630 if ( my_fildes[1] != -1 ) 1631 close( my_fildes[1] ); 1632 return( my_err ); 1633} 1634 1635 1636/* ************************************************************************************************************** 1637 * Test getauid, gettid, getuid, geteuid, issetugid, setaudit_addr, seteuid, settid, settid_with_pid, setuid system calls. 1638 * ************************************************************************************************************** 1639 */ 1640int uid_tests( void * the_argp ) 1641{ 1642 int my_err, my_status; 1643 pid_t my_pid, my_wait_pid; 1644 1645 if ( g_skip_setuid_tests != 0 ) { 1646 printf("\t skipping this test \n"); 1647 my_err = 0; 1648 goto test_passed_exit; 1649 } 1650 1651 /* test issetugid - should return 1 when not root and 0 when root 1652 * Figuring out setugid will not work in single-user mode; skip 1653 * this test in that case. 1654 */ 1655 if (!g_is_single_user) { 1656 my_err = issetugid( ); 1657 if ( getuid( ) == 0 ) { 1658 if ( my_err == 1 ) { 1659 printf( "issetugid should return false \n" ); 1660 goto test_failed_exit; 1661 } 1662 } 1663 else { 1664 if ( my_err == 0 ) { 1665 printf( "issetugid should return true \n" ); 1666 goto test_failed_exit; 1667 } 1668 } 1669 } 1670 1671 /* 1672 * fork here and do the setuid work in the child 1673 */ 1674 my_pid = fork( ); 1675 if ( my_pid == -1 ) { 1676 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 1677 goto test_failed_exit; 1678 } 1679 else if ( my_pid == 0 ) { 1680 /* 1681 * child process 1682 */ 1683 uid_t my_ruid, my_euid; 1684 uid_t my_uid, my_temp_uid; 1685 gid_t my_gid, my_temp_gid; 1686 auditinfo_addr_t my_aia; 1687 1688 my_ruid = getuid( ); 1689 my_euid = geteuid( ); 1690 if ( my_ruid == my_euid ) { 1691 exit( 0 ); 1692 } 1693 1694 /* Test getauid, gettid, setaudit_addr, settid, settid_with_pid */ 1695 /* get our current uid and gid for comparison later */ 1696 my_uid = getuid( ); 1697 my_gid = getgid( ); 1698 1699 my_err = syscall( SYS_settid, 4444, 5555 ); 1700 //my_err = settid( 4444, 5555 ); 1701 if (my_err != 0) { 1702 printf( "settid call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1703 exit( -1 ); 1704 } 1705 1706 my_err = syscall( SYS_gettid, &my_temp_uid, &my_temp_gid ); 1707 //my_err = gettid( &my_temp_uid, &my_temp_gid ); 1708 if (my_err != 0) { 1709 printf( "gettid call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1710 exit( -1 ); 1711 } 1712 if (my_temp_uid != 4444) { 1713 printf("get / settid test failed - wrong uid was set - %d \n", my_temp_uid); 1714 exit( -1 ); 1715 } 1716 if (my_temp_gid != 5555) { 1717 printf("get / settid test failed - wrong gid was set - %d \n", my_temp_gid); 1718 exit( -1 ); 1719 } 1720 1721 /* resume original identity */ 1722 my_err = syscall( SYS_settid, KAUTH_UID_NONE, KAUTH_GID_NONE ); 1723 //my_err = settid( KAUTH_UID_NONE, KAUTH_GID_NONE ); 1724 if (my_err != 0) { 1725 printf( "settid revert - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1726 exit( -1 ); 1727 } 1728 1729 /* values should be returned to original settings */ 1730 my_temp_uid = getuid( ); 1731 if (my_temp_uid == 4444) { 1732 printf("test failed - wrong uid was set - %d \n", my_temp_uid); 1733 exit( -1 ); 1734 } 1735 my_temp_gid = getgid( ); 1736 if (my_temp_gid == 5555) { 1737 printf("test failed - wrong gid was set - %d \n", my_temp_gid); 1738 exit( -1 ); 1739 } 1740 1741 /* 1742 * Assume the identity of our parent. 1743 */ 1744 my_err = syscall( SYS_settid_with_pid, getppid( ), 1 ); 1745 //my_err = settid_with_pid, my_target_pid, 1 ); 1746 if (my_err != 0) { 1747 printf( "settid_with_pid assume - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1748 exit( -1 ); 1749 } 1750 1751 /* 1752 * Resume our identity. 1753 */ 1754 my_err = syscall( SYS_settid_with_pid, 0, 0 ); 1755 //my_err = settid_with_pid( my_target_pid, 0 ); 1756 if (my_err != 0) { 1757 printf( "settid_with_pid resume - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1758 exit( -1 ); 1759 } 1760 1761 /* 1762 * test to make sure setaudit_addr doesn't cause audit info to get lost from 1763 * the credential. 1764 */ 1765 bzero( &my_aia, sizeof(my_aia) ); 1766 my_aia.ai_auid = 442344; 1767 my_aia.ai_asid = AU_ASSIGN_ASID; 1768 my_aia.ai_termid.at_type = AU_IPv4; 1769 my_err = setaudit_addr( &my_aia, sizeof(my_aia) ); 1770 if (my_err != 0) { 1771 printf( "setaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1772 exit( -1 ); 1773 } 1774 1775 my_aia.ai_auid = 0; 1776 my_err = getaudit_addr( &my_aia, sizeof(my_aia) ); 1777 if (my_err != 0) { 1778 printf( "getaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1779 exit( -1 ); 1780 } 1781 //printf("new audit ID is %d \n", my_aia.ai_auid); 1782 1783 if (my_aia.ai_auid != 442344) { 1784 printf("test failed - wrong audit ID was set - %d \n", my_aia.ai_auid); 1785 exit( -1 ); 1786 } 1787 1788 /* change real uid and effective uid to current euid */ 1789 my_err = setuid( my_euid ); 1790 if ( my_err == -1 ) { 1791 printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1792 exit( -1 ); 1793 } 1794 if ( getuid( ) != my_euid ) { 1795 printf( "setuid call failed to set the real uid \n" ); 1796 exit( -1 ); 1797 } 1798 1799 /* change effective uid to current euid - really a NOP */ 1800 my_err = seteuid( my_euid ); 1801 if ( my_err == -1 ) { 1802 printf( "seteuid call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1803 exit( -1 ); 1804 } 1805 if ( geteuid( ) != my_euid ) { 1806 printf( "seteuid call failed to set the original euid \n" ); 1807 exit( -1 ); 1808 } 1809 1810 /* change real uid and effective uid to original real uid */ 1811 my_err = setuid( my_ruid ); 1812 if ( my_err == -1 ) { 1813 printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1814 exit( -1 ); 1815 } 1816 if ( getuid( ) != my_ruid ) { 1817 printf( "setuid call failed to set the real uid \n" ); 1818 exit( -1 ); 1819 } 1820 1821 exit(0); 1822 } 1823 1824 /* 1825 * parent process - 1826 * wait for child to exit 1827 */ 1828 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 1829 if ( my_wait_pid == -1 ) { 1830 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 1831 goto test_failed_exit; 1832 } 1833 1834 /* wait4 should return our child's pid when it exits */ 1835 if ( my_wait_pid != my_pid ) { 1836 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid ); 1837 goto test_failed_exit; 1838 } 1839 1840 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 1841 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status ); 1842 goto test_failed_exit; 1843 } 1844 1845 my_err = 0; 1846 goto test_passed_exit; 1847 1848test_failed_exit: 1849 my_err = -1; 1850 1851test_passed_exit: 1852 return( my_err ); 1853} 1854 1855/* ************************************************************************************************************** 1856 * Test mknod, sync system calls. 1857 * ************************************************************************************************************** 1858 */ 1859int mknod_sync_test( void * the_argp ) 1860{ 1861 int my_err; 1862 char * my_pathp = NULL; 1863 kern_return_t my_kr; 1864 1865 if ( g_skip_setuid_tests != 0 ) { 1866 printf("\t skipping this test \n"); 1867 my_err = 0; 1868 goto test_passed_exit; 1869 } 1870 1871 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 1872 if(my_kr != KERN_SUCCESS){ 1873 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1874 goto test_failed_exit; 1875 } 1876 1877 *my_pathp = 0x00; 1878 strcat( my_pathp, "/dev/" ); 1879 1880 /* get a unique name for our test file */ 1881 my_err = create_random_name( my_pathp, 0 ); 1882 if ( my_err != 0 ) { 1883 goto test_failed_exit; 1884 } 1885 1886 my_err = mknod( my_pathp, (S_IFCHR | S_IRWXU), 0 ); 1887 if ( my_err == -1 ) { 1888 printf( "mknod failed with errno %d - %s \n", errno, strerror( errno ) ); 1889 printf( "path \"%s\" \n", my_pathp ); 1890 goto test_failed_exit; 1891 } 1892 1893 /* not really sure what to do with sync call test */ 1894 sync( ); 1895 my_err = 0; 1896 goto test_passed_exit; 1897 1898test_failed_exit: 1899 my_err = -1; 1900 1901test_passed_exit: 1902 if ( my_pathp != NULL ) { 1903 remove( my_pathp ); 1904 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 1905 } 1906 return( my_err ); 1907} 1908 1909/* ************************************************************************************************************** 1910 * Test chflags, fchflags system calls. 1911 * ************************************************************************************************************** 1912 */ 1913int chflags_fchflags_test( void * the_argp ) 1914{ 1915 int my_err; 1916 int my_fd = -1; 1917 u_int my_flags; 1918 char * my_pathp = NULL; 1919 struct stat my_sb; 1920 kern_return_t my_kr; 1921 1922 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 1923 if(my_kr != KERN_SUCCESS){ 1924 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1925 goto test_failed_exit; 1926 } 1927 1928 *my_pathp = 0x00; 1929 strcat( my_pathp, &g_target_path[0] ); 1930 strcat( my_pathp, "/" ); 1931 1932 /* create a test file */ 1933 my_err = create_random_name( my_pathp, 1 ); 1934 if ( my_err != 0 ) { 1935 goto test_failed_exit; 1936 } 1937 1938 /* make test file unchangable */ 1939 my_err = stat( my_pathp, &my_sb ); 1940 if ( my_err != 0 ) { 1941 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1942 goto test_failed_exit; 1943 } 1944 1945 my_flags = (my_sb.st_flags | UF_IMMUTABLE); 1946 my_err = chflags( my_pathp, my_flags ); 1947 if ( my_err != 0 ) { 1948 printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1949 goto test_failed_exit; 1950 } 1951 1952 /* should fail with EPERM since we cannot change the file now */ 1953 my_fd = open( my_pathp, O_RDWR, 0 ); 1954 if ( my_fd == -1 && errno != EPERM ) { 1955 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1956 printf( "open failed with wrong error - should be EPERM \n" ); 1957 goto test_failed_exit; 1958 } 1959 1960 /* this open should work OK */ 1961 my_fd = open( my_pathp, O_RDONLY, 0 ); 1962 if ( my_fd == -1 ) { 1963 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1964 goto test_failed_exit; 1965 } 1966 1967 my_err = stat( my_pathp, &my_sb ); 1968 if ( my_err != 0 ) { 1969 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1970 goto test_failed_exit; 1971 } 1972 1973 my_flags = (my_sb.st_flags & ~UF_IMMUTABLE); 1974 my_err = fchflags( my_fd, my_flags ); 1975 if ( my_err != 0 ) { 1976 printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1977 goto test_failed_exit; 1978 } 1979 1980 close( my_fd ); 1981 my_fd = -1; 1982 1983 /* should now work */ 1984 my_fd = open( my_pathp, O_RDWR, 0 ); 1985 if ( my_fd == -1 ) { 1986 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1987 goto test_failed_exit; 1988 } 1989 1990 my_err = 0; 1991 goto test_passed_exit; 1992 1993test_failed_exit: 1994 my_err = -1; 1995 1996test_passed_exit: 1997 if ( my_fd != -1 ) 1998 close( my_fd ); 1999 if ( my_pathp != NULL ) { 2000 remove( my_pathp ); 2001 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 2002 } 2003 return( my_err ); 2004} 2005 2006 2007/* ************************************************************************************************************** 2008 * Test kill, vfork, execve system calls. 2009 * ************************************************************************************************************** 2010 */ 2011/* There are many new exec() situations to test now that 64-bit is in. These extra tests are in response to 2012 * rdar://4606399 and rdar://4607285. It should cover every permutation of the following variables. 2013 * 2014 * - Current Process "Bitness": 64 or 32 2015 * - exec()'ed process "bitness": 64 or 32 2016 * (if 64 bit, size of page zero:) (4GB or 4KB) 2017 * - Parent Process "Bitness": 64 or 32 2018 2019 * Test to make sure certain inheritance properties of fork()'ed children 2020 * are correctly set. 2021 * 1. 64 bit process forking() 64-bit child, child execing() 64-bit file (4GB pagezero) 2022 * 2. 64 bit process forking() 64-bit child, child execing() 64-bit file (4KB pagezero) 2023 * 3. 64 bit process forking() 64-bit child, child execing() 32-bit file 2024 * 4. 32 bit process forking() 32-bit child, child execing() 32-bit file 2025 * 5. 32 bit process forking() 32-bit child, child execing() 64 bit file (4GB pagezero) 2026 * 6. 32 bit process forking() 32-bit child, child execing() 64 bit file (4KB pagezero) 2027 * 2028 */ 2029 2030 2031int execve_kill_vfork_test( void * the_argp ) 2032{ 2033 int my_err, my_status; 2034 pid_t my_pid, my_wait_pid; 2035 char * errmsg = NULL; 2036 char * argvs[2] = {"", NULL}; 2037 int bits = get_bits(); /* Gets actual processor bit-ness. */ 2038 2039 if (bits != 32 && bits != 64) { 2040 printf("Determination of processor bit-ness failed, get_bits() returned %d.\n", get_bits()); 2041 return(-1); 2042 } 2043 2044 if (get_architecture() == -1) { 2045 errmsg = "get_architecture() could not determine the CPU architecture.\n"; 2046 goto test_failed_exit; 2047 } 2048 2049 if (get_architecture() == INTEL) { 2050 struct stat sb; 2051 2052 if (bits == 64 && sizeof(long) == 8) { 2053 /* 2054 * Running on x86_64 hardware and running in 64-bit mode. 2055 * Check cases 1, 2, 3 and fork a child to check 4, 5, 6. 2056 */ 2057 errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4G pagezero.\n"; 2058 argvs[0] = "sleep-x86_64-4G"; 2059 if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 1)) goto test_failed_exit; 2060 2061 errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4K Pagezero.\n"; 2062 argvs[0] = "sleep-x86_64-4K"; 2063 if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 1)) goto test_failed_exit; 2064 2065 errmsg = "execve failed: from x64_64 forking and exec()ing 32-bit i386 process.\n"; 2066 argvs[0] = "sleep-i386"; 2067 if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1)) goto test_failed_exit; 2068 2069 /* Fork off a helper process and load a 32-bit program in it to test 32->64 bit exec(). */ 2070 errmsg = "execve failed to exec the helper process.\n"; 2071 argvs[0] = "launch-i386"; 2072 if (do_execve_test("helpers/launch-i386", argvs, NULL, 1) != 0) goto test_failed_exit; 2073 2074 /* Test posix_spawn for i386, x86_64 (should succeed) */ 2075 errmsg = NULL; 2076 if (do_spawn_test(CPU_TYPE_I386, 0)) 2077 goto test_failed_exit; 2078 if (do_spawn_test(CPU_TYPE_X86_64, 0)) 2079 goto test_failed_exit; 2080 } 2081 else if (bits == 64 && sizeof(long) == 4) { 2082 /* 2083 * Running on x86_64 hardware, but actually running in 32-bit mode. 2084 * Check cases 4, 5, 6 and fork a child to check 1, 2, 3. 2085 */ 2086 errmsg = "execve failed: from i386 forking and exec()ing i386 process.\n"; 2087 argvs[0] = "sleep-i386"; 2088 if (do_execve_test("helpers/sleep-i386", argvs, NULL, 0)) goto test_failed_exit; 2089 2090 errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4G pagezero.\n"; 2091 argvs[0] = "sleep-x86_64-4G"; 2092 if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 0)) goto test_failed_exit; 2093 2094 errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4K pagezero.\n"; 2095 argvs[0] = "sleep-x86_64-4K"; 2096 if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 0)) goto test_failed_exit; 2097 2098 /* Fork off a helper process and load a 64-bit program in it to test 64->32 bit exec(). */ 2099 errmsg = "execve failed to exec the helper process.\n"; 2100 argvs[0] = "launch-x86_64"; 2101 if (do_execve_test("helpers/launch-x86_64", argvs, NULL, 1) != 0) goto test_failed_exit; 2102 2103 /* Test posix_spawn for i386, x86_64 (should succeed) */ 2104 errmsg = NULL; 2105 if (do_spawn_test(CPU_TYPE_I386, 0)) 2106 goto test_failed_exit; 2107 if (do_spawn_test(CPU_TYPE_X86_64, 0)) 2108 goto test_failed_exit; 2109 } 2110 else if (bits == 32) { 2111 /* Running on i386 hardware. Check cases 4. */ 2112 errmsg = "execve failed: from i386 forking and exec()ing 32-bit i386 process.\n"; 2113 argvs[0] = "sleep-i386"; 2114 if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1)) goto test_failed_exit; 2115 2116 /* Test posix_spawn for x86_64 (should fail), i386 (should succeed) */ 2117 errmsg = NULL; 2118 if (do_spawn_test(CPU_TYPE_X86_64, 1)) 2119 goto test_failed_exit; 2120 if (do_spawn_test(CPU_TYPE_I386, 0)) 2121 goto test_failed_exit; 2122 } 2123 }else if(get_architecture() == ARM) { 2124 if (bits == 32) { 2125 2126 /* Running on arm hardware. Check cases 2. */ 2127 errmsg = "execve failed: from arm forking and exec()ing 32-bit arm process.\n"; 2128 argvs[0] = "sleep-arm"; 2129 if (do_execve_test("helpers/sleep-arm", argvs, NULL, 1)) 2130 goto test_failed_exit; 2131 2132 /* Test posix_spawn for arm (should succeed) */ 2133 errmsg = NULL; 2134 if (do_spawn_test(CPU_TYPE_ARM, 0)) 2135 goto test_failed_exit; 2136 } 2137 } 2138 else { 2139 /* Just in case someone decides we need more architectures in the future */ 2140 printf("get_architecture() returned unknown architecture"); 2141 return(-1); 2142 } 2143 2144 return 0; 2145 2146test_failed_exit: 2147 if (errmsg) 2148 printf("%s", errmsg); 2149 return -1; 2150} 2151 2152 2153/* ************************************************************************************************************** 2154 * Test getegid, getgid, getgroups, setegid, setgid, setgroups system calls. 2155 * ************************************************************************************************************** 2156 */ 2157int groups_test( void * the_argp ) 2158{ 2159#if !TARGET_OS_EMBEDDED 2160 int my_err, i; 2161 int my_group_count, my_orig_group_count; 2162 gid_t my_real_gid; 2163 gid_t my_effective_gid; 2164 gid_t my_removed_gid; 2165 gid_t my_new_gid; 2166 gid_t my_groups[ NGROUPS_MAX ]; 2167 2168 if ( g_skip_setuid_tests != 0 ) { 2169 printf("\t skipping this test \n"); 2170 my_err = 0; 2171 goto test_passed_exit; 2172 } 2173 2174 my_real_gid = getgid( ); 2175 my_effective_gid = getegid( ); 2176 2177 if ( !_prime_groups() ) { 2178 goto test_failed_exit; 2179 } 2180 2181 /* start by getting list of groups the current user belongs to */ 2182 my_orig_group_count = getgroups( NGROUPS_MAX, &my_groups[0] ); 2183 2184 if ( my_orig_group_count == -1 || my_orig_group_count < 1 ) { 2185 printf( "getgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2186 goto test_failed_exit; 2187 } 2188 2189 /* make sure real and effective gids are correct */ 2190 for ( i = 0; i < my_orig_group_count; i++ ) { 2191 if ( my_groups[i] == my_real_gid ) 2192 break; 2193 } 2194 if ( i >= my_orig_group_count ) { 2195 printf( "getgid or getgroups call failed. could not find real gid in list of groups. \n" ); 2196 goto test_failed_exit; 2197 } 2198 for ( i = 0; i < my_orig_group_count; i++ ) { 2199 if ( my_groups[i] == my_effective_gid ) 2200 break; 2201 } 2202 if ( i >= my_orig_group_count ) { 2203 printf( "getegid or getgroups call failed. could not find effective gid in list of groups. \n" ); 2204 goto test_failed_exit; 2205 } 2206 2207 /* remove the last group */ 2208 my_removed_gid = my_groups[ (my_orig_group_count - 1) ]; 2209 my_err = setgroups( (my_orig_group_count - 1), &my_groups[0] ); 2210 if ( my_err == -1 ) { 2211 printf( "setgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2212 goto test_failed_exit; 2213 } 2214 2215 my_group_count = getgroups( NGROUPS_MAX, &my_groups[0] ); 2216 2217 if ( my_group_count == -1 || my_group_count < 1 ) { 2218 printf( "getgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2219 goto test_failed_exit; 2220 } 2221 2222 /* make sure setgroups dropped one */ 2223 if ( my_orig_group_count <= my_group_count ) { 2224 printf( "setgroups call failed. current group count is too high. \n" ); 2225 goto test_failed_exit; 2226 } 2227 2228 /* now put removed gid back */ 2229 my_groups[ (my_orig_group_count - 1) ] = my_removed_gid; 2230 my_err = setgroups( my_orig_group_count, &my_groups[0] ); 2231 if ( my_err == -1 ) { 2232 printf( "setgroups call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2233 goto test_failed_exit; 2234 } 2235 2236 /* find a group to change real and effective gid to then do it */ 2237 my_new_gid = -1; 2238 for ( i = 0; i < my_orig_group_count; i++ ) { 2239 if ( my_groups[i] == my_effective_gid || my_groups[i] == my_real_gid ) 2240 continue; 2241 my_new_gid = my_groups[i]; 2242 } 2243 2244 if ( my_new_gid == -1 ) { 2245 printf( "could not find a gid to switch to. \n" ); 2246 goto test_failed_exit; 2247 } 2248 2249 /* test setegid */ 2250 my_err = setegid( my_new_gid ); 2251 if ( my_err == -1 ) { 2252 printf( "setegid call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2253 goto test_failed_exit; 2254 } 2255 /* verify it changed */ 2256 if ( getegid( ) != my_new_gid ) { 2257 printf( "setegid failed to change the effective gid. \n" ); 2258 goto test_failed_exit; 2259 } 2260 /* change it back to original value */ 2261 my_err = setegid( my_effective_gid ); 2262 if ( my_err == -1 ) { 2263 printf( "setegid call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2264 goto test_failed_exit; 2265 } 2266 2267 /* test setgid */ 2268 my_err = setgid( my_new_gid ); 2269 if ( my_err == -1 ) { 2270 printf( "setgid call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2271 goto test_failed_exit; 2272 } 2273 /* verify it changed */ 2274 if ( getgid( ) != my_new_gid ) { 2275 printf( "setgid failed to change the real gid. \n" ); 2276 goto test_failed_exit; 2277 } 2278 /* change it back to original value */ 2279 my_err = setgid( my_real_gid ); 2280 if ( my_err == -1 ) { 2281 printf( "setegid call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2282 goto test_failed_exit; 2283 } 2284 2285 my_err = 0; 2286 goto test_passed_exit; 2287 2288test_failed_exit: 2289 my_err = -1; 2290 2291test_passed_exit: 2292 return( my_err ); 2293#else 2294 printf( "\t--> Test not designed for EMBEDDED TARGET\n" ); 2295 return 0; 2296#endif 2297} 2298 2299 2300/* ************************************************************************************************************** 2301 * Test dup, dup2, getdtablesize system calls. 2302 * ************************************************************************************************************** 2303 */ 2304int dup_test( void * the_argp ) 2305{ 2306 int my_err; 2307 int my_fd = -1; 2308 int my_newfd = -1; 2309 int my_table_size, my_loop_counter = 0; 2310 char * my_pathp = NULL; 2311 ssize_t my_count; 2312 char my_buffer[64]; 2313 kern_return_t my_kr; 2314 2315 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 2316 if(my_kr != KERN_SUCCESS){ 2317 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2318 goto test_failed_exit; 2319 } 2320 2321 *my_pathp = 0x00; 2322 strcat( my_pathp, &g_target_path[0] ); 2323 strcat( my_pathp, "/" ); 2324 2325 /* create a test file */ 2326 my_err = create_random_name( my_pathp, 1 ); 2327 if ( my_err != 0 ) { 2328 goto test_failed_exit; 2329 } 2330 2331 /* test dup, dup2, getdtablesize */ 2332 my_table_size = getdtablesize( ); 2333 if ( my_table_size < 20 ) { 2334 printf( "getdtablesize should return at least 20, returned %d \n", my_table_size ); 2335 goto test_failed_exit; 2336 } 2337 2338 my_fd = open( my_pathp, O_RDWR, 0 ); 2339 if ( my_fd == -1 ) { 2340 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2341 goto test_failed_exit; 2342 } 2343 2344 my_newfd = dup( my_fd ); 2345 if ( my_newfd == -1 ) { 2346 printf( "dup call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2347 goto test_failed_exit; 2348 } 2349 2350redo: 2351 /* now write somne data to the orginal and new fd */ 2352 /* make sure test file is empty */ 2353 my_err = ftruncate( my_fd, 0 ); 2354 if ( my_err == -1 ) { 2355 printf( "ftruncate call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2356 goto test_failed_exit; 2357 } 2358 2359 lseek( my_fd, 0, SEEK_SET ); 2360 my_count = write( my_fd, "aa", 2 ); 2361 if ( my_count == -1 ) { 2362 printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2363 goto test_failed_exit; 2364 } 2365 2366 my_count = write( my_newfd, "xx", 2 ); 2367 if ( my_count == -1 ) { 2368 printf( "write call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 2369 goto test_failed_exit; 2370 } 2371 2372 /* now read it back and make sure data is correct */ 2373 lseek( my_fd, 0, SEEK_SET ); 2374 my_count = read( my_fd, &my_buffer[0], sizeof(my_buffer) ); 2375 if ( my_count == -1 ) { 2376 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2377 goto test_failed_exit; 2378 } 2379 if ( my_buffer[0] != 'a' || my_buffer[1] != 'a' || my_buffer[2] != 'x' || my_buffer[3] != 'x' ) { 2380 printf( "wrong data in test file. \n" ); 2381 goto test_failed_exit; 2382 } 2383 2384 bzero( &my_buffer[0], sizeof(my_buffer) ); 2385 lseek( my_newfd, 0, SEEK_SET ); 2386 my_count = read( my_newfd, &my_buffer[0], sizeof(my_buffer) ); 2387 if ( my_count == -1 ) { 2388 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2389 goto test_failed_exit; 2390 } 2391 if ( my_buffer[0] != 'a' || my_buffer[1] != 'a' || my_buffer[2] != 'x' || my_buffer[3] != 'x' ) { 2392 printf( "wrong data in test file. \n" ); 2393 goto test_failed_exit; 2394 } 2395 2396 /* we do the above tests twice - once for dup and once for dup2 */ 2397 if ( my_loop_counter < 1 ) { 2398 my_loop_counter++; 2399 close( my_newfd ); 2400 2401 my_err = dup2( my_fd, my_newfd ); 2402 if ( my_err == -1 ) { 2403 printf( "dup2 call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2404 goto test_failed_exit; 2405 } 2406 2407 goto redo; 2408 } 2409 2410 my_err = 0; 2411 goto test_passed_exit; 2412 2413test_failed_exit: 2414 my_err = -1; 2415 2416test_passed_exit: 2417 if ( my_fd != -1 ) 2418 close( my_fd ); 2419 if ( my_newfd != -1 ) 2420 close( my_newfd ); 2421 if ( my_pathp != NULL ) { 2422 remove( my_pathp ); 2423 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 2424 } 2425 return( my_err ); 2426} 2427 2428 2429/* ************************************************************************************************************** 2430 * Test getrusage system call. 2431 * ************************************************************************************************************** 2432 */ 2433int getrusage_test( void * the_argp ) 2434{ 2435 int my_err; 2436 struct rusage my_rusage; 2437 2438 my_err = getrusage( RUSAGE_SELF, &my_rusage ); 2439 if ( my_err == -1 ) { 2440 printf( "getrusage failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2441 goto test_failed_exit; 2442 } 2443 2444 /* do a sanity check on the getrusage results */ 2445 if ( my_rusage.ru_msgrcv > 1000 || my_rusage.ru_msgrcv < 0 ) { 2446 printf( "getrusage seems to report wrong data - ru_msgrcv looks odd. \n" ); 2447 goto test_failed_exit; 2448 } 2449 if ( my_rusage.ru_nsignals > 1000 || my_rusage.ru_nsignals < 0 ) { 2450 printf( "getrusage seems to report wrong data - ru_nsignals looks odd. \n" ); 2451 goto test_failed_exit; 2452 } 2453 2454 my_err = 0; 2455 goto test_passed_exit; 2456 2457test_failed_exit: 2458 my_err = -1; 2459 2460test_passed_exit: 2461 return( my_err ); 2462} 2463 2464/* ************************************************************************************************************** 2465 * Test getitimer, setitimer, sigaction, sigpending, sigprocmask, sigsuspend, sigwait system calls. 2466 * ************************************************************************************************************** 2467 */ 2468 2469int alarm_global = 0; 2470void test_alarm_handler( int the_arg ); 2471void test_alarm_handler( int the_arg ) 2472{ 2473 alarm_global = 4; 2474 //printf( "test_alarm_handler - got here \n" ); 2475 if ( the_arg == 0 ) { 2476 } 2477 return; 2478} 2479 2480void test_signal_handler( int the_arg ); 2481void test_signal_handler( int the_arg ) 2482{ 2483 //printf( "test_signal_handler - got here \n" ); 2484 if ( the_arg == 0 ) { 2485 } 2486 return; 2487} 2488 2489int signals_test( void * the_argp ) 2490{ 2491 int my_err, my_status; 2492 int my_fd = -1; 2493 char * my_pathp = NULL; 2494 pid_t my_pid, my_wait_pid; 2495 kern_return_t my_kr; 2496 2497 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 2498 if(my_kr != KERN_SUCCESS){ 2499 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2500 goto test_failed_exit; 2501 } 2502 2503 *my_pathp = 0x00; 2504 strcat( my_pathp, &g_target_path[0] ); 2505 strcat( my_pathp, "/" ); 2506 2507 /* create a test file */ 2508 my_err = create_random_name( my_pathp, 1 ); 2509 if ( my_err != 0 ) { 2510 goto test_failed_exit; 2511 } 2512 2513 /* 2514 * spin off a child process that we will use for signal related testing. 2515 */ 2516 my_pid = fork( ); 2517 if ( my_pid == -1 ) { 2518 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 2519 goto test_failed_exit; 2520 } 2521 if ( my_pid == 0 ) { 2522 /* 2523 * child process - test signal related system calls. 2524 */ 2525 //int my_counter; 2526 int my_signal; 2527 sigset_t my_sigset; 2528 struct sigaction my_sigaction; 2529#ifdef MAC_OS_X_VERSION_10_5 2530#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 2531 /* If this is Leopard. To allow compiling for Inca x86_64 this definition cannot 2532 * be included. But it is needed to compile on Leopard. 2533 */ 2534 struct __darwin_sigaltstack my_sigaltstack; 2535#endif 2536#else 2537 struct sigaltstack my_sigaltstack; 2538#endif 2539 struct itimerval my_timer; 2540 2541 2542 /* test getting the current signal stack context */ 2543 my_err = sigaltstack( NULL, &my_sigaltstack ); 2544 if ( my_err == -1 ) { 2545 printf( "sigaction failed with errno %d - %s \n", errno, strerror( errno ) ); 2546 exit( -1 ); 2547 } 2548 if ( (my_sigaltstack.ss_flags & SS_DISABLE) == 0 ) { 2549 printf( "sigaction must have failed - SS_DISABLE is cleared \n" ); 2550 exit( -1 ); 2551 } 2552 2553 /* set up to catch SIGUSR1 */ 2554 my_sigaction.sa_handler = test_signal_handler; 2555 my_sigaction.sa_flags = SA_RESTART; 2556 my_sigaction.sa_mask = 0; 2557 2558 my_err = sigaction( SIGUSR1, &my_sigaction, NULL ); 2559 if ( my_err == -1 ) { 2560 printf( "sigaction failed with errno %d - %s \n", errno, strerror( errno ) ); 2561 exit( -1 ); 2562 } 2563 2564 /* now suspend until signal SIGUSR1 is sent */ 2565 sigemptyset( &my_sigset ); 2566 my_err = sigsuspend( &my_sigset ); 2567 if ( my_err == -1 ) { 2568 if ( errno != EINTR ) { 2569 printf( "sigsuspend should have returned with errno EINTR \n" ); 2570 exit( -1 ); 2571 } 2572 } 2573 2574 /* block SIGUSR1 */ 2575 sigemptyset( &my_sigset ); 2576 sigaddset( &my_sigset, SIGUSR1 ); 2577 if ( sigismember( &my_sigset, SIGUSR1 ) == 0 ) { 2578 printf( "sigaddset call failed to add SIGUSR1 to signal set \n" ); 2579 exit( -1 ); 2580 } 2581 my_err = sigprocmask( SIG_BLOCK, &my_sigset, NULL ); 2582 if ( my_err == -1 ) { 2583 printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) ); 2584 exit( -1 ); 2585 } 2586 2587 /* make sure we are blocking SIGUSR1 */ 2588 sigemptyset( &my_sigset ); 2589 my_err = sigprocmask( 0, NULL, &my_sigset ); 2590 if ( my_err == -1 ) { 2591 printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) ); 2592 exit( -1 ); 2593 } 2594 if ( sigismember( &my_sigset, SIGUSR1 ) == 0 ) { 2595 printf( "sigaddset call failed to add SIGUSR1 to signal set \n" ); 2596 exit( -1 ); 2597 } 2598 2599 /* our parent will send a 2nd SIGUSR1 signal which we should now see getting 2600 * blocked. 2601 */ 2602 sigemptyset( &my_sigset ); 2603 sigaddset( &my_sigset, SIGUSR1 ); 2604 my_err = sigwait( &my_sigset, &my_signal ); 2605 if ( my_err == -1 ) { 2606 printf( "sigwait failed with errno %d - %s \n", errno, strerror( errno ) ); 2607 exit( -1 ); 2608 } 2609 //printf( "%s - %d - signal 0x%02X %d \n", __FUNCTION__, __LINE__, my_signal, my_signal ); 2610 if ( my_signal != SIGUSR1 ) { 2611 printf( "sigwait failed to catch a pending SIGUSR1 signal. \n" ); 2612 exit( -1 ); 2613 } 2614 2615 /* now unblock SIGUSR1 */ 2616 sigfillset( &my_sigset ); 2617 sigdelset( &my_sigset, SIGUSR1 ); 2618 my_err = sigprocmask( SIG_UNBLOCK, &my_sigset, NULL ); 2619 if ( my_err == -1 ) { 2620 printf( "sigprocmask failed with errno %d - %s \n", errno, strerror( errno ) ); 2621 exit( -1 ); 2622 } 2623 if ( sigismember( &my_sigset, SIGUSR1 ) != 0 ) { 2624 printf( "sigprocmask call failed to unblock SIGUSR1 \n" ); 2625 exit( -1 ); 2626 } 2627 2628 /* test get / setitimer */ 2629 timerclear( &my_timer.it_interval ); 2630 timerclear( &my_timer.it_value ); 2631 my_err = setitimer( ITIMER_VIRTUAL, &my_timer, NULL ); 2632 if ( my_err == -1 ) { 2633 printf( "setitimer - ITIMER_VIRTUAL - failed with errno %d - %s \n", errno, strerror( errno ) ); 2634 exit( -1 ); 2635 } 2636 my_err = setitimer( ITIMER_PROF, &my_timer, NULL ); 2637 if ( my_err == -1 ) { 2638 printf( "setitimer - ITIMER_PROF - failed with errno %d - %s \n", errno, strerror( errno ) ); 2639 exit( -1 ); 2640 } 2641 2642 /* set up to catch SIGALRM */ 2643 alarm_global = 0; 2644 my_sigaction.sa_handler = test_alarm_handler; 2645 my_sigaction.sa_flags = SA_RESTART; 2646 my_sigaction.sa_mask = 0; 2647 2648 my_err = sigaction( SIGALRM, &my_sigaction, NULL ); 2649 if ( my_err == -1 ) { 2650 printf( "sigaction - SIGALRM - failed with errno %d - %s \n", errno, strerror( errno ) ); 2651 exit( -1 ); 2652 } 2653 2654 /* set timer for half a second */ 2655 my_timer.it_value.tv_usec = (1000000 / 2); 2656 my_err = setitimer( ITIMER_REAL, &my_timer, NULL ); 2657 if ( my_err == -1 ) { 2658 printf( "setitimer - ITIMER_REAL - failed with errno %d - %s \n", errno, strerror( errno ) ); 2659 exit( -1 ); 2660 } 2661 2662 /* now suspend until signal SIGALRM is sent */ 2663 sigfillset( &my_sigset ); 2664 sigdelset( &my_sigset, SIGALRM ); 2665 my_err = sigsuspend( &my_sigset ); 2666 if ( my_err == -1 ) { 2667 if ( errno != EINTR ) { 2668 printf( "sigsuspend should have returned with errno EINTR \n" ); 2669 exit( -1 ); 2670 } 2671 } 2672 if ( alarm_global != 4 ) { 2673 printf( "setitimer test failed - did not catch SIGALRM \n" ); 2674 exit( -1 ); 2675 } 2676 2677 /* make sure ITIMER_REAL is now clear */ 2678 my_timer.it_value.tv_sec = 44; 2679 my_timer.it_value.tv_usec = 44; 2680 my_err = getitimer( ITIMER_REAL, &my_timer ); 2681 if ( my_err == -1 ) { 2682 printf( "getitimer - ITIMER_REAL - failed with errno %d - %s \n", errno, strerror( errno ) ); 2683 exit( -1 ); 2684 } 2685 if ( timerisset( &my_timer.it_value ) || timerisset( &my_timer.it_interval ) ) { 2686 printf( "ITIMER_REAL is set, but should not be \n" ); 2687 exit( -1 ); 2688 } 2689 2690 exit(0); 2691 } 2692 2693 /* 2694 * parent process - let child set up to suspend then signal it with SIGUSR1 2695 */ 2696 sleep( 1 ); 2697 my_err = kill( my_pid, SIGUSR1 ); 2698 if ( my_err == -1 ) { 2699 printf( "kill call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2700 goto test_failed_exit; 2701 } 2702 2703 /* send 2nd signal to suspended child - which should be blocking SIGUSR1 signals */ 2704 sleep( 1 ); 2705 my_err = kill( my_pid, SIGUSR1 ); 2706 if ( my_err == -1 ) { 2707 printf( "kill call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2708 goto test_failed_exit; 2709 } 2710 2711 /* wait for child to exit */ 2712 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 2713 if ( my_wait_pid == -1 ) { 2714 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 2715 goto test_failed_exit; 2716 } 2717 2718 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 2719 goto test_failed_exit; 2720 } 2721 2722 my_err = 0; 2723 goto test_passed_exit; 2724 2725test_failed_exit: 2726 my_err = -1; 2727 2728test_passed_exit: 2729 if ( my_fd != -1 ) 2730 close( my_fd ); 2731 if ( my_pathp != NULL ) { 2732 remove( my_pathp ); 2733 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 2734 } 2735 return( my_err ); 2736} 2737 2738/* ************************************************************************************************************** 2739 * Test getlogin, setlogin system calls. 2740 * ************************************************************************************************************** 2741 */ 2742int getlogin_setlogin_test( void * the_argp ) 2743{ 2744 int my_err, my_status; 2745 pid_t my_pid, my_wait_pid; 2746 kern_return_t my_kr; 2747 2748 if ( g_skip_setuid_tests != 0 ) { 2749 printf("\t skipping this test \n"); 2750 my_err = 0; 2751 goto test_passed_exit; 2752 } 2753 2754 /* 2755 * spin off a child process that we will use for testing. 2756 */ 2757 my_pid = fork( ); 2758 if ( my_pid == -1 ) { 2759 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 2760 goto test_failed_exit; 2761 } 2762 if ( my_pid == 0 ) { 2763 /* 2764 * child process - do getlogin and setlogin testing. 2765 */ 2766 char * my_namep = NULL; 2767 int my_len; 2768 char * my_new_namep = NULL; 2769 2770 my_namep = getlogin( ); 2771 if ( my_namep == NULL ) { 2772 printf( "getlogin returned NULL name pointer \n" ); 2773 my_err = -1; 2774 goto exit_child; 2775 } 2776 2777 my_len = strlen( my_namep ) + 4; 2778 2779 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_namep, my_len, VM_FLAGS_ANYWHERE); 2780 if(my_kr != KERN_SUCCESS){ 2781 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2782 my_err = -1; 2783 goto exit_child; 2784 } 2785 2786 bzero( (void *)my_new_namep, my_len ); 2787 2788 strcat( my_new_namep, my_namep ); 2789 strcat( my_new_namep, "2" ); 2790 2791 2792 /* set new name */ 2793 my_err = setlogin( my_new_namep ); 2794 if ( my_err == -1 ) { 2795 printf( "When setting new login name, setlogin failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2796 my_err = -1; 2797 goto exit_child; 2798 } 2799 2800 /* make sure we set new name */ 2801 my_namep = getlogin( ); 2802 if ( my_namep == NULL ) { 2803 printf( "getlogin returned NULL name pointer \n" ); 2804 my_err = -1; 2805 goto exit_child; 2806 } 2807 2808 if ( memcmp( my_namep, my_new_namep, strlen( my_new_namep ) ) != 0 ) { 2809 printf( "setlogin failed to set the new name \n" ); 2810 my_err = -1; 2811 goto exit_child; 2812 } 2813 2814 /* reset to original name */ 2815 my_len = strlen ( my_namep ); 2816 my_namep[ my_len - 1 ] = '\0'; 2817 2818 my_err = setlogin( my_namep ); 2819 if ( my_err == -1 ) { 2820 printf( "When resetting login name, setlogin failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2821 my_err = -1; 2822 goto exit_child; 2823 } 2824 2825 2826 my_err = 0; 2827exit_child: 2828 if ( my_new_namep != NULL ) { 2829 vm_deallocate(mach_task_self(), (vm_address_t)my_new_namep, my_len); 2830 } 2831 exit( my_err ); 2832 } 2833 2834 /* parent process - 2835 * wait for child to exit 2836 */ 2837 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 2838 if ( my_wait_pid == -1 ) { 2839 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 2840 goto test_failed_exit; 2841 } 2842 2843 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 2844 goto test_failed_exit; 2845 } 2846 my_err = 0; 2847 goto test_passed_exit; 2848 2849test_failed_exit: 2850 my_err = -1; 2851 2852test_passed_exit: 2853 return( my_err ); 2854} 2855 2856/* ************************************************************************************************************** 2857 * Test acct system call. 2858 * ************************************************************************************************************** 2859 */ 2860int acct_test( void * the_argp ) 2861{ 2862 int my_err, my_status; 2863 int my_fd = -1; 2864 char * my_pathp = NULL; 2865 struct acct * my_acctp; 2866 pid_t my_pid, my_wait_pid; 2867 ssize_t my_count; 2868 char my_buffer[ (sizeof(struct acct) + 32) ]; 2869 kern_return_t my_kr; 2870 2871 if ( g_skip_setuid_tests != 0 ) { 2872 printf("\t skipping this test \n"); 2873 my_err = 0; 2874 goto test_passed_exit; 2875 } 2876 2877 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 2878 if(my_kr != KERN_SUCCESS){ 2879 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2880 goto test_failed_exit; 2881 } 2882 2883 *my_pathp = 0x00; 2884 strcat( my_pathp, &g_target_path[0] ); 2885 strcat( my_pathp, "/" ); 2886 2887 /* create a test file */ 2888 my_err = create_random_name( my_pathp, 1 ); 2889 if ( my_err != 0 ) { 2890 goto test_failed_exit; 2891 } 2892 2893 /* enable process accounting */ 2894 my_err = acct( my_pathp ); 2895 if ( my_err == -1 ) { 2896 printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2897 goto test_failed_exit; 2898 } 2899 2900 /* 2901 * spin off a child process that we will use for testing. 2902 */ 2903 my_pid = fork( ); 2904 if ( my_pid == -1 ) { 2905 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 2906 goto test_failed_exit; 2907 } 2908 if ( my_pid == 0 ) { 2909 char *argv[2]; /* supply valid argv array to execv() */ 2910 argv[0] = "/usr/bin/true"; 2911 argv[1] = 0; 2912 2913 /* 2914 * child process - do a little work then exit. 2915 */ 2916 my_err = execv( argv[0], argv); 2917 exit( 0 ); 2918 } 2919 2920 /* parent process - 2921 * wait for child to exit 2922 */ 2923 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 2924 if ( my_wait_pid == -1 ) { 2925 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 2926 goto test_failed_exit; 2927 } 2928 2929 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 2930 printf("unexpected child exit status for accounting test load: %d\n", WEXITSTATUS( my_status)); 2931 goto test_failed_exit; 2932 } 2933 2934 /* disable process accounting */ 2935 my_err = acct( NULL ); 2936 if ( my_err == -1 ) { 2937 printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2938 goto test_failed_exit; 2939 } 2940 2941 /* now verify that there is accounting info in the log file */ 2942 my_fd = open( my_pathp, O_RDONLY, 0 ); 2943 if ( my_fd == -1 ) { 2944 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2945 goto test_failed_exit; 2946 } 2947 2948 lseek( my_fd, 0, SEEK_SET ); 2949 bzero( (void *)&my_buffer[0], sizeof(my_buffer) ); 2950 my_count = read( my_fd, &my_buffer[0], sizeof(struct acct) ); 2951 if ( my_count == -1 ) { 2952 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2953 goto test_failed_exit; 2954 } 2955 2956 my_acctp = (struct acct *) &my_buffer[0]; 2957 2958 /* first letters in ac_comm should match the name of the executable */ 2959 if ( getuid( ) != my_acctp->ac_uid || getgid( ) != my_acctp->ac_gid || 2960 my_acctp->ac_comm[0] != 't' || my_acctp->ac_comm[1] != 'r' ) { 2961 printf( "------------------------\n" ); 2962 printf( "my_acctp->ac_uid = %lu (should be: %lu)\n", (unsigned long) my_acctp->ac_uid, (unsigned long) getuid() ); 2963 printf( "my_acctp->ac_gid = %lu (should be: %lu)\n", (unsigned long) my_acctp->ac_gid, (unsigned long) getgid() ); 2964 2965 print_acct_debug_strings(my_acctp->ac_comm); 2966 2967 goto test_failed_exit; 2968 } 2969 my_err = 0; 2970 goto test_passed_exit; 2971 2972test_failed_exit: 2973 my_err = -1; 2974 2975test_passed_exit: 2976 if ( my_fd != -1 ) 2977 close( my_fd ); 2978 if ( my_pathp != NULL ) { 2979 remove( my_pathp ); 2980 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 2981 } 2982 return( my_err ); 2983} 2984 2985void print_acct_debug_strings( char * my_ac_comm ) 2986{ 2987 char my_cmd_str[11]; /* sizeof(acct_cmd) + 1 for '\0' if acct_cmd is bogus */ 2988 char my_hex_str[128]; 2989 int i; 2990 2991 my_hex_str[0] = '\0'; 2992 for(i = 0; i < 10; i++) 2993 { 2994 sprintf( my_hex_str, "%s \'0x%x\' ", my_hex_str, my_ac_comm[i]); 2995 } 2996 2997 memccpy(my_cmd_str, my_ac_comm, '\0', 10); 2998 my_cmd_str[10] = '\0'; /* In case ac_comm was bogus */ 2999 3000 3001 printf( "my_acctp->ac_comm = \"%s\" (should begin with: \"tr\")\n", my_cmd_str); 3002 printf( "my_acctp->ac_comm = \"%s\"\n", my_hex_str); 3003 printf( "------------------------\n" ); 3004} 3005 3006 3007/* ************************************************************************************************************** 3008 * Test ioctl system calls. 3009 * ************************************************************************************************************** 3010 */ 3011int ioctl_test( void * the_argp ) 3012{ 3013 int my_err, my_result; 3014 int my_fd = -1; 3015 struct statfs * my_infop; 3016 char * my_ptr; 3017 int my_blksize; 3018 long long my_block_count; 3019 char my_name[ 128 ]; 3020 3021 my_result = getmntinfo( &my_infop, MNT_NOWAIT ); 3022 if ( my_result < 1 ) { 3023 printf( "getmntinfo failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3024 goto test_failed_exit; 3025 } 3026 3027 /* make this a raw device */ 3028 strcpy( &my_name[0], &my_infop->f_mntfromname[0] ); 3029 if ( (my_ptr = strrchr( &my_name[0], '/' )) != 0 ) { 3030 if ( my_ptr[1] != 'r' ) { 3031 my_ptr[ strlen( my_ptr ) ] = 0x00; 3032 memmove( &my_ptr[2], &my_ptr[1], (strlen( &my_ptr[1] ) + 1) ); 3033 my_ptr[1] = 'r'; 3034 } 3035 } 3036 3037 my_fd = open(&my_name[0], O_RDONLY ); 3038 if ( my_fd == -1 ) { 3039 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3040 goto test_failed_exit; 3041 } 3042 3043 /* obtain the size of the media (in blocks) */ 3044 my_err = ioctl( my_fd, DKIOCGETBLOCKCOUNT, &my_block_count ); 3045 if ( my_err == -1 ) { 3046 printf( "ioctl DKIOCGETBLOCKCOUNT failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3047 goto test_failed_exit; 3048 } 3049 3050 /* obtain the block size of the media */ 3051 my_err = ioctl( my_fd, DKIOCGETBLOCKSIZE, &my_blksize ); 3052 if ( my_err == -1 ) { 3053 printf( "ioctl DKIOCGETBLOCKSIZE failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3054 goto test_failed_exit; 3055 } 3056 //printf( "my_block_count %qd my_blksize %d \n", my_block_count, my_blksize ); 3057 3058 /* make sure the returned data looks somewhat valid */ 3059 if ( my_blksize < 0 || my_blksize > (1024 * 1000) ) { 3060 printf( "ioctl appears to have returned incorrect block size data \n" ); 3061 goto test_failed_exit; 3062 } 3063 3064 my_err = 0; 3065 goto test_passed_exit; 3066 3067test_failed_exit: 3068 my_err = -1; 3069 3070test_passed_exit: 3071 if ( my_fd != -1 ) 3072 close( my_fd ); 3073 return( my_err ); 3074} 3075 3076/* ************************************************************************************************************** 3077 * Test mkdir, rmdir, umask system calls. 3078 * ************************************************************************************************************** 3079 */ 3080int mkdir_rmdir_umask_test( void * the_argp ) 3081{ 3082 int my_err; 3083 int my_fd = -1; 3084 int did_umask = 0; 3085 char * my_pathp = NULL; 3086 mode_t my_orig_mask; 3087 struct stat my_sb; 3088 kern_return_t my_kr; 3089 3090 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3091 if(my_kr != KERN_SUCCESS){ 3092 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3093 goto test_failed_exit; 3094 } 3095 3096 *my_pathp = 0x00; 3097 strcat( my_pathp, &g_target_path[0] ); 3098 strcat( my_pathp, "/" ); 3099 3100 /* get a unique name to use with mkdir */ 3101 my_err = create_random_name( my_pathp, 0 ); 3102 if ( my_err != 0 ) { 3103 printf( "create_random_name failed with error %d\n", my_err ); 3104 goto test_failed_exit; 3105 } 3106 3107 /* set umask to clear WX for other and group and clear X for user */ 3108 my_orig_mask = umask( (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) ); 3109 did_umask = 1; 3110 3111 /* create a directory with RWX for user, group, other (which should be limited by umask) */ 3112 my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) ); 3113 if ( my_err == -1 ) { 3114 printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3115 goto test_failed_exit; 3116 } 3117 3118 /* verify results - (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) should be clear*/ 3119 my_err = stat( my_pathp, &my_sb ); 3120 if ( my_err != 0 ) { 3121 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3122 goto test_failed_exit; 3123 } 3124 if ( (my_sb.st_mode & (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH)) != 0 ) { 3125 printf( "umask did not limit modes as it should have \n" ); 3126 goto test_failed_exit; 3127 } 3128 3129 /* get rid of our test directory */ 3130 my_err = rmdir( my_pathp ); 3131 if ( my_err == -1 ) { 3132 printf( "rmdir failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3133 goto test_failed_exit; 3134 } 3135 my_err = 0; 3136 goto test_passed_exit; 3137 3138test_failed_exit: 3139 my_err = -1; 3140 3141test_passed_exit: 3142 if ( my_fd != -1 ) 3143 close( my_fd ); 3144 if ( my_pathp != NULL ) { 3145 rmdir( my_pathp ); 3146 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3147 } 3148 if ( did_umask != 0 ) { 3149 umask( my_orig_mask ); 3150 } 3151 3152 return( my_err ); 3153} 3154 3155/* ************************************************************************************************************** 3156 * Test chroot system call. 3157 * ************************************************************************************************************** 3158 */ 3159int chroot_test( void * the_argp ) 3160{ 3161 int my_err, my_status; 3162 pid_t my_pid, my_wait_pid; 3163 char * my_pathp = NULL; 3164 kern_return_t my_kr; 3165 3166 if ( g_skip_setuid_tests != 0 ) { 3167 printf("\t skipping this test \n"); 3168 my_err = 0; 3169 goto test_passed_exit; 3170 } 3171 3172 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3173 if(my_kr != KERN_SUCCESS){ 3174 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3175 goto test_failed_exit; 3176 } 3177 3178 *my_pathp = 0x00; 3179 strcat( my_pathp, &g_target_path[0] ); 3180 strcat( my_pathp, "/" ); 3181 3182 /* get a unique name for our test directory */ 3183 my_err = create_random_name( my_pathp, 0 ); 3184 if ( my_err != 0 ) { 3185 goto test_failed_exit; 3186 } 3187 3188 /* create a test directory */ 3189 my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) ); 3190 if ( my_err == -1 ) { 3191 printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3192 goto test_failed_exit; 3193 } 3194 3195 /* 3196 * spin off a child process that we will use for testing. 3197 */ 3198 my_pid = fork( ); 3199 if ( my_pid == -1 ) { 3200 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 3201 goto test_failed_exit; 3202 } 3203 if ( my_pid == 0 ) { 3204 /* 3205 * child process - do getlogin and setlogin testing. 3206 */ 3207 struct stat my_sb; 3208 3209 /* change our root to our new test directory */ 3210 my_err = chroot( my_pathp ); 3211 if ( my_err != 0 ) { 3212 printf( "chroot failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3213 exit( -1 ); 3214 } 3215 3216 /* verify root directory is now an empty directory */ 3217 my_err = stat( "/", &my_sb ); 3218 if ( my_err != 0 ) { 3219 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3220 exit( -1 ); 3221 } 3222 if ( my_sb.st_nlink > 2 ) { 3223 printf( "root dir should be emnpty! \n" ); 3224 exit( -1 ); 3225 } 3226 exit( 0 ); 3227 } 3228 3229 /* parent process - 3230 * wait for child to exit 3231 */ 3232 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 3233 if ( my_wait_pid == -1 ) { 3234 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 3235 goto test_failed_exit; 3236 } 3237 3238 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 3239 printf( "bad exit status\n" ); 3240 goto test_failed_exit; 3241 } 3242 3243 my_err = 0; 3244 goto test_passed_exit; 3245 3246test_failed_exit: 3247 my_err = -1; 3248 3249test_passed_exit: 3250 if ( my_pathp != NULL ) { 3251 my_err = rmdir( my_pathp ); 3252 if ( my_err != 0 ) { 3253 printf( "rmdir failed with error %d - \"%s\" path %p\n", errno, strerror( errno), my_pathp ); 3254 } 3255 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3256 } 3257 return( my_err ); 3258} 3259 3260/* ************************************************************************************************************** 3261 * Test getpgrp, getpgid, getsid, setpgid, setpgrp, setsid system calls. 3262 * ************************************************************************************************************** 3263 */ 3264int process_group_test( void * the_argp ) 3265{ 3266 int my_err = 0, i = 0; 3267 pid_t my_session_id, my_pid, my_process_group; 3268 3269 /* get current session ID, pgid, and pid */ 3270 my_session_id = getsid( 0 ); 3271 if ( my_session_id == -1 ) { 3272 printf( "getsid call failed with error %d - \"%s\" \n", 3273 errno, strerror( errno ) ); 3274 goto test_failed_exit; 3275 } 3276 3277 my_pid = getpid( ); 3278 my_process_group = getpgrp( ); 3279 3280 /* test getpgrp and getpgid - they should return the same results when 0 is passed to getpgid */ 3281 if ( my_process_group != getpgid( 0 ) ) { 3282 printf( "getpgrp and getpgid did not return the same process group ID \n" ); 3283 printf( "getpgid: %d, my_process_group: %d\n", getpgid( 0 ), my_process_group ); 3284 goto test_failed_exit; 3285 } 3286 3287 if ( my_pid == my_process_group ) { 3288 /* we are process group leader */ 3289 my_err = setsid( ); 3290 if ( my_err == 0 || errno != EPERM ) { 3291 printf( "setsid call should have failed with EPERM\n" ); 3292 goto test_failed_exit; 3293 } 3294 } else { 3295 /* we are not process group leader: try creating new session */ 3296 my_err = setsid( ); 3297 if ( my_err == -1 ) { 3298 printf( "setsid call failed with error %d - \"%s\" \n", 3299 errno, strerror( errno ) ); 3300 goto test_failed_exit; 3301 } 3302 3303 if ( my_process_group == getpgid( 0 ) ) { 3304 printf( "process group was not reset \n" ); 3305 goto test_failed_exit; 3306 } 3307 } 3308 3309 /* find an unused process group ID */ 3310 for ( i = 10000; i < 1000000; i++ ) { 3311 my_process_group = getpgid( i ); 3312 if ( my_process_group == -1 ) { 3313 break; 3314 } 3315 } 3316 3317 /* this should fail */ 3318 my_err = setpgid( 0, my_process_group ); 3319 if ( my_err != -1 ) { 3320 printf( "setpgid should have failed, but did not \n" ); 3321 goto test_failed_exit; 3322 } 3323 3324 my_err = 0; 3325 goto test_passed_exit; 3326 3327test_failed_exit: 3328 my_err = -1; 3329 3330test_passed_exit: 3331 return( my_err ); 3332} 3333 3334/* ************************************************************************************************************** 3335 * Test fcntl system calls. 3336 * ************************************************************************************************************** 3337 */ 3338int fcntl_test( void * the_argp ) 3339{ 3340 int my_err, my_result, my_tmep; 3341 int my_fd = -1; 3342 int my_newfd = -1; 3343 char * my_pathp = NULL; 3344 kern_return_t my_kr; 3345 3346 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3347 if(my_kr != KERN_SUCCESS){ 3348 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3349 goto test_failed_exit; 3350 } 3351 3352 *my_pathp = 0x00; 3353 strcat( my_pathp, &g_target_path[0] ); 3354 strcat( my_pathp, "/" ); 3355 3356 /* create a test file */ 3357 my_err = create_random_name( my_pathp, 1 ); 3358 if ( my_err != 0 ) { 3359 goto test_failed_exit; 3360 } 3361 3362 /* open our test file and use fcntl to get / set file descriptor flags */ 3363 my_fd = open( my_pathp, O_RDONLY, 0 ); 3364 if ( my_fd == -1 ) { 3365 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3366 goto test_failed_exit; 3367 } 3368 3369 my_result = fcntl( my_fd, F_GETFD, 0 ); 3370 if ( my_result == -1 ) { 3371 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3372 goto test_failed_exit; 3373 } 3374 3375 my_tmep = (my_result & FD_CLOEXEC); 3376 if ( my_tmep ) { 3377 /* FD_CLOEXEC is on, let's turn it off */ 3378 my_result = fcntl( my_fd, F_SETFD, 0 ); 3379 } 3380 else { 3381 /* FD_CLOEXEC is off, let's turn it on */ 3382 my_result = fcntl( my_fd, F_SETFD, 1 ); 3383 } 3384 if ( my_result == -1 ) { 3385 printf( "fcntl - F_SETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3386 goto test_failed_exit; 3387 } 3388 3389 /* now check to see if it is set correctly */ 3390 my_result = fcntl( my_fd, F_GETFD, 0 ); 3391 if ( my_result == -1 ) { 3392 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3393 goto test_failed_exit; 3394 } 3395 if ( my_tmep == (my_result & 0x01) ) { 3396 printf( "fcntl - F_SETFD failed to set FD_CLOEXEC correctly!!! \n" ); 3397 goto test_failed_exit; 3398 } 3399 3400 /* dup it to a new fd with FD_CLOEXEC forced on */ 3401 3402 my_result = fcntl( my_fd, F_DUPFD_CLOEXEC, 0); 3403 if ( my_result == -1 ) { 3404 printf( "fcntl - F_DUPFD_CLOEXEC - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3405 goto test_failed_exit; 3406 } 3407 my_newfd = my_result; 3408 3409 /* check to see that it too is marked with FD_CLOEXEC */ 3410 3411 my_result = fcntl( my_newfd, F_GETFD, 0); 3412 if ( my_result == -1 ) { 3413 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3414 goto test_failed_exit; 3415 } 3416 if ( (my_result & FD_CLOEXEC) == 0 ) { 3417 printf( "fcntl - F_DUPFD_CLOEXEC failed to set FD_CLOEXEC!!! \n" ); 3418 goto test_failed_exit; 3419 } 3420 3421 close( my_newfd ); 3422 my_newfd = -1; 3423 3424#if !TARGET_OS_EMBEDDED /* This section of the test is specific for the desktop platform, refer <rdar://problem/8850905>*/ 3425 /* While we're here, dup it via an open of /dev/fd/<fd> .. */ 3426 3427 { 3428 char devfdpath[PATH_MAX]; 3429 3430 (void) snprintf( devfdpath, sizeof (devfdpath), 3431 "/dev/fd/%u", my_fd ); 3432 my_result = open( devfdpath, O_RDONLY | O_CLOEXEC ); 3433 } 3434 if ( my_result == -1 ) { 3435 printf( "open call failed on /dev/fd/%u with error %d - \"%s\" \n", my_fd, errno, strerror( errno) ); 3436 goto test_failed_exit; 3437 } 3438 my_newfd = my_result; 3439 3440 /* check to see that it too is marked with FD_CLOEXEC */ 3441 3442 my_result = fcntl( my_newfd, F_GETFD, 0); 3443 if ( my_result == -1 ) { 3444 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3445 goto test_failed_exit; 3446 } 3447 if ( (my_result & FD_CLOEXEC) == 0 ) { 3448 printf( "fcntl - O_CLOEXEC open of /dev/fd/%u failed to set FD_CLOEXEC!!! \n", my_fd ); 3449 goto test_failed_exit; 3450 } 3451 close ( my_newfd ); 3452 my_newfd = -1; 3453#endif 3454 my_err = 0; 3455 goto test_passed_exit; 3456 3457test_failed_exit: 3458 my_err = -1; 3459 3460test_passed_exit: 3461 if ( my_newfd != -1) 3462 close ( my_newfd ); 3463 if ( my_fd != -1 ) 3464 close( my_fd ); 3465 if ( my_pathp != NULL ) { 3466 remove( my_pathp ); 3467 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3468 } 3469 return( my_err ); 3470} 3471 3472/* ************************************************************************************************************** 3473 * Test getpriority, setpriority system calls. 3474 * ************************************************************************************************************** 3475 */ 3476int getpriority_setpriority_test( void * the_argp ) 3477{ 3478 int my_err; 3479 int my_priority; 3480 int my_new_priority; 3481 3482 /* getpriority returns scheduling priority so -1 is a valid value */ 3483 errno = 0; 3484 my_priority = getpriority( PRIO_PROCESS, 0 ); 3485 if ( my_priority == -1 && errno != 0 ) { 3486 printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3487 goto test_failed_exit; 3488 } 3489 3490 /* change scheduling priority */ 3491 my_new_priority = (my_priority == PRIO_MIN) ? (my_priority + 10) : (PRIO_MIN); 3492 my_err = setpriority( PRIO_PROCESS, 0, my_new_priority ); 3493 if ( my_err == -1 ) { 3494 printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3495 goto test_failed_exit; 3496 } 3497 3498 /* verify change */ 3499 errno = 0; 3500 my_priority = getpriority( PRIO_PROCESS, 0 ); 3501 if ( my_priority == -1 && errno != 0 ) { 3502 printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3503 goto test_failed_exit; 3504 } 3505 3506 if ( my_priority != my_new_priority ) { 3507 printf( "setpriority - failed to set correct scheduling priority \n" ); 3508 goto test_failed_exit; 3509 } 3510 3511 /* reset scheduling priority */ 3512 my_err = setpriority( PRIO_PROCESS, 0, 0 ); 3513 if ( my_err == -1 ) { 3514 printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3515 goto test_failed_exit; 3516 } 3517 3518 my_err = 0; 3519 goto test_passed_exit; 3520 3521test_failed_exit: 3522 my_err = -1; 3523 3524test_passed_exit: 3525 return( my_err ); 3526} 3527 3528/* ************************************************************************************************************** 3529 * Test futimes, gettimeofday, settimeofday, utimes system calls. 3530 * ************************************************************************************************************** 3531 */ 3532int time_tests( void * the_argp ) 3533{ 3534 int my_err; 3535 int my_fd = -1; 3536 char * my_pathp = NULL; 3537 struct timeval my_orig_time; 3538 struct timeval my_temp_time; 3539 struct timeval my_utimes[4]; 3540 struct timezone my_tz; 3541 struct stat my_sb; 3542 kern_return_t my_kr; 3543 3544 if ( g_skip_setuid_tests != 0 ) { 3545 printf( "\t skipping this test \n" ); 3546 my_err = 0; 3547 goto test_passed_exit; 3548 } 3549 3550 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3551 if(my_kr != KERN_SUCCESS){ 3552 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3553 goto test_failed_exit; 3554 } 3555 3556 *my_pathp = 0x00; 3557 strcat( my_pathp, &g_target_path[0] ); 3558 strcat( my_pathp, "/" ); 3559 3560 /* create a test file */ 3561 my_err = create_random_name( my_pathp, 1 ); 3562 if ( my_err != 0 ) { 3563 goto test_failed_exit; 3564 } 3565 3566 my_err = gettimeofday( &my_orig_time, &my_tz ); 3567 if ( my_err == -1 ) { 3568 printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3569 goto test_failed_exit; 3570 } 3571 //printf( "tv_sec %d tv_usec %ld \n", my_orig_time.tv_sec, my_orig_time.tv_usec ); 3572 3573 my_temp_time = my_orig_time; 3574 my_temp_time.tv_sec -= 60; 3575 my_err = settimeofday( &my_temp_time, NULL ); 3576 if ( my_err == -1 ) { 3577 printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3578 goto test_failed_exit; 3579 } 3580 3581 my_err = gettimeofday( &my_temp_time, NULL ); 3582 if ( my_err == -1 ) { 3583 printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3584 goto test_failed_exit; 3585 } 3586 //printf( "tv_sec %d tv_usec %ld \n", my_temp_time.tv_sec, my_temp_time.tv_usec ); 3587 if ( my_orig_time.tv_sec <= my_temp_time.tv_sec ) { 3588 printf( "settimeofday did not set correct time \n" ); 3589 goto test_failed_exit; 3590 } 3591 3592 /* set time back to original value plus 1 second */ 3593 my_temp_time = my_orig_time; 3594 my_temp_time.tv_sec += 1; 3595 my_err = settimeofday( &my_temp_time, NULL ); 3596 if ( my_err == -1 ) { 3597 printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3598 goto test_failed_exit; 3599 } 3600 3601 /* test utimes and futimes - get current access and mod times then change them */ 3602 my_err = stat( my_pathp, &my_sb ); 3603 if ( my_err != 0 ) { 3604 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3605 goto test_failed_exit; 3606 } 3607 TIMESPEC_TO_TIMEVAL( &my_utimes[0], &my_sb.st_atimespec ); 3608 TIMESPEC_TO_TIMEVAL( &my_utimes[1], &my_sb.st_mtimespec ); 3609 my_utimes[0].tv_sec -= 120; /* make access time 2 minutes older */ 3610 my_utimes[1].tv_sec -= 120; /* make mod time 2 minutes older */ 3611 3612 my_err = utimes( my_pathp, &my_utimes[0] ); 3613 if ( my_err == -1 ) { 3614 printf( "utimes - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3615 goto test_failed_exit; 3616 } 3617 3618 /* make sure the correct times are set */ 3619 my_err = stat( my_pathp, &my_sb ); 3620 if ( my_err != 0 ) { 3621 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3622 goto test_failed_exit; 3623 } 3624 TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec ); 3625 TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec ); 3626 if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec || 3627 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) { 3628 printf( "utimes failed to set access and mod times \n" ); 3629 goto test_failed_exit; 3630 } 3631 3632 my_fd = open( my_pathp, O_RDWR, 0 ); 3633 if ( my_fd == -1 ) { 3634 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3635 goto test_failed_exit; 3636 } 3637 3638 my_utimes[0].tv_sec -= 120; /* make access time 2 minutes older */ 3639 my_utimes[1].tv_sec -= 120; /* make mod time 2 minutes older */ 3640 my_err = futimes( my_fd, &my_utimes[0] ); 3641 if ( my_err == -1 ) { 3642 printf( "futimes - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3643 goto test_failed_exit; 3644 } 3645 3646 /* make sure the correct times are set */ 3647 my_err = stat( my_pathp, &my_sb ); 3648 if ( my_err != 0 ) { 3649 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3650 goto test_failed_exit; 3651 } 3652 TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec ); 3653 TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec ); 3654 if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec || 3655 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) { 3656 printf( "futimes failed to set access and mod times \n" ); 3657 goto test_failed_exit; 3658 } 3659 3660 my_err = 0; 3661 goto test_passed_exit; 3662 3663test_failed_exit: 3664 my_err = -1; 3665 3666test_passed_exit: 3667 if ( my_fd != -1 ) 3668 close( my_fd ); 3669 if ( my_pathp != NULL ) { 3670 remove( my_pathp ); 3671 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3672 } 3673 return( my_err ); 3674} 3675 3676/* ************************************************************************************************************** 3677 * Test rename, stat system calls. 3678 * ************************************************************************************************************** 3679 */ 3680int rename_test( void * the_argp ) 3681{ 3682 int my_err; 3683 char * my_pathp = NULL; 3684 char * my_new_pathp = NULL; 3685 ino_t my_file_id; 3686 struct stat my_sb; 3687 kern_return_t my_kr; 3688 3689 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3690 if(my_kr != KERN_SUCCESS){ 3691 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3692 goto test_failed_exit; 3693 } 3694 3695 *my_pathp = 0x00; 3696 strcat( my_pathp, &g_target_path[0] ); 3697 strcat( my_pathp, "/" ); 3698 3699 /* create a test file */ 3700 my_err = create_random_name( my_pathp, 1 ); 3701 if ( my_err != 0 ) { 3702 goto test_failed_exit; 3703 } 3704 3705 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3706 if(my_kr != KERN_SUCCESS){ 3707 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3708 goto test_failed_exit; 3709 } 3710 3711 *my_new_pathp = 0x00; 3712 strcat( my_new_pathp, &g_target_path[0] ); 3713 strcat( my_new_pathp, "/" ); 3714 3715 /* get a unique name for our rename test */ 3716 my_err = create_random_name( my_new_pathp, 0 ); 3717 if ( my_err != 0 ) { 3718 goto test_failed_exit; 3719 } 3720 3721 /* save file ID for later use */ 3722 my_err = stat( my_pathp, &my_sb ); 3723 if ( my_err != 0 ) { 3724 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3725 goto test_failed_exit; 3726 } 3727 my_file_id = my_sb.st_ino; 3728 3729 /* test rename */ 3730 my_err = rename( my_pathp, my_new_pathp ); 3731 if ( my_err == -1 ) { 3732 printf( "rename - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3733 goto test_failed_exit; 3734 } 3735 3736 /* make sure old name is no longer there */ 3737 my_err = stat( my_pathp, &my_sb ); 3738 if ( my_err == 0 ) { 3739 printf( "rename call failed - found old name \n" ); 3740 goto test_failed_exit; 3741 } 3742 3743 /* make sure new name is there and is correct file id */ 3744 my_err = stat( my_new_pathp, &my_sb ); 3745 if ( my_err != 0 ) { 3746 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3747 goto test_failed_exit; 3748 } 3749 if ( my_file_id != my_sb.st_ino ) { 3750 printf( "rename failed - wrong file id \n" ); 3751 goto test_failed_exit; 3752 } 3753 3754 my_err = 0; 3755 goto test_passed_exit; 3756 3757test_failed_exit: 3758 my_err = -1; 3759 3760test_passed_exit: 3761 if ( my_pathp != NULL ) { 3762 remove( my_pathp ); 3763 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3764 } 3765 if ( my_new_pathp != NULL ) { 3766 remove( my_new_pathp ); 3767 vm_deallocate(mach_task_self(), (vm_address_t)my_new_pathp, PATH_MAX); 3768 } 3769 return( my_err ); 3770} 3771 3772/* ************************************************************************************************************** 3773 * Test locking system calls. 3774 * ************************************************************************************************************** 3775 */ 3776int locking_test( void * the_argp ) 3777{ 3778 int my_err, my_status; 3779 pid_t my_pid, my_wait_pid; 3780 int my_fd = -1; 3781 char * my_pathp = NULL; 3782 kern_return_t my_kr; 3783 3784 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3785 if(my_kr != KERN_SUCCESS){ 3786 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3787 goto test_failed_exit; 3788 } 3789 3790 *my_pathp = 0x00; 3791 strcat( my_pathp, &g_target_path[0] ); 3792 strcat( my_pathp, "/" ); 3793 3794 /* create a test file */ 3795 my_err = create_random_name( my_pathp, 1 ); 3796 if ( my_err != 0 ) { 3797 goto test_failed_exit; 3798 } 3799 3800 /* test flock */ 3801 my_fd = open( my_pathp, O_RDWR, 0 ); 3802 if ( my_fd == -1 ) { 3803 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3804 goto test_failed_exit; 3805 } 3806 3807 my_err = flock( my_fd, LOCK_EX ); 3808 if ( my_err == -1 ) { 3809 printf( "flock - LOCK_EX - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3810 goto test_failed_exit; 3811 } 3812 3813 /* 3814 * spin off a child process that we will use for testing. 3815 */ 3816 my_pid = fork( ); 3817 if ( my_pid == -1 ) { 3818 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 3819 goto test_failed_exit; 3820 } 3821 if ( my_pid == 0 ) { 3822 /* 3823 * child process. 3824 */ 3825 int my_child_fd = -1; 3826 int my_child_err; 3827 3828 my_child_fd = open( my_pathp, O_RDWR, 0 ); 3829 if ( my_child_fd == -1 ) { 3830 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3831 my_child_err = -1; 3832 goto child_exit; 3833 } 3834 3835 my_err = flock( my_child_fd, (LOCK_EX | LOCK_NB) ); 3836 if ( my_err == -1 ) { 3837 if ( errno != EWOULDBLOCK ) { 3838 printf( "flock call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3839 my_child_err = -1; 3840 goto child_exit; 3841 } 3842 } 3843 else { 3844 printf( "flock call should have failed with EWOULDBLOCK err \n" ); 3845 my_child_err = -1; 3846 goto child_exit; 3847 } 3848 my_child_err = 0; 3849child_exit: 3850 if ( my_child_fd != -1 ) 3851 close( my_child_fd ); 3852 exit( my_child_err ); 3853 } 3854 3855 /* parent process - 3856 * wait for child to exit 3857 */ 3858 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 3859 if ( my_wait_pid == -1 ) { 3860 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 3861 goto test_failed_exit; 3862 } 3863 3864 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 3865 goto test_failed_exit; 3866 } 3867 3868 my_err = flock( my_fd, LOCK_UN ); 3869 if ( my_err == -1 ) { 3870 printf( "flock - LOCK_UN - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3871 goto test_failed_exit; 3872 } 3873 3874 my_err = 0; 3875 goto test_passed_exit; 3876 3877test_failed_exit: 3878 my_err = -1; 3879 3880test_passed_exit: 3881 if ( my_fd != -1 ) 3882 close( my_fd ); 3883 if ( my_pathp != NULL ) { 3884 remove( my_pathp ); 3885 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3886 } 3887 return( my_err ); 3888} 3889 3890/* ************************************************************************************************************** 3891 * Test mkfifo system calls. 3892 * ************************************************************************************************************** 3893 */ 3894int mkfifo_test( void * the_argp ) 3895{ 3896 int my_err, my_status; 3897 pid_t my_pid, my_wait_pid; 3898 int my_fd = -1; 3899 char * my_pathp = NULL; 3900 ssize_t my_result; 3901 off_t my_current_offset; 3902 kern_return_t my_kr; 3903 3904 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3905 if(my_kr != KERN_SUCCESS){ 3906 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3907 goto test_failed_exit; 3908 } 3909 3910 *my_pathp = 0x00; 3911 strcat( my_pathp, &g_target_path[0] ); 3912 strcat( my_pathp, "/" ); 3913 3914 /* get unique name for our fifo */ 3915 my_err = create_random_name( my_pathp, 0 ); 3916 if ( my_err != 0 ) { 3917 goto test_failed_exit; 3918 } 3919 3920 my_err = mkfifo( my_pathp, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) ); 3921 if ( my_err != 0 ) { 3922 printf( "mkfifo failed with errno %d - %s. \n", errno, strerror( errno ) ); 3923 goto test_failed_exit; 3924 } 3925 3926 /* 3927 * spin off a child process that we will use for testing. 3928 */ 3929 my_pid = fork( ); 3930 if ( my_pid == -1 ) { 3931 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 3932 goto test_failed_exit; 3933 } 3934 if ( my_pid == 0 ) { 3935 /* 3936 * child process. 3937 */ 3938 int my_child_fd = -1; 3939 int my_child_err; 3940 char my_buffer[64]; 3941 3942 /* open read end of fifo */ 3943 my_child_fd = open( my_pathp, O_RDWR, 0 ); 3944 if ( my_child_fd == -1 ) { 3945 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3946 my_child_err = -1; 3947 goto child_exit; 3948 } 3949 3950 /* read message from parent */ 3951 bzero( (void *)&my_buffer[0], sizeof(my_buffer) ); 3952 my_result = read( my_child_fd, &my_buffer[0], sizeof(my_buffer) ); 3953 if ( my_result == -1 ) { 3954 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3955 my_child_err = -1; 3956 goto child_exit; 3957 } 3958 if ( strcmp( "parent to child", &my_buffer[0] ) != 0 ) { 3959 printf( "read wrong message from parent \n" ); 3960 my_child_err = -1; 3961 goto child_exit; 3962 } 3963 3964 my_child_err = 0; 3965child_exit: 3966 if ( my_child_fd != -1 ) 3967 close( my_child_fd ); 3968 exit( my_child_err ); 3969 } 3970 3971 /* parent process - open write end of fifo 3972 */ 3973 my_fd = open( my_pathp, O_WRONLY, 0 ); 3974 if ( my_fd == -1 ) { 3975 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3976 goto test_failed_exit; 3977 } 3978 3979 /* make sure we can't seek on a fifo */ 3980 my_current_offset = lseek( my_fd, 0, SEEK_CUR ); 3981 if ( my_current_offset != -1 ) { 3982 printf( "lseek on fifo should fail but did not \n" ); 3983 goto test_failed_exit; 3984 } 3985 3986 my_result = write( my_fd, "parent to child", 15 ); 3987 if ( my_result == -1 ) { 3988 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3989 goto test_failed_exit; 3990 } 3991 3992 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 3993 if ( my_wait_pid == -1 ) { 3994 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 3995 goto test_failed_exit; 3996 } 3997 3998 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 3999 goto test_failed_exit; 4000 } 4001 4002 my_err = 0; 4003 goto test_passed_exit; 4004 4005test_failed_exit: 4006 my_err = -1; 4007 4008test_passed_exit: 4009 if ( my_fd != -1 ) 4010 close( my_fd ); 4011 if ( my_pathp != NULL ) { 4012 remove( my_pathp ); 4013 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 4014 } 4015 return( my_err ); 4016} 4017 4018/* ************************************************************************************************************** 4019 * Test quotactl system calls. 4020 * ************************************************************************************************************** 4021 */ 4022int quotactl_test( void * the_argp ) 4023{ 4024#if !TARGET_OS_EMBEDDED 4025 int my_err; 4026 int is_quotas_on = 0; 4027 struct dqblk my_quota_blk; 4028 4029 if ( g_skip_setuid_tests != 0 ) { 4030 printf( "\t skipping this test \n" ); 4031 my_err = 0; 4032 goto test_passed_exit; 4033 } 4034 4035 /* start off by checking the status of quotas on the boot volume */ 4036 my_err = quotactl( "/mach_kernel", QCMD(Q_QUOTASTAT, USRQUOTA), 0, (caddr_t)&is_quotas_on ); 4037 if ( my_err == -1 ) { 4038 printf( "quotactl - Q_QUOTASTAT - failed with errno %d - %s \n", errno, strerror( errno ) ); 4039 goto test_failed_exit; 4040 } 4041 4042 if ( is_quotas_on == 0 ) { 4043 /* quotas are off */ 4044 my_err = 0; 4045 goto test_passed_exit; 4046 } 4047 4048 my_err = quotactl( "/mach_kernel", QCMD(Q_GETQUOTA, USRQUOTA), getuid(), (caddr_t)&my_quota_blk ); 4049 if ( my_err == -1 ) { 4050 printf( "quotactl - Q_GETQUOTA - failed with errno %d - %s \n", errno, strerror( errno ) ); 4051 goto test_failed_exit; 4052 } 4053 4054 my_err = 0; 4055 goto test_passed_exit; 4056 4057test_failed_exit: 4058 my_err = -1; 4059 4060test_passed_exit: 4061 return( my_err ); 4062#else 4063 printf( "\t--> Not supported on EMBEDDED TARGET\n" ); 4064 return 0; 4065#endif 4066} 4067 4068/* ************************************************************************************************************** 4069 * Test getrlimit, setrlimit system calls. 4070 * ************************************************************************************************************** 4071 */ 4072int limit_tests( void * the_argp ) 4073{ 4074 int my_err; 4075 struct rlimit my_current_rlimit; 4076 struct rlimit my_rlimit; 4077 4078 my_err = getrlimit( RLIMIT_NOFILE, &my_current_rlimit ); 4079 if ( my_err == -1 ) { 4080 printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) ); 4081 goto test_failed_exit; 4082 } 4083 if ( my_current_rlimit.rlim_cur != RLIM_INFINITY ) { 4084 if ( my_current_rlimit.rlim_cur != my_current_rlimit.rlim_max ) 4085 my_current_rlimit.rlim_cur += 1; 4086 else 4087 my_current_rlimit.rlim_cur -= 1; 4088 my_rlimit.rlim_cur = my_current_rlimit.rlim_cur; 4089 my_rlimit.rlim_max = my_current_rlimit.rlim_max; 4090 my_err = setrlimit( RLIMIT_NOFILE, &my_rlimit ); 4091 if ( my_err == -1 ) { 4092 printf( "setrlimit - failed with errno %d - %s \n", errno, strerror( errno ) ); 4093 goto test_failed_exit; 4094 } 4095 4096 /* verify that we set a new limit */ 4097 bzero( (void *) &my_rlimit, sizeof( my_rlimit ) ); 4098 my_err = getrlimit( RLIMIT_NOFILE, &my_rlimit ); 4099 if ( my_err == -1 ) { 4100 printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) ); 4101 goto test_failed_exit; 4102 } 4103 if ( my_rlimit.rlim_cur != my_current_rlimit.rlim_cur ) { 4104 printf( "failed to get/set new RLIMIT_NOFILE soft limit \n" ); 4105 printf( "soft limits - current %lld should be %lld \n", my_rlimit.rlim_cur, my_current_rlimit.rlim_cur ); 4106 goto test_failed_exit; 4107 } 4108 4109#if CONFORMANCE_CHANGES_IN_XNU // can't do this check until conformance changes get into xnu 4110 printf( "hard limits - current %lld should be %lld \n", my_rlimit.rlim_max, my_current_rlimit.rlim_max ); 4111 if ( my_rlimit.rlim_max != my_current_rlimit.rlim_max ) { 4112 printf( "failed to get/set new RLIMIT_NOFILE hard limit \n" ); 4113 goto test_failed_exit; 4114 } 4115#endif 4116 4117 /* 4118 * A test for a limit that won't fit in a signed 32 bits, a la 5414697 4119 * Note: my_rlimit should still have a valid rlim_max. 4120 */ 4121 long long biglim = 2147483649ll; /* Just over 2^31 */ 4122 my_rlimit.rlim_cur = biglim; 4123 my_err = setrlimit(RLIMIT_CPU, &my_rlimit); 4124 if (my_err == -1) { 4125 printf("failed to set large limit.\n"); 4126 goto test_failed_exit; 4127 } 4128 4129 bzero(&my_rlimit, sizeof(struct rlimit)); 4130 my_err = getrlimit(RLIMIT_CPU, &my_rlimit); 4131 if (my_err == -1) { 4132 printf("after setting large value, failed to getrlimit().\n"); 4133 goto test_failed_exit; 4134 } 4135 4136 if (my_rlimit.rlim_cur != biglim) { 4137 printf("didn't retrieve large limit.\n"); 4138 goto test_failed_exit; 4139 } 4140 } 4141 4142 my_err = 0; 4143 goto test_passed_exit; 4144 4145test_failed_exit: 4146 my_err = -1; 4147 4148test_passed_exit: 4149 return( my_err ); 4150} 4151 4152/* ************************************************************************************************************** 4153 * Test getattrlist, getdirentriesattr, setattrlist system calls. 4154 * ************************************************************************************************************** 4155 */ 4156struct test_attr_buf { 4157 uint32_t length; 4158 fsobj_type_t obj_type; 4159 fsobj_id_t obj_id; 4160 struct timespec backup_time; 4161}; 4162 4163typedef struct test_attr_buf test_attr_buf; 4164 4165int directory_tests( void * the_argp ) 4166{ 4167 int my_err, done, found_it, i; 4168 int my_fd = -1; 4169 int is_ufs = 0; 4170 char * my_pathp = NULL; 4171 char * my_bufp = NULL; 4172 char * my_file_namep; 4173#ifdef __LP64__ 4174 unsigned int my_base; 4175 unsigned int my_count; 4176 unsigned int my_new_state; 4177#else 4178 unsigned long my_base; 4179 unsigned long my_count; 4180 unsigned long my_new_state; 4181#endif 4182 fsobj_id_t my_obj_id; 4183 struct timespec my_new_backup_time; 4184 struct attrlist my_attrlist; 4185 test_attr_buf my_attr_buf[4]; 4186 struct statfs my_statfs_buf; 4187 kern_return_t my_kr; 4188 4189 /* need to know type of file system */ 4190 my_err = statfs( &g_target_path[0], &my_statfs_buf ); 4191 if ( my_err == -1 ) { 4192 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4193 goto test_failed_exit; 4194 } 4195 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) { 4196 is_ufs = 1; 4197 } 4198 4199 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, (1024 * 5), VM_FLAGS_ANYWHERE); 4200 if(my_kr != KERN_SUCCESS){ 4201 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4202 goto test_failed_exit; 4203 } 4204 4205 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 4206 if(my_kr != KERN_SUCCESS){ 4207 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4208 goto test_failed_exit; 4209 } 4210 4211 *my_pathp = 0x00; 4212 strcat( my_pathp, &g_target_path[0] ); 4213 strcat( my_pathp, "/" ); 4214 4215 /* create a test file */ 4216 my_err = create_random_name( my_pathp, 1 ); 4217 if ( my_err != 0 ) { 4218 goto test_failed_exit; 4219 } 4220 4221 /* get pointer to just the file name */ 4222 my_file_namep = strrchr( my_pathp, '/' ); 4223 my_file_namep++; 4224 4225 /* check out the test directory */ 4226 my_fd = open( &g_target_path[0], (O_RDONLY), 0 ); 4227 if ( my_fd == -1 ) { 4228 printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4229 goto test_failed_exit; 4230 } 4231 4232 /* test get/setattrlist */ 4233 memset( &my_attrlist, 0, sizeof(my_attrlist) ); 4234 my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT; 4235 my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME); 4236 my_err = getattrlist( my_pathp, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf[0]), 0 ); 4237 4238 if ( my_err != 0 ) { 4239 if ( errno == ENOTSUP && is_ufs ) { 4240 /* getattr calls not supported on ufs */ 4241 my_err = 0; 4242 goto test_passed_exit; 4243 } 4244 printf( "getattrlist call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4245 goto test_failed_exit; 4246 } 4247 /* validate returned data */ 4248 if ( my_attr_buf[0].obj_type != VREG ) { 4249 printf( "getattrlist returned incorrect obj_type data. \n" ); 4250 goto test_failed_exit; 4251 } 4252 4253 /* set new backup time */ 4254 my_obj_id = my_attr_buf[0].obj_id; 4255 my_new_backup_time = my_attr_buf[0].backup_time; 4256 my_new_backup_time.tv_sec += 60; 4257 my_attr_buf[0].backup_time.tv_sec = my_new_backup_time.tv_sec; 4258 my_attrlist.commonattr = (ATTR_CMN_BKUPTIME); 4259 my_err = setattrlist( my_pathp, &my_attrlist, &my_attr_buf[0].backup_time, sizeof(my_attr_buf[0].backup_time), 0 ); 4260 if ( my_err != 0 ) { 4261 printf( "setattrlist call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4262 goto test_failed_exit; 4263 } 4264 4265 /* validate setattrlist using getdirentriesattr */ 4266 close( my_fd ); 4267 my_fd = open( &g_target_path[0], (O_RDONLY), 0 ); 4268 if ( my_fd == -1 ) { 4269 printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4270 goto test_failed_exit; 4271 } 4272 memset( &my_attrlist, 0, sizeof(my_attrlist) ); 4273 memset( &my_attr_buf, 0, sizeof(my_attr_buf) ); 4274 my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT; 4275 my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME); 4276 my_count = 4; 4277 my_base = 0; 4278 my_err = getdirentriesattr( my_fd, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf), &my_count, 4279 &my_base, &my_new_state, 0 ); 4280 if ( my_err < 0 ) { 4281 printf( "getdirentriesattr call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4282 goto test_failed_exit; 4283 } 4284 4285 found_it = 0; 4286 for ( i = 0; i < my_count; i++ ) { 4287 if ( my_attr_buf[i].obj_id.fid_objno == my_obj_id.fid_objno && 4288 my_attr_buf[i].obj_id.fid_generation == my_obj_id.fid_generation ) { 4289 found_it = 1; 4290 if ( my_attr_buf[i].backup_time.tv_sec != my_new_backup_time.tv_sec ) { 4291 printf( "setattrlist failed to set backup time. \n" ); 4292 goto test_failed_exit; 4293 } 4294 } 4295 } 4296 if ( found_it == 0 ) { 4297 printf( "getdirentriesattr failed to find test file. \n" ); 4298 goto test_failed_exit; 4299 } 4300 4301 my_err = 0; 4302 goto test_passed_exit; 4303 4304test_failed_exit: 4305 if(my_err != 0) 4306 my_err = -1; 4307 4308test_passed_exit: 4309 if ( my_fd != -1 ) 4310 close( my_fd ); 4311 if ( my_pathp != NULL ) { 4312 remove( my_pathp ); 4313 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 4314 } 4315 if ( my_bufp != NULL ) { 4316 vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, (1024 * 5)); 4317 } 4318 return( my_err ); 4319} 4320 4321/* ************************************************************************************************************** 4322 * Test exchangedata system calls. 4323 * ************************************************************************************************************** 4324 */ 4325int exchangedata_test( void * the_argp ) 4326{ 4327 int my_err; 4328 int my_fd1 = -1; 4329 int my_fd2 = -1; 4330 char * my_file1_pathp = NULL; 4331 char * my_file2_pathp = NULL; 4332 ssize_t my_result; 4333 char my_buffer[16]; 4334 struct statfs my_statfs_buf; 4335 kern_return_t my_kr; 4336 4337 /* need to know type of file system */ 4338 my_err = statfs( &g_target_path[0], &my_statfs_buf ); 4339 if ( my_err == -1 ) { 4340 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4341 goto test_failed_exit; 4342 } 4343 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) { 4344 /* ufs does not support exchangedata */ 4345 my_err = 0; 4346 goto test_passed_exit; 4347 } 4348 4349 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file1_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 4350 if(my_kr != KERN_SUCCESS){ 4351 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4352 goto test_failed_exit; 4353 } 4354 4355 *my_file1_pathp = 0x00; 4356 strcat( my_file1_pathp, &g_target_path[0] ); 4357 strcat( my_file1_pathp, "/" ); 4358 4359 /* create a test file */ 4360 my_err = create_random_name( my_file1_pathp, 1 ); 4361 if ( my_err != 0 ) { 4362 printf( "create_random_name my_err: %d\n", my_err ); 4363 goto test_failed_exit; 4364 } 4365 my_fd1 = open( my_file1_pathp, O_RDWR, 0 ); 4366 if ( my_fd1 == -1 ) { 4367 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4368 goto test_failed_exit; 4369 } 4370 my_result = write( my_fd1, "11111111", 8 ); 4371 if ( my_result == -1 ) { 4372 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4373 goto test_failed_exit; 4374 } 4375 4376 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file2_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 4377 if(my_kr != KERN_SUCCESS){ 4378 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4379 goto test_failed_exit; 4380 } 4381 4382 *my_file2_pathp = 0x00; 4383 strcat( my_file2_pathp, &g_target_path[0] ); 4384 strcat( my_file2_pathp, "/" ); 4385 4386 /* create a test file */ 4387 my_err = create_random_name( my_file2_pathp, 1 ); 4388 if ( my_err != 0 ) { 4389 printf( "create_random_name my_err: %d\n", my_err ); 4390 goto test_failed_exit; 4391 } 4392 my_fd2 = open( my_file2_pathp, O_RDWR, 0 ); 4393 if ( my_fd2 == -1 ) { 4394 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4395 goto test_failed_exit; 4396 } 4397 my_result = write( my_fd2, "22222222", 8 ); 4398 if ( my_result == -1 ) { 4399 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4400 goto test_failed_exit; 4401 } 4402 close(my_fd1); 4403 my_fd1 = -1; 4404 close(my_fd2); 4405 my_fd2 = -1; 4406 4407 /* test exchangedata */ 4408 my_err = exchangedata( my_file1_pathp, my_file2_pathp, 0 ); 4409 if ( my_err == -1 ) { 4410 printf( "exchangedata failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4411 goto test_failed_exit; 4412 } 4413 4414 /* now validate exchange */ 4415 my_fd1 = open( my_file1_pathp, O_RDONLY, 0 ); 4416 if ( my_fd1 == -1 ) { 4417 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4418 goto test_failed_exit; 4419 } 4420 bzero( (void *)&my_buffer[0], sizeof(my_buffer) ); 4421 my_result = read( my_fd1, &my_buffer[0], 8 ); 4422 if ( my_result == -1 ) { 4423 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4424 goto test_failed_exit; 4425 } 4426 4427 if ( memcmp( &my_buffer[0], "22222222", 8 ) != 0 ) { 4428 printf( "exchangedata failed - incorrect data in file \n" ); 4429 goto test_failed_exit; 4430 } 4431 4432 my_err = 0; 4433 goto test_passed_exit; 4434 4435test_failed_exit: 4436 my_err = -1; 4437 4438test_passed_exit: 4439 if ( my_fd1 != -1 ) 4440 close( my_fd1 ); 4441 if ( my_file1_pathp != NULL ) { 4442 remove( my_file1_pathp ); 4443 vm_deallocate(mach_task_self(), (vm_address_t)my_file1_pathp, PATH_MAX); 4444 } 4445 if ( my_fd2 != -1 ) 4446 close( my_fd2 ); 4447 if ( my_file2_pathp != NULL ) { 4448 remove( my_file2_pathp ); 4449 vm_deallocate(mach_task_self(), (vm_address_t)my_file2_pathp, PATH_MAX); 4450 } 4451 return( my_err ); 4452} 4453 4454 4455/* ************************************************************************************************************** 4456 * Test searchfs system calls. 4457 * ************************************************************************************************************** 4458 */ 4459 4460struct packed_name_attr { 4461 u_int32_t size; /* Of the remaining fields */ 4462 struct attrreference ref; /* Offset/length of name itself */ 4463 char name[ PATH_MAX ]; 4464}; 4465 4466struct packed_attr_ref { 4467 u_int32_t size; /* Of the remaining fields */ 4468 struct attrreference ref; /* Offset/length of attr itself */ 4469}; 4470 4471struct packed_result { 4472 u_int32_t size; /* Including size field itself */ 4473 attrreference_t obj_name; 4474 struct fsobj_id obj_id; 4475 struct timespec obj_create_time; 4476 char room_for_name[ 64 ]; 4477}; 4478typedef struct packed_result packed_result; 4479typedef struct packed_result * packed_result_p; 4480 4481#define MAX_MATCHES 10 4482#define MAX_EBUSY_RETRIES 5 4483 4484int searchfs_test( void * the_argp ) 4485{ 4486#if !TARGET_OS_EMBEDDED 4487 int my_err, my_items_found = 0, my_ebusy_count; 4488 char * my_pathp = NULL; 4489 unsigned long my_matches; 4490 unsigned long my_search_options; 4491 struct fssearchblock my_search_blk; 4492 struct attrlist my_return_list; 4493 struct searchstate my_search_state; 4494 struct packed_name_attr my_info1; 4495 struct packed_attr_ref my_info2; 4496 packed_result my_result_buffer[ MAX_MATCHES ]; 4497 struct statfs my_statfs_buf; 4498 kern_return_t my_kr; 4499 4500 /* need to know type of file system */ 4501 my_err = statfs( &g_target_path[0], &my_statfs_buf ); 4502 if ( my_err == -1 ) { 4503 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4504 goto test_failed_exit; 4505 } 4506 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) { 4507 /* ufs does not support exchangedata */ 4508 my_err = 0; 4509 goto test_passed_exit; 4510 } 4511 4512 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 4513 if(my_kr != KERN_SUCCESS){ 4514 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4515 goto test_failed_exit; 4516 } 4517 4518 *my_pathp = 0x00; 4519 strcat( my_pathp, &g_target_path[0] ); 4520 strcat( my_pathp, "/" ); 4521 4522 /* create test files */ 4523 my_err = create_file_with_name( my_pathp, "foo", 0 ); 4524 if ( my_err < 0 ) { 4525 printf( "failed to create a test file name in \"%s\" \n", my_pathp ); 4526 goto test_failed_exit; 4527 } 4528 4529 my_err = create_file_with_name( my_pathp, "foobar", 0 ); 4530 if ( my_err < 0 ) { 4531 printf( "failed to create a test file name in \"%s\" \n", my_pathp ); 4532 goto test_failed_exit; 4533 } 4534 4535 my_err = create_file_with_name( my_pathp, "foofoo", 0 ); 4536 if ( my_err < 0 ) { 4537 printf( "failed to create a test file name in \"%s\" \n", my_pathp ); 4538 goto test_failed_exit; 4539 } 4540 4541 my_err = create_file_with_name( my_pathp, "xxxfoo", 0 ); 4542 if ( my_err < 0 ) { 4543 printf( "failed to create a test file name in \"%s\" \n", my_pathp ); 4544 goto test_failed_exit; 4545 } 4546 4547 /* EBUSY count updated below the catalogue_changed label */ 4548 my_ebusy_count = 0; 4549 4550catalogue_changed: 4551 /* search target volume for all file system objects with "foo" in the name */ 4552 /* Set up the attributes we're searching on. */ 4553 my_items_found = 0; /* Set this here in case we're completely restarting */ 4554 my_search_blk.searchattrs.bitmapcount = ATTR_BIT_MAP_COUNT; 4555 my_search_blk.searchattrs.reserved = 0; 4556 my_search_blk.searchattrs.commonattr = ATTR_CMN_NAME; 4557 my_search_blk.searchattrs.volattr = 0; 4558 my_search_blk.searchattrs.dirattr = 0; 4559 my_search_blk.searchattrs.fileattr = 0; 4560 my_search_blk.searchattrs.forkattr = 0; 4561 4562 /* Set up the attributes we want for all returned matches. */ 4563 /* Why is returnattrs a pointer instead of an embedded struct? */ 4564 my_search_blk.returnattrs = &my_return_list; 4565 my_return_list.bitmapcount = ATTR_BIT_MAP_COUNT; 4566 my_return_list.reserved = 0; 4567 my_return_list.commonattr = ATTR_CMN_NAME | ATTR_CMN_OBJID | ATTR_CMN_CRTIME; 4568 my_return_list.volattr = 0; 4569 my_return_list.dirattr = 0; 4570 my_return_list.fileattr = 0; 4571 my_return_list.forkattr = 0; 4572 4573 /* Allocate a buffer for returned matches */ 4574 my_search_blk.returnbuffer = my_result_buffer; 4575 my_search_blk.returnbuffersize = sizeof(my_result_buffer); 4576 4577 /* Pack the searchparams1 into a buffer */ 4578 /* NOTE: A name appears only in searchparams1 */ 4579 strcpy( my_info1.name, "foo" ); 4580 my_info1.ref.attr_dataoffset = sizeof(struct attrreference); 4581 my_info1.ref.attr_length = strlen(my_info1.name) + 1; 4582 my_info1.size = sizeof(struct attrreference) + my_info1.ref.attr_length; 4583 my_search_blk.searchparams1 = &my_info1; 4584 my_search_blk.sizeofsearchparams1 = my_info1.size + sizeof(u_int32_t); 4585 4586 /* Pack the searchparams2 into a buffer */ 4587 my_info2.size = sizeof(struct attrreference); 4588 my_info2.ref.attr_dataoffset = sizeof(struct attrreference); 4589 my_info2.ref.attr_length = 0; 4590 my_search_blk.searchparams2 = &my_info2; 4591 my_search_blk.sizeofsearchparams2 = sizeof(my_info2); 4592 4593 /* Maximum number of matches we want */ 4594 my_search_blk.maxmatches = MAX_MATCHES; 4595 4596 /* Maximum time to search, per call */ 4597 my_search_blk.timelimit.tv_sec = 1; 4598 my_search_blk.timelimit.tv_usec = 0; 4599 4600 my_search_options = (SRCHFS_START | SRCHFS_MATCHPARTIALNAMES | 4601 SRCHFS_MATCHFILES | SRCHFS_MATCHDIRS); 4602 do { 4603 char * my_end_ptr; 4604 char * my_ptr; 4605 int i; 4606 4607 my_err = searchfs( my_pathp, &my_search_blk, &my_matches, 0, my_search_options, &my_search_state ); 4608 if ( my_err == -1 ) 4609 my_err = errno; 4610 if ( (my_err == 0 || my_err == EAGAIN) && my_matches > 0 ) { 4611 /* Unpack the results */ 4612 // printf("my_matches %d \n", my_matches); 4613 my_ptr = (char *) &my_result_buffer[0]; 4614 my_end_ptr = (my_ptr + sizeof(my_result_buffer)); 4615 for ( i = 0; i < my_matches; ++i ) { 4616 packed_result_p my_result_p = (packed_result_p) my_ptr; 4617 char * my_name_p; 4618 4619 /* see if we foound all our test files */ 4620 my_name_p = (((char *)(&my_result_p->obj_name)) + my_result_p->obj_name.attr_dataoffset); 4621 if ( memcmp( my_name_p, "foo", 3 ) == 0 || 4622 memcmp( my_name_p, "foobar", 6 ) == 0 || 4623 memcmp( my_name_p, "foofoo", 6 ) == 0 || 4624 memcmp( my_name_p, "xxxfoo", 6 ) == 0 ) { 4625 my_items_found++; 4626 } 4627#if DEBUG 4628 printf("obj_name \"%.*s\" \n", 4629 (int) my_result_p->obj_name.attr_length, 4630 (((char *)(&my_result_p->obj_name)) + 4631 my_result_p->obj_name.attr_dataoffset)); 4632 printf("size %d fid_objno %d fid_generation %d tv_sec 0x%02LX \n", 4633 my_result_p->size, my_result_p->obj_id.fid_objno, 4634 my_result_p->obj_id.fid_generation, 4635 my_result_p->obj_create_time.tv_sec); 4636#endif 4637 my_ptr = (my_ptr + my_result_p->size); 4638 if (my_ptr > my_end_ptr) 4639 break; 4640 } 4641 } 4642 4643 /* EBUSY indicates catalogue change; retry a few times. */ 4644 if ((my_err == EBUSY) && (my_ebusy_count++ < MAX_EBUSY_RETRIES)) { 4645 goto catalogue_changed; 4646 } 4647 if ( !(my_err == 0 || my_err == EAGAIN) ) { 4648 printf( "searchfs failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4649 } 4650 my_search_options &= ~SRCHFS_START; 4651 } while ( my_err == EAGAIN ); 4652 4653 if ( my_items_found < 4 ) { 4654 printf( "searchfs failed to find all test files \n" ); 4655 goto test_failed_exit; 4656 } 4657 4658 my_err = 0; 4659 goto test_passed_exit; 4660 4661test_failed_exit: 4662 my_err = -1; 4663 4664test_passed_exit: 4665 if ( my_pathp != NULL ) { 4666 char * my_ptr = (my_pathp + strlen( my_pathp )); 4667 strcat( my_pathp, "foo" ); 4668 remove( my_pathp ); 4669 *my_ptr = 0x00; 4670 strcat( my_pathp, "foobar" ); 4671 remove( my_pathp ); 4672 *my_ptr = 0x00; 4673 strcat( my_pathp, "foofoo" ); 4674 remove( my_pathp ); 4675 *my_ptr = 0x00; 4676 strcat( my_pathp, "xxxfoo" ); 4677 remove( my_pathp ); 4678 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 4679 } 4680 return( my_err ); 4681#else 4682 printf( "\t--> Not supported on EMBEDDED TARGET\n" ); 4683 return 0; 4684#endif 4685} 4686 4687 4688#define AIO_TESTS_BUFFER_SIZE (1024 * 4000) 4689#define AIO_TESTS_OUR_COUNT 5 4690/* ************************************************************************************************************** 4691 * Test aio_error, aio_read, aio_return, aio_suspend, aio_write, fcntl system calls. 4692 * ************************************************************************************************************** 4693 */ 4694int aio_tests( void * the_argp ) 4695{ 4696 int my_err, i; 4697 char * my_pathp; 4698 struct aiocb * my_aiocbp; 4699 ssize_t my_result; 4700 struct timespec my_timeout; 4701 int my_fd_list[ AIO_TESTS_OUR_COUNT ]; 4702 char * my_buffers[ AIO_TESTS_OUR_COUNT ]; 4703 struct aiocb * my_aiocb_list[ AIO_TESTS_OUR_COUNT ]; 4704 struct aiocb my_aiocbs[ AIO_TESTS_OUR_COUNT ]; 4705 char * my_file_paths[ AIO_TESTS_OUR_COUNT ]; 4706 kern_return_t my_kr; 4707 4708 /* set up to have the ability to fire off up to AIO_TESTS_OUR_COUNT async IOs at once */ 4709 memset( &my_fd_list[0], 0xFF, sizeof( my_fd_list ) ); 4710 memset( &my_buffers[0], 0x00, sizeof( my_buffers ) ); 4711 memset( &my_aiocb_list[0], 0x00, sizeof( my_aiocb_list ) ); 4712 memset( &my_file_paths[0], 0x00, sizeof( my_file_paths ) ); 4713 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) { 4714 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_buffers[ i ], AIO_TESTS_BUFFER_SIZE, VM_FLAGS_ANYWHERE); 4715 if(my_kr != KERN_SUCCESS){ 4716 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4717 goto test_failed_exit; 4718 } 4719 4720 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file_paths[ i ], PATH_MAX, VM_FLAGS_ANYWHERE); 4721 if(my_kr != KERN_SUCCESS){ 4722 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4723 goto test_failed_exit; 4724 } 4725 4726 my_pathp = my_file_paths[ i ]; 4727 *my_pathp = 0x00; 4728 strcat( my_pathp, &g_target_path[0] ); 4729 strcat( my_pathp, "/" ); 4730 4731 /* create a test file */ 4732 my_err = create_random_name( my_pathp, 1 ); 4733 if ( my_err != 0 ) { 4734 goto test_failed_exit; 4735 } 4736 my_fd_list[ i ] = open( my_pathp, O_RDWR, 0 ); 4737 if ( my_fd_list[ i ] <= 0 ) { 4738 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4739 goto test_failed_exit; 4740 } 4741 4742 my_aiocbp = &my_aiocbs[ i ]; 4743 my_aiocb_list[ i ] = my_aiocbp; 4744 memset( my_aiocbp, 0x00, sizeof( *my_aiocbp ) ); 4745 my_aiocbp->aio_fildes = my_fd_list[ i ]; 4746 my_aiocbp->aio_buf = (char *) my_buffers[ i ]; 4747 my_aiocbp->aio_nbytes = 1024; 4748 my_aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; // no signals at completion; 4749 my_aiocbp->aio_sigevent.sigev_signo = 0; 4750 } 4751 4752 /* test direct IO (F_NOCACHE) and aio_write */ 4753 my_err = fcntl( my_fd_list[ 0 ], F_NOCACHE, 1 ); 4754 if ( my_err != 0 ) { 4755 printf( "malloc failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4756 goto test_failed_exit; 4757 } 4758 4759 my_aiocbp = &my_aiocbs[ 0 ]; 4760 my_aiocbp->aio_fildes = my_fd_list[ 0 ]; 4761 my_aiocbp->aio_offset = 4096; 4762 my_aiocbp->aio_buf = my_buffers[ 0 ]; 4763 my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE; 4764 my_aiocbp->aio_reqprio = 0; 4765 my_aiocbp->aio_sigevent.sigev_notify = 0; 4766 my_aiocbp->aio_sigevent.sigev_signo = 0; 4767 my_aiocbp->aio_sigevent.sigev_value.sival_int = 0; 4768 my_aiocbp->aio_sigevent.sigev_notify_function = NULL; 4769 my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL; 4770 my_aiocbp->aio_lio_opcode = 0; 4771 4772 /* write some data */ 4773 memset( my_buffers[ 0 ], 'j', AIO_TESTS_BUFFER_SIZE ); 4774 my_err = aio_write( my_aiocbp ); 4775 if ( my_err != 0 ) { 4776 printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4777 goto test_failed_exit; 4778 } 4779 4780 while ( 1 ) { 4781 my_err = aio_error( my_aiocbp ); 4782 if ( my_err == EINPROGRESS ) { 4783 /* wait for IO to complete */ 4784 sleep( 1 ); 4785 continue; 4786 } 4787 else if ( my_err == 0 ) { 4788 ssize_t my_result; 4789 my_result = aio_return( my_aiocbp ); 4790 break; 4791 } 4792 else { 4793 printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) ); 4794 goto test_failed_exit; 4795 } 4796 } /* while loop */ 4797 4798 /* read some data */ 4799 memset( my_buffers[ 0 ], 'x', AIO_TESTS_BUFFER_SIZE ); 4800 my_err = aio_read( my_aiocbp ); 4801 4802 while ( 1 ) { 4803 my_err = aio_error( my_aiocbp ); 4804 if ( my_err == EINPROGRESS ) { 4805 /* wait for IO to complete */ 4806 sleep( 1 ); 4807 continue; 4808 } 4809 else if ( my_err == 0 ) { 4810 ssize_t my_result; 4811 my_result = aio_return( my_aiocbp ); 4812 4813 if ( *(my_buffers[ 0 ]) != 'j' || *(my_buffers[ 0 ] + AIO_TESTS_BUFFER_SIZE - 1) != 'j' ) { 4814 printf( "aio_read or aio_write failed - wrong data read \n" ); 4815 goto test_failed_exit; 4816 } 4817 break; 4818 } 4819 else { 4820 printf( "aio_read failed with error %d - \"%s\" \n", my_err, strerror( my_err ) ); 4821 goto test_failed_exit; 4822 } 4823 } /* while loop */ 4824 4825 /* test aio_fsync */ 4826 close( my_fd_list[ 0 ] ); 4827 my_fd_list[ 0 ] = open( my_pathp, O_RDWR, 0 ); 4828 if ( my_fd_list[ 0 ] == -1 ) { 4829 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4830 goto test_failed_exit; 4831 } 4832 4833 my_aiocbp = &my_aiocbs[ 0 ]; 4834 my_aiocbp->aio_fildes = my_fd_list[ 0 ]; 4835 my_aiocbp->aio_offset = 0; 4836 my_aiocbp->aio_buf = my_buffers[ 0 ]; 4837 my_aiocbp->aio_nbytes = 1024; 4838 my_aiocbp->aio_reqprio = 0; 4839 my_aiocbp->aio_sigevent.sigev_notify = 0; 4840 my_aiocbp->aio_sigevent.sigev_signo = 0; 4841 my_aiocbp->aio_sigevent.sigev_value.sival_int = 0; 4842 my_aiocbp->aio_sigevent.sigev_notify_function = NULL; 4843 my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL; 4844 my_aiocbp->aio_lio_opcode = 0; 4845 4846 /* write some data */ 4847 memset( my_buffers[ 0 ], 'e', 1024 ); 4848 my_err = aio_write( my_aiocbp ); 4849 if ( my_err != 0 ) { 4850 printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4851 goto test_failed_exit; 4852 } 4853 while ( 1 ) { 4854 my_err = aio_error( my_aiocbp ); 4855 if ( my_err == EINPROGRESS ) { 4856 /* wait for IO to complete */ 4857 sleep( 1 ); 4858 continue; 4859 } 4860 else if ( my_err == 0 ) { 4861 ssize_t my_result; 4862 my_result = aio_return( my_aiocbp ); 4863 break; 4864 } 4865 else { 4866 printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) ); 4867 goto test_failed_exit; 4868 } 4869 } /* while loop */ 4870 4871 my_err = aio_fsync( O_SYNC, my_aiocbp ); 4872 if ( my_err != 0 ) { 4873 printf( "aio_fsync failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4874 goto test_failed_exit; 4875 } 4876 while ( 1 ) { 4877 my_err = aio_error( my_aiocbp ); 4878 if ( my_err == EINPROGRESS ) { 4879 /* wait for IO to complete */ 4880 sleep( 1 ); 4881 continue; 4882 } 4883 else if ( my_err == 0 ) { 4884 aio_return( my_aiocbp ); 4885 break; 4886 } 4887 else { 4888 printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) ); 4889 goto test_failed_exit; 4890 } 4891 } /* while loop */ 4892 4893 /* validate write */ 4894 memset( my_buffers[ 0 ], 0x20, 16 ); 4895 lseek( my_fd_list[ 0 ], 0, SEEK_SET ); 4896 my_result = read( my_fd_list[ 0 ], my_buffers[ 0 ], 16); 4897 if ( my_result == -1 ) { 4898 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4899 goto test_failed_exit; 4900 } 4901 if ( *(my_buffers[ 0 ]) != 'e' || *(my_buffers[ 0 ] + 16 - 1) != 'e' ) { 4902 printf( "aio_fsync or aio_write failed - wrong data read \n" ); 4903 goto test_failed_exit; 4904 } 4905 4906 /* test aio_suspend and lio_listio */ 4907 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) { 4908 memset( my_buffers[ i ], 'a', AIO_TESTS_BUFFER_SIZE ); 4909 my_aiocbp = &my_aiocbs[ i ]; 4910 my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE; 4911 my_aiocbp->aio_lio_opcode = LIO_WRITE; 4912 } 4913 my_err = lio_listio( LIO_NOWAIT, my_aiocb_list, AIO_TESTS_OUR_COUNT, NULL ); 4914 if ( my_err != 0 ) { 4915 printf( "lio_listio call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4916 goto test_failed_exit; 4917 } 4918 4919 my_timeout.tv_sec = 1; 4920 my_timeout.tv_nsec = 0; 4921 my_err = aio_suspend( (const struct aiocb *const*) my_aiocb_list, AIO_TESTS_OUR_COUNT, &my_timeout ); 4922 if ( my_err != 0 ) { 4923 printf( "aio_suspend call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4924 goto test_failed_exit; 4925 } 4926 4927 /* test aio_cancel */ 4928 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) { 4929 my_aiocbp = &my_aiocbs[ i ]; 4930 my_err = aio_cancel( my_aiocbp->aio_fildes, my_aiocbp ); 4931 if ( my_err != AIO_ALLDONE && my_err != AIO_CANCELED && my_err != AIO_NOTCANCELED ) { 4932 printf( "aio_cancel failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4933 goto test_failed_exit; 4934 } 4935 } 4936 4937 my_err = 0; 4938 goto test_passed_exit; 4939 4940test_failed_exit: 4941 my_err = -1; 4942 4943test_passed_exit: 4944 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) { 4945 if ( my_fd_list[ i ] != -1 ) { 4946 close( my_fd_list[ i ] ); 4947 my_fd_list[ i ] = -1; 4948 } 4949 if ( my_file_paths[ i ] != NULL ) { 4950 remove( my_file_paths[ i ] ); 4951 vm_deallocate(mach_task_self(), (vm_address_t)my_file_paths[ i ], PATH_MAX); 4952 my_file_paths[ i ] = NULL; 4953 } 4954 if ( my_buffers[ i ] != NULL ) { 4955 vm_deallocate(mach_task_self(), (vm_address_t)my_buffers[ i ], AIO_TESTS_BUFFER_SIZE); 4956 my_buffers[ i ] = NULL; 4957 } 4958 } 4959 return( my_err ); 4960} 4961 4962 4963/* ************************************************************************************************************** 4964 * Test msgctl, msgget, msgrcv, msgsnd system calls. 4965 * ************************************************************************************************************** 4966 */ 4967int message_queue_tests( void * the_argp ) 4968{ 4969#if !TARGET_OS_EMBEDDED 4970 int my_err; 4971 int my_msg_queue_id = -1; 4972 ssize_t my_result; 4973 struct msqid_ds my_msq_ds; 4974 struct testing_msq_message { 4975 long msq_type; 4976 char msq_buffer[ 32 ]; 4977 } my_msg; 4978 4979 /* get a message queue established for our use */ 4980 my_msg_queue_id = msgget( IPC_PRIVATE, (IPC_CREAT | IPC_EXCL | IPC_R | IPC_W) ); 4981 if ( my_msg_queue_id == -1 ) { 4982 printf( "msgget failed with errno %d - %s \n", errno, strerror( errno ) ); 4983 goto test_failed_exit; 4984 } 4985 4986 /* get some stats on our message queue */ 4987 my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds ); 4988 if ( my_err == -1 ) { 4989 printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) ); 4990 goto test_failed_exit; 4991 } 4992 if ( my_msq_ds.msg_perm.cuid != geteuid( ) ) { 4993 printf( "msgctl IPC_STAT failed to get correct creator uid \n" ); 4994 goto test_failed_exit; 4995 } 4996 if ( (my_msq_ds.msg_perm.mode & (IPC_R | IPC_W)) == 0 ) { 4997 printf( "msgctl IPC_STAT failed to get correct mode \n" ); 4998 goto test_failed_exit; 4999 } 5000 5001 /* put a message into our queue */ 5002 my_msg.msq_type = 1; 5003 strcpy( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" ); 5004 my_err = msgsnd( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0 ); 5005 if ( my_err == -1 ) { 5006 printf( "msgsnd failed with errno %d - %s \n", errno, strerror( errno ) ); 5007 goto test_failed_exit; 5008 } 5009 5010 my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds ); 5011 if ( my_err == -1 ) { 5012 printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) ); 5013 goto test_failed_exit; 5014 } 5015 if ( my_msq_ds.msg_qnum != 1 ) { 5016 printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" ); 5017 goto test_failed_exit; 5018 } 5019 5020 /* pull message off the queue */ 5021 bzero( (void *)&my_msg, sizeof( my_msg ) ); 5022 my_result = msgrcv( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0, 0 ); 5023 if ( my_result == -1 ) { 5024 printf( "msgrcv failed with errno %d - %s \n", errno, strerror( errno ) ); 5025 goto test_failed_exit; 5026 } 5027 if ( my_result != sizeof( my_msg.msq_buffer ) ) { 5028 printf( "msgrcv failed to return the correct number of bytes in our buffer \n" ); 5029 goto test_failed_exit; 5030 } 5031 if ( strcmp( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" ) != 0 ) { 5032 printf( "msgrcv failed to get the correct message \n" ); 5033 goto test_failed_exit; 5034 } 5035 5036 my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds ); 5037 if ( my_err == -1 ) { 5038 printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) ); 5039 goto test_failed_exit; 5040 } 5041 if ( my_msq_ds.msg_qnum != 0 ) { 5042 printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" ); 5043 goto test_failed_exit; 5044 } 5045 5046 /* tear down the message queue */ 5047 my_err = msgctl( my_msg_queue_id, IPC_RMID, NULL ); 5048 if ( my_err == -1 ) { 5049 printf( "msgctl IPC_RMID failed with errno %d - %s \n", errno, strerror( errno ) ); 5050 goto test_failed_exit; 5051 } 5052 my_msg_queue_id = -1; 5053 5054 my_err = 0; 5055 goto test_passed_exit; 5056 5057test_failed_exit: 5058 my_err = -1; 5059 5060test_passed_exit: 5061 if ( my_msg_queue_id != -1 ) { 5062 msgctl( my_msg_queue_id, IPC_RMID, NULL ); 5063 } 5064 return( my_err ); 5065#else 5066 printf( "\t--> Not supported on EMBEDDED TARGET \n" ); 5067 return 0; 5068#endif 5069} 5070 5071 5072 5073/* ************************************************************************************************************** 5074 * Test execution from data and stack areas. 5075 * ************************************************************************************************************** 5076 */ 5077int data_exec_tests( void * the_argp ) 5078{ 5079 int my_err = 0; 5080 int arch, bits; 5081 posix_spawnattr_t attrp; 5082 char *argv[] = { "helpers/data_exec32nonxspawn", NULL }; 5083 5084 int my_pid, my_status, ret; 5085 5086 if ((arch = get_architecture()) == -1) { 5087 printf("data_exec_test: couldn't determine architecture\n"); 5088 goto test_failed_exit; 5089 } 5090 5091 bits = get_bits(); 5092 5093 /* 5094 * If the machine is 64-bit capable, run both the 32 and 64 bit versions of the test. 5095 * Otherwise, just run the 32-bit version. 5096 */ 5097 5098 if (arch == INTEL) { 5099 if (bits == 64) { 5100 if (system("arch -arch x86_64 helpers/data_exec") != 0) { 5101 printf("data_exec-x86_64 failed\n"); 5102 goto test_failed_exit; 5103 } 5104 } 5105 5106 if (system("arch -arch i386 helpers/data_exec") != 0) { 5107 printf("data_exec-i386 failed\n"); 5108 goto test_failed_exit; 5109 } 5110 5111 posix_spawnattr_init(&attrp); 5112 posix_spawnattr_setflags(&attrp, _POSIX_SPAWN_ALLOW_DATA_EXEC ); 5113 ret = posix_spawn(&my_pid, "helpers/data_exec32nonxspawn", NULL, &attrp, argv, NULL); 5114 if (ret) { 5115 printf("data_exec-i386 failed in posix_spawn %s\n", strerror(errno)); 5116 goto test_failed_exit; 5117 } 5118 ret = wait4(my_pid, &my_status, 0, NULL); 5119 if (ret == -1) { 5120 printf("data_exec-i386 wait4 failed with errno %d - %s\n", errno, strerror(errno)); 5121 goto test_failed_exit; 5122 } 5123 if (WEXITSTATUS(my_status) != 0) { 5124 printf("data_exec-i386 _POSIX_SPAWN_ALLOW_DATA_EXEC failed\n"); 5125 goto test_failed_exit; 5126 } 5127 } 5128 5129 /* Add new architectures here similar to the above. */ 5130 5131 goto test_passed_exit; 5132 5133test_failed_exit: 5134 my_err = -1; 5135 5136test_passed_exit: 5137 return my_err; 5138} 5139 5140/* ************************************************************************************************************** 5141 * Test KASLR-related functionality 5142 * ************************************************************************************************************** 5143 */ 5144int kaslr_test( void * the_argp ) 5145{ 5146 int result = 0; 5147 uint64_t slide = 0; 5148 size_t size; 5149 int slide_enabled; 5150 5151 size = sizeof(slide_enabled); 5152 result = sysctlbyname("kern.slide", &slide_enabled, &size, NULL, 0); 5153 if (result != 0) { 5154 printf("sysctlbyname(\"kern.slide\") failed with errno %d\n", errno); 5155 goto test_failed_exit; 5156 } 5157 5158 /* Test positive case first */ 5159 size = sizeof(slide); 5160 result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size); 5161 if (result == 0) { 5162 /* syscall supported, slide must be non-zero if running latest xnu and KASLR is enabled */ 5163 if (slide_enabled && (slide == 0)) { 5164 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported slide of 0x%016llx\n", slide); 5165 goto test_failed_exit; 5166 } 5167 if (size != sizeof(slide)) { 5168 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported size of %lu\n", size); 5169 goto test_failed_exit; 5170 } 5171 } else { 5172 /* Only ENOTSUP is allowed. If so, assume all calls will be unsupported */ 5173 if (errno == ENOTSUP) { 5174 return 0; 5175 } else { 5176 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) returned unexpected errno (errno %d)\n", errno); 5177 goto test_failed_exit; 5178 } 5179 } 5180 5181 /* Negative cases for expected failures */ 5182 size = sizeof(slide); 5183 result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, &size); 5184 if ((result == 0) || (errno != EFAULT)) { 5185 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno); 5186 goto test_failed_exit; 5187 } 5188 5189 size = sizeof(slide) + 1; /* EINVAL */ 5190 result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size); 5191 if ((result == 0) || (errno != EINVAL)) { 5192 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size+1) returned unexpected success or errno (result %d errno %d)\n", result, errno); 5193 goto test_failed_exit; 5194 } 5195 5196 result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, NULL /* EFAULT */); 5197 if ((result == 0) || (errno != EFAULT)) { 5198 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, NULL) returned unexpected success or errno (result %d errno %d)\n", result, errno); 5199 goto test_failed_exit; 5200 } 5201 5202 size = sizeof(slide); 5203 result = kas_info(KAS_INFO_MAX_SELECTOR /* EINVAL */, &slide, &size); 5204 if ((result == 0) || (errno != EINVAL)) { 5205 printf("kas_info(KAS_INFO_MAX_SELECTOR, &slide, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno); 5206 goto test_failed_exit; 5207 } 5208 5209 return 0; 5210 5211test_failed_exit: 5212 return -1; 5213} 5214 5215#if TEST_SYSTEM_CALLS 5216 5217/* ************************************************************************************************************** 5218 * Test xxxxxxxxx system calls. 5219 * ************************************************************************************************************** 5220 */ 5221int sample_test( void * the_argp ) 5222{ 5223 int my_err; 5224 int my_fd = -1; 5225 char * my_pathp = NULL; 5226 kern_return_t my_kr; 5227 5228 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 5229 if(my_kr != KERN_SUCCESS){ 5230 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 5231 goto test_failed_exit; 5232 } 5233 5234 *my_pathp = 0x00; 5235 strcat( my_pathp, &g_target_path[0] ); 5236 strcat( my_pathp, "/" ); 5237 5238 /* create a test file */ 5239 my_err = create_random_name( my_pathp, 1 ); 5240 if ( my_err != 0 ) { 5241 goto test_failed_exit; 5242 } 5243 5244 /* add your test code here... */ 5245 5246 5247 my_err = 0; 5248 goto test_passed_exit; 5249 5250test_failed_exit: 5251 my_err = -1; 5252 5253test_passed_exit: 5254 if ( my_fd != -1 ) 5255 close( my_fd ); 5256 if ( my_pathp != NULL ) { 5257 remove( my_pathp ); 5258 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 5259 } 5260 return( my_err ); 5261} 5262 5263#endif 5264