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 if( my_new_gid1 != my_groups[ i ] ) { 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#if !TARGET_OS_EMBEDDED 1762 /* 1763 * test to make sure setaudit_addr doesn't cause audit info to get lost from 1764 * the credential. 1765 */ 1766 bzero( &my_aia, sizeof(my_aia) ); 1767 my_aia.ai_auid = 442344; 1768 my_aia.ai_asid = AU_ASSIGN_ASID; 1769 my_aia.ai_termid.at_type = AU_IPv4; 1770 my_err = setaudit_addr( &my_aia, sizeof(my_aia) ); 1771 if (my_err != 0) { 1772 printf( "setaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1773 exit( -1 ); 1774 } 1775 1776 my_aia.ai_auid = 0; 1777 my_err = getaudit_addr( &my_aia, sizeof(my_aia) ); 1778 if (my_err != 0) { 1779 printf( "getaudit_addr - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1780 exit( -1 ); 1781 } 1782 //printf("new audit ID is %d \n", my_aia.ai_auid); 1783 1784 if (my_aia.ai_auid != 442344) { 1785 printf("test failed - wrong audit ID was set - %d \n", my_aia.ai_auid); 1786 exit( -1 ); 1787 } 1788#endif 1789 1790 /* change real uid and effective uid to current euid */ 1791 my_err = setuid( my_euid ); 1792 if ( my_err == -1 ) { 1793 printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1794 exit( -1 ); 1795 } 1796 if ( getuid( ) != my_euid ) { 1797 printf( "setuid call failed to set the real uid \n" ); 1798 exit( -1 ); 1799 } 1800 1801 /* change effective uid to current euid - really a NOP */ 1802 my_err = seteuid( my_euid ); 1803 if ( my_err == -1 ) { 1804 printf( "seteuid call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1805 exit( -1 ); 1806 } 1807 if ( geteuid( ) != my_euid ) { 1808 printf( "seteuid call failed to set the original euid \n" ); 1809 exit( -1 ); 1810 } 1811 1812 /* change real uid and effective uid to original real uid */ 1813 my_err = setuid( my_ruid ); 1814 if ( my_err == -1 ) { 1815 printf( "setuid call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1816 exit( -1 ); 1817 } 1818 if ( getuid( ) != my_ruid ) { 1819 printf( "setuid call failed to set the real uid \n" ); 1820 exit( -1 ); 1821 } 1822 1823 exit(0); 1824 } 1825 1826 /* 1827 * parent process - 1828 * wait for child to exit 1829 */ 1830 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 1831 if ( my_wait_pid == -1 ) { 1832 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 1833 goto test_failed_exit; 1834 } 1835 1836 /* wait4 should return our child's pid when it exits */ 1837 if ( my_wait_pid != my_pid ) { 1838 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid, my_pid ); 1839 goto test_failed_exit; 1840 } 1841 1842 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 1843 printf( "wait4 returned wrong exit status - 0x%02X \n", my_status ); 1844 goto test_failed_exit; 1845 } 1846 1847 my_err = 0; 1848 goto test_passed_exit; 1849 1850test_failed_exit: 1851 my_err = -1; 1852 1853test_passed_exit: 1854 return( my_err ); 1855} 1856 1857/* ************************************************************************************************************** 1858 * Test mknod, sync system calls. 1859 * ************************************************************************************************************** 1860 */ 1861int mknod_sync_test( void * the_argp ) 1862{ 1863 int my_err; 1864 char * my_pathp = NULL; 1865 kern_return_t my_kr; 1866 1867 if ( g_skip_setuid_tests != 0 ) { 1868 printf("\t skipping this test \n"); 1869 my_err = 0; 1870 goto test_passed_exit; 1871 } 1872 1873 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 1874 if(my_kr != KERN_SUCCESS){ 1875 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1876 goto test_failed_exit; 1877 } 1878 1879 *my_pathp = 0x00; 1880 strcat( my_pathp, "/dev/" ); 1881 1882 /* get a unique name for our test file */ 1883 my_err = create_random_name( my_pathp, 0 ); 1884 if ( my_err != 0 ) { 1885 goto test_failed_exit; 1886 } 1887 1888 my_err = mknod( my_pathp, (S_IFCHR | S_IRWXU), 0 ); 1889 if ( my_err == -1 ) { 1890 printf( "mknod failed with errno %d - %s \n", errno, strerror( errno ) ); 1891 printf( "path \"%s\" \n", my_pathp ); 1892 goto test_failed_exit; 1893 } 1894 1895 /* not really sure what to do with sync call test */ 1896 sync( ); 1897 my_err = 0; 1898 goto test_passed_exit; 1899 1900test_failed_exit: 1901 my_err = -1; 1902 1903test_passed_exit: 1904 if ( my_pathp != NULL ) { 1905 remove( my_pathp ); 1906 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 1907 } 1908 return( my_err ); 1909} 1910 1911/* ************************************************************************************************************** 1912 * Test chflags, fchflags system calls. 1913 * ************************************************************************************************************** 1914 */ 1915int chflags_fchflags_test( void * the_argp ) 1916{ 1917 int my_err; 1918 int my_fd = -1; 1919 u_int my_flags; 1920 char * my_pathp = NULL; 1921 struct stat my_sb; 1922 kern_return_t my_kr; 1923 1924 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 1925 if(my_kr != KERN_SUCCESS){ 1926 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1927 goto test_failed_exit; 1928 } 1929 1930 *my_pathp = 0x00; 1931 strcat( my_pathp, &g_target_path[0] ); 1932 strcat( my_pathp, "/" ); 1933 1934 /* create a test file */ 1935 my_err = create_random_name( my_pathp, 1 ); 1936 if ( my_err != 0 ) { 1937 goto test_failed_exit; 1938 } 1939 1940 /* make test file unchangable */ 1941 my_err = stat( my_pathp, &my_sb ); 1942 if ( my_err != 0 ) { 1943 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1944 goto test_failed_exit; 1945 } 1946 1947 my_flags = (my_sb.st_flags | UF_IMMUTABLE); 1948 my_err = chflags( my_pathp, my_flags ); 1949 if ( my_err != 0 ) { 1950 printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1951 goto test_failed_exit; 1952 } 1953 1954 /* should fail with EPERM since we cannot change the file now */ 1955 my_fd = open( my_pathp, O_RDWR, 0 ); 1956 if ( my_fd == -1 && errno != EPERM ) { 1957 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1958 printf( "open failed with wrong error - should be EPERM \n" ); 1959 goto test_failed_exit; 1960 } 1961 1962 /* this open should work OK */ 1963 my_fd = open( my_pathp, O_RDONLY, 0 ); 1964 if ( my_fd == -1 ) { 1965 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1966 goto test_failed_exit; 1967 } 1968 1969 my_err = stat( my_pathp, &my_sb ); 1970 if ( my_err != 0 ) { 1971 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1972 goto test_failed_exit; 1973 } 1974 1975 my_flags = (my_sb.st_flags & ~UF_IMMUTABLE); 1976 my_err = fchflags( my_fd, my_flags ); 1977 if ( my_err != 0 ) { 1978 printf( "chflags call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1979 goto test_failed_exit; 1980 } 1981 1982 close( my_fd ); 1983 my_fd = -1; 1984 1985 /* should now work */ 1986 my_fd = open( my_pathp, O_RDWR, 0 ); 1987 if ( my_fd == -1 ) { 1988 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 1989 goto test_failed_exit; 1990 } 1991 1992 my_err = 0; 1993 goto test_passed_exit; 1994 1995test_failed_exit: 1996 my_err = -1; 1997 1998test_passed_exit: 1999 if ( my_fd != -1 ) 2000 close( my_fd ); 2001 if ( my_pathp != NULL ) { 2002 remove( my_pathp ); 2003 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 2004 } 2005 return( my_err ); 2006} 2007 2008 2009/* ************************************************************************************************************** 2010 * Test kill, vfork, execve system calls. 2011 * ************************************************************************************************************** 2012 */ 2013/* There are many new exec() situations to test now that 64-bit is in. These extra tests are in response to 2014 * rdar://4606399 and rdar://4607285. It should cover every permutation of the following variables. 2015 * 2016 * - Current Process "Bitness": 64 or 32 2017 * - exec()'ed process "bitness": 64 or 32 2018 * (if 64 bit, size of page zero:) (4GB or 4KB) 2019 * - Parent Process "Bitness": 64 or 32 2020 2021 * Test to make sure certain inheritance properties of fork()'ed children 2022 * are correctly set. 2023 * 1. 64 bit process forking() 64-bit child, child execing() 64-bit file (4GB pagezero) 2024 * 2. 64 bit process forking() 64-bit child, child execing() 64-bit file (4KB pagezero) 2025 * 3. 64 bit process forking() 64-bit child, child execing() 32-bit file 2026 * 4. 32 bit process forking() 32-bit child, child execing() 32-bit file 2027 * 5. 32 bit process forking() 32-bit child, child execing() 64 bit file (4GB pagezero) 2028 * 6. 32 bit process forking() 32-bit child, child execing() 64 bit file (4KB pagezero) 2029 * 2030 */ 2031 2032 2033int execve_kill_vfork_test( void * the_argp ) 2034{ 2035 int my_err, my_status; 2036 pid_t my_pid, my_wait_pid; 2037 char * errmsg = NULL; 2038 char * argvs[2] = {"", NULL}; 2039 int bits = get_bits(); /* Gets actual processor bit-ness. */ 2040 2041 if (bits != 32 && bits != 64) { 2042 printf("Determination of processor bit-ness failed, get_bits() returned %d.\n", get_bits()); 2043 return(-1); 2044 } 2045 2046 if (get_architecture() == -1) { 2047 errmsg = "get_architecture() could not determine the CPU architecture.\n"; 2048 goto test_failed_exit; 2049 } 2050 2051 if (get_architecture() == INTEL) { 2052 struct stat sb; 2053 2054 if (bits == 64 && sizeof(long) == 8) { 2055 /* 2056 * Running on x86_64 hardware and running in 64-bit mode. 2057 * Check cases 1, 2, 3 and fork a child to check 4, 5, 6. 2058 */ 2059 errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4G pagezero.\n"; 2060 argvs[0] = "sleep-x86_64-4G"; 2061 if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 1)) goto test_failed_exit; 2062 2063 errmsg = "execve failed: from x86_64 forking and exec()ing 64-bit x86_64 process w/ 4K Pagezero.\n"; 2064 argvs[0] = "sleep-x86_64-4K"; 2065 if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 1)) goto test_failed_exit; 2066 2067 errmsg = "execve failed: from x64_64 forking and exec()ing 32-bit i386 process.\n"; 2068 argvs[0] = "sleep-i386"; 2069 if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1)) goto test_failed_exit; 2070 2071 /* Fork off a helper process and load a 32-bit program in it to test 32->64 bit exec(). */ 2072 errmsg = "execve failed to exec the helper process.\n"; 2073 argvs[0] = "launch-i386"; 2074 if (do_execve_test("helpers/launch-i386", argvs, NULL, 1) != 0) goto test_failed_exit; 2075 2076 /* Test posix_spawn for i386, x86_64 (should succeed) */ 2077 errmsg = NULL; 2078 if (do_spawn_test(CPU_TYPE_I386, 0)) 2079 goto test_failed_exit; 2080 if (do_spawn_test(CPU_TYPE_X86_64, 0)) 2081 goto test_failed_exit; 2082 } 2083 else if (bits == 64 && sizeof(long) == 4) { 2084 /* 2085 * Running on x86_64 hardware, but actually running in 32-bit mode. 2086 * Check cases 4, 5, 6 and fork a child to check 1, 2, 3. 2087 */ 2088 errmsg = "execve failed: from i386 forking and exec()ing i386 process.\n"; 2089 argvs[0] = "sleep-i386"; 2090 if (do_execve_test("helpers/sleep-i386", argvs, NULL, 0)) goto test_failed_exit; 2091 2092 errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4G pagezero.\n"; 2093 argvs[0] = "sleep-x86_64-4G"; 2094 if (do_execve_test("helpers/sleep-x86_64-4G", argvs, NULL, 0)) goto test_failed_exit; 2095 2096 errmsg = "execve failed: from i386 forking and exec()ing x86_64 process w/ 4K pagezero.\n"; 2097 argvs[0] = "sleep-x86_64-4K"; 2098 if (do_execve_test("helpers/sleep-x86_64-4K", argvs, NULL, 0)) goto test_failed_exit; 2099 2100 /* Fork off a helper process and load a 64-bit program in it to test 64->32 bit exec(). */ 2101 errmsg = "execve failed to exec the helper process.\n"; 2102 argvs[0] = "launch-x86_64"; 2103 if (do_execve_test("helpers/launch-x86_64", argvs, NULL, 1) != 0) goto test_failed_exit; 2104 2105 /* Test posix_spawn for i386, x86_64 (should succeed) */ 2106 errmsg = NULL; 2107 if (do_spawn_test(CPU_TYPE_I386, 0)) 2108 goto test_failed_exit; 2109 if (do_spawn_test(CPU_TYPE_X86_64, 0)) 2110 goto test_failed_exit; 2111 } 2112 else if (bits == 32) { 2113 /* Running on i386 hardware. Check cases 4. */ 2114 errmsg = "execve failed: from i386 forking and exec()ing 32-bit i386 process.\n"; 2115 argvs[0] = "sleep-i386"; 2116 if (do_execve_test("helpers/sleep-i386", argvs, NULL, 1)) goto test_failed_exit; 2117 2118 /* Test posix_spawn for x86_64 (should fail), i386 (should succeed) */ 2119 errmsg = NULL; 2120 if (do_spawn_test(CPU_TYPE_X86_64, 1)) 2121 goto test_failed_exit; 2122 if (do_spawn_test(CPU_TYPE_I386, 0)) 2123 goto test_failed_exit; 2124 } 2125 } else if(get_architecture() == ARM) { 2126 2127 errmsg = "execve failed: from arm forking and exec()ing 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 ( WIFSIGNALED( my_status ) || ( 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 int acct_record_found; 2871 char * test_bin_name = NULL; 2872 2873 if ( g_skip_setuid_tests != 0 ) { 2874 printf("\t skipping this test \n"); 2875 my_err = 0; 2876 goto test_passed_exit; 2877 } 2878 2879 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 2880 if(my_kr != KERN_SUCCESS){ 2881 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2882 goto test_failed_exit; 2883 } 2884 2885 *my_pathp = 0x00; 2886 strcat( my_pathp, &g_target_path[0] ); 2887 strcat( my_pathp, "/" ); 2888 2889 /* create a test file */ 2890 my_err = create_random_name( my_pathp, 1 ); 2891 if ( my_err != 0 ) { 2892 goto test_failed_exit; 2893 } 2894 2895 /* enable process accounting */ 2896 my_err = acct( my_pathp ); 2897 if ( my_err == -1 ) { 2898 printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2899 goto test_failed_exit; 2900 } 2901 2902 /* 2903 * spin off a child process that we will use for testing. 2904 */ 2905 my_pid = fork( ); 2906 if ( my_pid == -1 ) { 2907 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 2908 goto test_failed_exit; 2909 } 2910 if ( my_pid == 0 ) { 2911 char *argv[2]; /* supply valid argv array to execv() */ 2912 argv[0] = "/usr/bin/true"; 2913 argv[1] = 0; 2914 2915 /* 2916 * child process - do a little work then exit. 2917 */ 2918 my_err = execv( argv[0], argv); 2919 exit( 0 ); 2920 } 2921 2922 /* parent process - 2923 * wait for child to exit 2924 */ 2925 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 2926 if ( my_wait_pid == -1 ) { 2927 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 2928 goto test_failed_exit; 2929 } 2930 2931 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 2932 printf("unexpected child exit status for accounting test load: %d\n", WEXITSTATUS( my_status)); 2933 goto test_failed_exit; 2934 } 2935 2936 /* disable process accounting */ 2937 my_err = acct( NULL ); 2938 if ( my_err == -1 ) { 2939 printf( "acct failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2940 goto test_failed_exit; 2941 } 2942 2943 /* now verify that there is accounting info in the log file */ 2944 my_fd = open( my_pathp, O_RDONLY, 0 ); 2945 if ( my_fd == -1 ) { 2946 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2947 goto test_failed_exit; 2948 } 2949 2950 lseek( my_fd, 0, SEEK_SET ); 2951 bzero( (void *)&my_buffer[0], sizeof(my_buffer) ); 2952 acct_record_found = 0; 2953 test_bin_name = "true"; 2954 2955 while(1) { 2956 2957 my_count = read( my_fd, &my_buffer[0], sizeof(struct acct) ); 2958 2959 if ( my_count == -1 ) { 2960 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 2961 goto test_failed_exit; 2962 } 2963 2964 if ( my_count < sizeof(struct acct)) { 2965 /* Indicates EOF or misaligned file size */ 2966 printf("Reached end of accounting records with last read count: %d\n", my_count); 2967 break; 2968 } 2969 2970 my_acctp = (struct acct *) &my_buffer[0]; 2971 /* first letters in ac_comm should match the name of the executable */ 2972 if ( (getuid() == my_acctp->ac_uid) && (getgid() == my_acctp->ac_gid) && 2973 (!strncmp(my_acctp->ac_comm, test_bin_name, strlen(test_bin_name))) ) { 2974 /* Expected accounting record found */ 2975 acct_record_found = 1; 2976 break; 2977 } 2978 2979 } 2980 2981 if (acct_record_found) { 2982 my_err = 0; 2983 goto test_passed_exit; 2984 } else { 2985 printf( "------------------------\n" ); 2986 printf( "Expected Accounting Record for child process %s not found\n", test_bin_name ); 2987 printf( "Expected uid: %lu Expected gid: %lu\n" , (unsigned long) getuid(), (unsigned long) getgid() ); 2988 printf( "Account file path: %s\n", my_pathp ); 2989 goto test_failed_exit; 2990 } 2991 2992test_failed_exit: 2993 my_err = -1; 2994 2995test_passed_exit: 2996 if ( my_fd != -1 ) 2997 close( my_fd ); 2998 if ( my_pathp != NULL ) { 2999 remove( my_pathp ); 3000 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3001 } 3002 return( my_err ); 3003} 3004 3005void print_acct_debug_strings( char * my_ac_comm ) 3006{ 3007 char my_cmd_str[11]; /* sizeof(acct_cmd) + 1 for '\0' if acct_cmd is bogus */ 3008 char my_hex_str[128]; 3009 int i; 3010 3011 my_hex_str[0] = '\0'; 3012 for(i = 0; i < 10; i++) 3013 { 3014 sprintf( my_hex_str, "%s \'0x%x\' ", my_hex_str, my_ac_comm[i]); 3015 } 3016 3017 memccpy(my_cmd_str, my_ac_comm, '\0', 10); 3018 my_cmd_str[10] = '\0'; /* In case ac_comm was bogus */ 3019 3020 3021 printf( "my_acctp->ac_comm = \"%s\" (should begin with: \"tr\")\n", my_cmd_str); 3022 printf( "my_acctp->ac_comm = \"%s\"\n", my_hex_str); 3023 printf( "------------------------\n" ); 3024} 3025 3026 3027/* ************************************************************************************************************** 3028 * Test ioctl system calls. 3029 * ************************************************************************************************************** 3030 */ 3031int ioctl_test( void * the_argp ) 3032{ 3033 int my_err, my_result; 3034 int my_fd = -1; 3035 struct statfs * my_infop; 3036 char * my_ptr; 3037 int my_blksize; 3038 long long my_block_count; 3039 char my_name[ 128 ]; 3040 3041 my_result = getmntinfo( &my_infop, MNT_NOWAIT ); 3042 if ( my_result < 1 ) { 3043 printf( "getmntinfo failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3044 goto test_failed_exit; 3045 } 3046 3047 /* make this a raw device */ 3048 strcpy( &my_name[0], &my_infop->f_mntfromname[0] ); 3049 if ( (my_ptr = strrchr( &my_name[0], '/' )) != 0 ) { 3050 if ( my_ptr[1] != 'r' ) { 3051 my_ptr[ strlen( my_ptr ) ] = 0x00; 3052 memmove( &my_ptr[2], &my_ptr[1], (strlen( &my_ptr[1] ) + 1) ); 3053 my_ptr[1] = 'r'; 3054 } 3055 } 3056 3057 my_fd = open(&my_name[0], O_RDONLY ); 3058 if ( my_fd == -1 ) { 3059 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3060 goto test_failed_exit; 3061 } 3062 3063 /* obtain the size of the media (in blocks) */ 3064 my_err = ioctl( my_fd, DKIOCGETBLOCKCOUNT, &my_block_count ); 3065 if ( my_err == -1 ) { 3066 printf( "ioctl DKIOCGETBLOCKCOUNT failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3067 goto test_failed_exit; 3068 } 3069 3070 /* obtain the block size of the media */ 3071 my_err = ioctl( my_fd, DKIOCGETBLOCKSIZE, &my_blksize ); 3072 if ( my_err == -1 ) { 3073 printf( "ioctl DKIOCGETBLOCKSIZE failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3074 goto test_failed_exit; 3075 } 3076 //printf( "my_block_count %qd my_blksize %d \n", my_block_count, my_blksize ); 3077 3078 /* make sure the returned data looks somewhat valid */ 3079 if ( my_blksize < 0 || my_blksize > (1024 * 1000) ) { 3080 printf( "ioctl appears to have returned incorrect block size data \n" ); 3081 goto test_failed_exit; 3082 } 3083 3084 my_err = 0; 3085 goto test_passed_exit; 3086 3087test_failed_exit: 3088 my_err = -1; 3089 3090test_passed_exit: 3091 if ( my_fd != -1 ) 3092 close( my_fd ); 3093 return( my_err ); 3094} 3095 3096/* ************************************************************************************************************** 3097 * Test mkdir, rmdir, umask system calls. 3098 * ************************************************************************************************************** 3099 */ 3100int mkdir_rmdir_umask_test( void * the_argp ) 3101{ 3102 int my_err; 3103 int my_fd = -1; 3104 int did_umask = 0; 3105 char * my_pathp = NULL; 3106 mode_t my_orig_mask; 3107 struct stat my_sb; 3108 kern_return_t my_kr; 3109 3110 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3111 if(my_kr != KERN_SUCCESS){ 3112 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3113 goto test_failed_exit; 3114 } 3115 3116 *my_pathp = 0x00; 3117 strcat( my_pathp, &g_target_path[0] ); 3118 strcat( my_pathp, "/" ); 3119 3120 /* get a unique name to use with mkdir */ 3121 my_err = create_random_name( my_pathp, 0 ); 3122 if ( my_err != 0 ) { 3123 printf( "create_random_name failed with error %d\n", my_err ); 3124 goto test_failed_exit; 3125 } 3126 3127 /* set umask to clear WX for other and group and clear X for user */ 3128 my_orig_mask = umask( (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) ); 3129 did_umask = 1; 3130 3131 /* create a directory with RWX for user, group, other (which should be limited by umask) */ 3132 my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) ); 3133 if ( my_err == -1 ) { 3134 printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3135 goto test_failed_exit; 3136 } 3137 3138 /* verify results - (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH) should be clear*/ 3139 my_err = stat( my_pathp, &my_sb ); 3140 if ( my_err != 0 ) { 3141 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3142 goto test_failed_exit; 3143 } 3144 if ( (my_sb.st_mode & (S_IXUSR | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH)) != 0 ) { 3145 printf( "umask did not limit modes as it should have \n" ); 3146 goto test_failed_exit; 3147 } 3148 3149 /* get rid of our test directory */ 3150 my_err = rmdir( my_pathp ); 3151 if ( my_err == -1 ) { 3152 printf( "rmdir failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3153 goto test_failed_exit; 3154 } 3155 my_err = 0; 3156 goto test_passed_exit; 3157 3158test_failed_exit: 3159 my_err = -1; 3160 3161test_passed_exit: 3162 if ( my_fd != -1 ) 3163 close( my_fd ); 3164 if ( my_pathp != NULL ) { 3165 rmdir( my_pathp ); 3166 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3167 } 3168 if ( did_umask != 0 ) { 3169 umask( my_orig_mask ); 3170 } 3171 3172 return( my_err ); 3173} 3174 3175/* ************************************************************************************************************** 3176 * Test chroot system call. 3177 * ************************************************************************************************************** 3178 */ 3179int chroot_test( void * the_argp ) 3180{ 3181 int my_err, my_status; 3182 pid_t my_pid, my_wait_pid; 3183 char * my_pathp = NULL; 3184 kern_return_t my_kr; 3185 3186 if ( g_skip_setuid_tests != 0 ) { 3187 printf("\t skipping this test \n"); 3188 my_err = 0; 3189 goto test_passed_exit; 3190 } 3191 3192 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3193 if(my_kr != KERN_SUCCESS){ 3194 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3195 goto test_failed_exit; 3196 } 3197 3198 *my_pathp = 0x00; 3199 strcat( my_pathp, &g_target_path[0] ); 3200 strcat( my_pathp, "/" ); 3201 3202 /* get a unique name for our test directory */ 3203 my_err = create_random_name( my_pathp, 0 ); 3204 if ( my_err != 0 ) { 3205 goto test_failed_exit; 3206 } 3207 3208 /* create a test directory */ 3209 my_err = mkdir( my_pathp, (S_IRWXU | S_IRWXG | S_IRWXO) ); 3210 if ( my_err == -1 ) { 3211 printf( "mkdir failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3212 goto test_failed_exit; 3213 } 3214 3215 /* 3216 * spin off a child process that we will use for testing. 3217 */ 3218 my_pid = fork( ); 3219 if ( my_pid == -1 ) { 3220 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 3221 goto test_failed_exit; 3222 } 3223 if ( my_pid == 0 ) { 3224 /* 3225 * child process - do getlogin and setlogin testing. 3226 */ 3227 struct stat my_sb; 3228 3229 /* change our root to our new test directory */ 3230 my_err = chroot( my_pathp ); 3231 if ( my_err != 0 ) { 3232 printf( "chroot failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3233 exit( -1 ); 3234 } 3235 3236 /* verify root directory is now an empty directory */ 3237 my_err = stat( "/", &my_sb ); 3238 if ( my_err != 0 ) { 3239 printf( "stat call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3240 exit( -1 ); 3241 } 3242 if ( my_sb.st_nlink > 2 ) { 3243 printf( "root dir should be emnpty! \n" ); 3244 exit( -1 ); 3245 } 3246 exit( 0 ); 3247 } 3248 3249 /* parent process - 3250 * wait for child to exit 3251 */ 3252 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 3253 if ( my_wait_pid == -1 ) { 3254 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 3255 goto test_failed_exit; 3256 } 3257 3258 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 3259 printf( "bad exit status\n" ); 3260 goto test_failed_exit; 3261 } 3262 3263 my_err = 0; 3264 goto test_passed_exit; 3265 3266test_failed_exit: 3267 my_err = -1; 3268 3269test_passed_exit: 3270 if ( my_pathp != NULL ) { 3271 my_err = rmdir( my_pathp ); 3272 if ( my_err != 0 ) { 3273 printf( "rmdir failed with error %d - \"%s\" path %p\n", errno, strerror( errno), my_pathp ); 3274 } 3275 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3276 } 3277 return( my_err ); 3278} 3279 3280/* ************************************************************************************************************** 3281 * Test getpgrp, getpgid, getsid, setpgid, setpgrp, setsid system calls. 3282 * ************************************************************************************************************** 3283 */ 3284int process_group_test( void * the_argp ) 3285{ 3286 int my_err = 0, i = 0; 3287 pid_t my_session_id, my_pid, my_process_group; 3288 3289 /* get current session ID, pgid, and pid */ 3290 my_session_id = getsid( 0 ); 3291 if ( my_session_id == -1 ) { 3292 printf( "getsid call failed with error %d - \"%s\" \n", 3293 errno, strerror( errno ) ); 3294 goto test_failed_exit; 3295 } 3296 3297 my_pid = getpid( ); 3298 my_process_group = getpgrp( ); 3299 3300 /* test getpgrp and getpgid - they should return the same results when 0 is passed to getpgid */ 3301 if ( my_process_group != getpgid( 0 ) ) { 3302 printf( "getpgrp and getpgid did not return the same process group ID \n" ); 3303 printf( "getpgid: %d, my_process_group: %d\n", getpgid( 0 ), my_process_group ); 3304 goto test_failed_exit; 3305 } 3306 3307 if ( my_pid == my_process_group ) { 3308 /* we are process group leader */ 3309 my_err = setsid( ); 3310 if ( my_err == 0 || errno != EPERM ) { 3311 printf( "setsid call should have failed with EPERM\n" ); 3312 goto test_failed_exit; 3313 } 3314 } else { 3315 /* we are not process group leader: try creating new session */ 3316 my_err = setsid( ); 3317 if ( my_err == -1 ) { 3318 printf( "setsid call failed with error %d - \"%s\" \n", 3319 errno, strerror( errno ) ); 3320 goto test_failed_exit; 3321 } 3322 3323 if ( my_process_group == getpgid( 0 ) ) { 3324 printf( "process group was not reset \n" ); 3325 goto test_failed_exit; 3326 } 3327 } 3328 3329 /* find an unused process group ID */ 3330 for ( i = 10000; i < 1000000; i++ ) { 3331 my_process_group = getpgid( i ); 3332 if ( my_process_group == -1 ) { 3333 break; 3334 } 3335 } 3336 3337 /* this should fail */ 3338 my_err = setpgid( 0, my_process_group ); 3339 if ( my_err != -1 ) { 3340 printf( "setpgid should have failed, but did not \n" ); 3341 goto test_failed_exit; 3342 } 3343 3344 my_err = 0; 3345 goto test_passed_exit; 3346 3347test_failed_exit: 3348 my_err = -1; 3349 3350test_passed_exit: 3351 return( my_err ); 3352} 3353 3354/* ************************************************************************************************************** 3355 * Test fcntl system calls. 3356 * ************************************************************************************************************** 3357 */ 3358int fcntl_test( void * the_argp ) 3359{ 3360 int my_err, my_result, my_tmep; 3361 int my_fd = -1; 3362 int my_newfd = -1; 3363 char * my_pathp = NULL; 3364 kern_return_t my_kr; 3365 3366 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3367 if(my_kr != KERN_SUCCESS){ 3368 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3369 goto test_failed_exit; 3370 } 3371 3372 *my_pathp = 0x00; 3373 strcat( my_pathp, &g_target_path[0] ); 3374 strcat( my_pathp, "/" ); 3375 3376 /* create a test file */ 3377 my_err = create_random_name( my_pathp, 1 ); 3378 if ( my_err != 0 ) { 3379 goto test_failed_exit; 3380 } 3381 3382 /* open our test file and use fcntl to get / set file descriptor flags */ 3383 my_fd = open( my_pathp, O_RDONLY, 0 ); 3384 if ( my_fd == -1 ) { 3385 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3386 goto test_failed_exit; 3387 } 3388 3389 my_result = fcntl( my_fd, F_GETFD, 0 ); 3390 if ( my_result == -1 ) { 3391 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3392 goto test_failed_exit; 3393 } 3394 3395 my_tmep = (my_result & FD_CLOEXEC); 3396 if ( my_tmep ) { 3397 /* FD_CLOEXEC is on, let's turn it off */ 3398 my_result = fcntl( my_fd, F_SETFD, 0 ); 3399 } 3400 else { 3401 /* FD_CLOEXEC is off, let's turn it on */ 3402 my_result = fcntl( my_fd, F_SETFD, 1 ); 3403 } 3404 if ( my_result == -1 ) { 3405 printf( "fcntl - F_SETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3406 goto test_failed_exit; 3407 } 3408 3409 /* now check to see if it is set correctly */ 3410 my_result = fcntl( my_fd, F_GETFD, 0 ); 3411 if ( my_result == -1 ) { 3412 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3413 goto test_failed_exit; 3414 } 3415 if ( my_tmep == (my_result & 0x01) ) { 3416 printf( "fcntl - F_SETFD failed to set FD_CLOEXEC correctly!!! \n" ); 3417 goto test_failed_exit; 3418 } 3419 3420 /* dup it to a new fd with FD_CLOEXEC forced on */ 3421 3422 my_result = fcntl( my_fd, F_DUPFD_CLOEXEC, 0); 3423 if ( my_result == -1 ) { 3424 printf( "fcntl - F_DUPFD_CLOEXEC - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3425 goto test_failed_exit; 3426 } 3427 my_newfd = my_result; 3428 3429 /* check to see that it too is marked with FD_CLOEXEC */ 3430 3431 my_result = fcntl( my_newfd, F_GETFD, 0); 3432 if ( my_result == -1 ) { 3433 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3434 goto test_failed_exit; 3435 } 3436 if ( (my_result & FD_CLOEXEC) == 0 ) { 3437 printf( "fcntl - F_DUPFD_CLOEXEC failed to set FD_CLOEXEC!!! \n" ); 3438 goto test_failed_exit; 3439 } 3440 3441 close( my_newfd ); 3442 my_newfd = -1; 3443 3444#if !TARGET_OS_EMBEDDED /* This section of the test is specific for the desktop platform, refer <rdar://problem/8850905>*/ 3445 /* While we're here, dup it via an open of /dev/fd/<fd> .. */ 3446 3447 { 3448 char devfdpath[PATH_MAX]; 3449 3450 (void) snprintf( devfdpath, sizeof (devfdpath), 3451 "/dev/fd/%u", my_fd ); 3452 my_result = open( devfdpath, O_RDONLY | O_CLOEXEC ); 3453 } 3454 if ( my_result == -1 ) { 3455 printf( "open call failed on /dev/fd/%u with error %d - \"%s\" \n", my_fd, errno, strerror( errno) ); 3456 goto test_failed_exit; 3457 } 3458 my_newfd = my_result; 3459 3460 /* check to see that it too is marked with FD_CLOEXEC */ 3461 3462 my_result = fcntl( my_newfd, F_GETFD, 0); 3463 if ( my_result == -1 ) { 3464 printf( "fcntl - F_GETFD - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3465 goto test_failed_exit; 3466 } 3467 if ( (my_result & FD_CLOEXEC) == 0 ) { 3468 printf( "fcntl - O_CLOEXEC open of /dev/fd/%u failed to set FD_CLOEXEC!!! \n", my_fd ); 3469 goto test_failed_exit; 3470 } 3471 close ( my_newfd ); 3472 my_newfd = -1; 3473#endif 3474 my_err = 0; 3475 goto test_passed_exit; 3476 3477test_failed_exit: 3478 my_err = -1; 3479 3480test_passed_exit: 3481 if ( my_newfd != -1) 3482 close ( my_newfd ); 3483 if ( my_fd != -1 ) 3484 close( my_fd ); 3485 if ( my_pathp != NULL ) { 3486 remove( my_pathp ); 3487 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3488 } 3489 return( my_err ); 3490} 3491 3492/* ************************************************************************************************************** 3493 * Test getpriority, setpriority system calls. 3494 * ************************************************************************************************************** 3495 */ 3496int getpriority_setpriority_test( void * the_argp ) 3497{ 3498 int my_err; 3499 int my_priority; 3500 int my_new_priority; 3501 3502 /* getpriority returns scheduling priority so -1 is a valid value */ 3503 errno = 0; 3504 my_priority = getpriority( PRIO_PROCESS, 0 ); 3505 if ( my_priority == -1 && errno != 0 ) { 3506 printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3507 goto test_failed_exit; 3508 } 3509 3510 /* change scheduling priority */ 3511 my_new_priority = (my_priority == PRIO_MIN) ? (my_priority + 10) : (PRIO_MIN); 3512 my_err = setpriority( PRIO_PROCESS, 0, my_new_priority ); 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 /* verify change */ 3519 errno = 0; 3520 my_priority = getpriority( PRIO_PROCESS, 0 ); 3521 if ( my_priority == -1 && errno != 0 ) { 3522 printf( "getpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3523 goto test_failed_exit; 3524 } 3525 3526 if ( my_priority != my_new_priority ) { 3527 printf( "setpriority - failed to set correct scheduling priority \n" ); 3528 goto test_failed_exit; 3529 } 3530 3531 /* reset scheduling priority */ 3532 my_err = setpriority( PRIO_PROCESS, 0, 0 ); 3533 if ( my_err == -1 ) { 3534 printf( "setpriority - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3535 goto test_failed_exit; 3536 } 3537 3538 my_err = 0; 3539 goto test_passed_exit; 3540 3541test_failed_exit: 3542 my_err = -1; 3543 3544test_passed_exit: 3545 return( my_err ); 3546} 3547 3548/* ************************************************************************************************************** 3549 * Test futimes, gettimeofday, settimeofday, utimes system calls. 3550 * ************************************************************************************************************** 3551 */ 3552int time_tests( void * the_argp ) 3553{ 3554 int my_err; 3555 int my_fd = -1; 3556 char * my_pathp = NULL; 3557 struct timeval my_orig_time; 3558 struct timeval my_temp_time; 3559 struct timeval my_utimes[4]; 3560 struct timezone my_tz; 3561 struct stat my_sb; 3562 kern_return_t my_kr; 3563 3564 if ( g_skip_setuid_tests != 0 ) { 3565 printf( "\t skipping this test \n" ); 3566 my_err = 0; 3567 goto test_passed_exit; 3568 } 3569 3570 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3571 if(my_kr != KERN_SUCCESS){ 3572 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3573 goto test_failed_exit; 3574 } 3575 3576 *my_pathp = 0x00; 3577 strcat( my_pathp, &g_target_path[0] ); 3578 strcat( my_pathp, "/" ); 3579 3580 /* create a test file */ 3581 my_err = create_random_name( my_pathp, 1 ); 3582 if ( my_err != 0 ) { 3583 goto test_failed_exit; 3584 } 3585 3586 my_err = gettimeofday( &my_orig_time, &my_tz ); 3587 if ( my_err == -1 ) { 3588 printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3589 goto test_failed_exit; 3590 } 3591 //printf( "tv_sec %d tv_usec %ld \n", my_orig_time.tv_sec, my_orig_time.tv_usec ); 3592 3593 my_temp_time = my_orig_time; 3594 my_temp_time.tv_sec -= 60; 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 my_err = gettimeofday( &my_temp_time, NULL ); 3602 if ( my_err == -1 ) { 3603 printf( "gettimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3604 goto test_failed_exit; 3605 } 3606 //printf( "tv_sec %d tv_usec %ld \n", my_temp_time.tv_sec, my_temp_time.tv_usec ); 3607 if ( my_orig_time.tv_sec <= my_temp_time.tv_sec ) { 3608 printf( "settimeofday did not set correct time \n" ); 3609 goto test_failed_exit; 3610 } 3611 3612 /* set time back to original value plus 1 second */ 3613 my_temp_time = my_orig_time; 3614 my_temp_time.tv_sec += 1; 3615 my_err = settimeofday( &my_temp_time, NULL ); 3616 if ( my_err == -1 ) { 3617 printf( "settimeofday - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3618 goto test_failed_exit; 3619 } 3620 3621 /* test utimes and futimes - get current access and mod times then change them */ 3622 my_err = stat( my_pathp, &my_sb ); 3623 if ( my_err != 0 ) { 3624 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3625 goto test_failed_exit; 3626 } 3627 TIMESPEC_TO_TIMEVAL( &my_utimes[0], &my_sb.st_atimespec ); 3628 TIMESPEC_TO_TIMEVAL( &my_utimes[1], &my_sb.st_mtimespec ); 3629 my_utimes[0].tv_sec -= 120; /* make access time 2 minutes older */ 3630 my_utimes[1].tv_sec -= 120; /* make mod time 2 minutes older */ 3631 3632 my_err = utimes( my_pathp, &my_utimes[0] ); 3633 if ( my_err == -1 ) { 3634 printf( "utimes - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3635 goto test_failed_exit; 3636 } 3637 3638 /* make sure the correct times are set */ 3639 my_err = stat( my_pathp, &my_sb ); 3640 if ( my_err != 0 ) { 3641 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3642 goto test_failed_exit; 3643 } 3644 TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec ); 3645 TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec ); 3646 if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec || 3647 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) { 3648 printf( "utimes failed to set access and mod times \n" ); 3649 goto test_failed_exit; 3650 } 3651 3652 my_fd = open( my_pathp, O_RDWR, 0 ); 3653 if ( my_fd == -1 ) { 3654 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3655 goto test_failed_exit; 3656 } 3657 3658 my_utimes[0].tv_sec -= 120; /* make access time 2 minutes older */ 3659 my_utimes[1].tv_sec -= 120; /* make mod time 2 minutes older */ 3660 my_err = futimes( my_fd, &my_utimes[0] ); 3661 if ( my_err == -1 ) { 3662 printf( "futimes - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3663 goto test_failed_exit; 3664 } 3665 3666 /* make sure the correct times are set */ 3667 my_err = stat( my_pathp, &my_sb ); 3668 if ( my_err != 0 ) { 3669 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3670 goto test_failed_exit; 3671 } 3672 TIMESPEC_TO_TIMEVAL( &my_utimes[2], &my_sb.st_atimespec ); 3673 TIMESPEC_TO_TIMEVAL( &my_utimes[3], &my_sb.st_mtimespec ); 3674 if ( my_utimes[0].tv_sec != my_utimes[2].tv_sec || 3675 my_utimes[1].tv_sec != my_utimes[3].tv_sec ) { 3676 printf( "futimes failed to set access and mod times \n" ); 3677 goto test_failed_exit; 3678 } 3679 3680 my_err = 0; 3681 goto test_passed_exit; 3682 3683test_failed_exit: 3684 my_err = -1; 3685 3686test_passed_exit: 3687 if ( my_fd != -1 ) 3688 close( my_fd ); 3689 if ( my_pathp != NULL ) { 3690 remove( my_pathp ); 3691 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3692 } 3693 return( my_err ); 3694} 3695 3696/* ************************************************************************************************************** 3697 * Test rename, stat system calls. 3698 * ************************************************************************************************************** 3699 */ 3700int rename_test( void * the_argp ) 3701{ 3702 int my_err; 3703 char * my_pathp = NULL; 3704 char * my_new_pathp = NULL; 3705 ino_t my_file_id; 3706 struct stat my_sb; 3707 kern_return_t my_kr; 3708 3709 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3710 if(my_kr != KERN_SUCCESS){ 3711 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3712 goto test_failed_exit; 3713 } 3714 3715 *my_pathp = 0x00; 3716 strcat( my_pathp, &g_target_path[0] ); 3717 strcat( my_pathp, "/" ); 3718 3719 /* create a test file */ 3720 my_err = create_random_name( my_pathp, 1 ); 3721 if ( my_err != 0 ) { 3722 goto test_failed_exit; 3723 } 3724 3725 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_new_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3726 if(my_kr != KERN_SUCCESS){ 3727 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3728 goto test_failed_exit; 3729 } 3730 3731 *my_new_pathp = 0x00; 3732 strcat( my_new_pathp, &g_target_path[0] ); 3733 strcat( my_new_pathp, "/" ); 3734 3735 /* get a unique name for our rename test */ 3736 my_err = create_random_name( my_new_pathp, 0 ); 3737 if ( my_err != 0 ) { 3738 goto test_failed_exit; 3739 } 3740 3741 /* save file ID for later use */ 3742 my_err = stat( my_pathp, &my_sb ); 3743 if ( my_err != 0 ) { 3744 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3745 goto test_failed_exit; 3746 } 3747 my_file_id = my_sb.st_ino; 3748 3749 /* test rename */ 3750 my_err = rename( my_pathp, my_new_pathp ); 3751 if ( my_err == -1 ) { 3752 printf( "rename - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3753 goto test_failed_exit; 3754 } 3755 3756 /* make sure old name is no longer there */ 3757 my_err = stat( my_pathp, &my_sb ); 3758 if ( my_err == 0 ) { 3759 printf( "rename call failed - found old name \n" ); 3760 goto test_failed_exit; 3761 } 3762 3763 /* make sure new name is there and is correct file id */ 3764 my_err = stat( my_new_pathp, &my_sb ); 3765 if ( my_err != 0 ) { 3766 printf( "stat - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3767 goto test_failed_exit; 3768 } 3769 if ( my_file_id != my_sb.st_ino ) { 3770 printf( "rename failed - wrong file id \n" ); 3771 goto test_failed_exit; 3772 } 3773 3774 my_err = 0; 3775 goto test_passed_exit; 3776 3777test_failed_exit: 3778 my_err = -1; 3779 3780test_passed_exit: 3781 if ( my_pathp != NULL ) { 3782 remove( my_pathp ); 3783 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3784 } 3785 if ( my_new_pathp != NULL ) { 3786 remove( my_new_pathp ); 3787 vm_deallocate(mach_task_self(), (vm_address_t)my_new_pathp, PATH_MAX); 3788 } 3789 return( my_err ); 3790} 3791 3792/* ************************************************************************************************************** 3793 * Test locking system calls. 3794 * ************************************************************************************************************** 3795 */ 3796int locking_test( void * the_argp ) 3797{ 3798 int my_err, my_status; 3799 pid_t my_pid, my_wait_pid; 3800 int my_fd = -1; 3801 char * my_pathp = NULL; 3802 kern_return_t my_kr; 3803 3804 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3805 if(my_kr != KERN_SUCCESS){ 3806 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3807 goto test_failed_exit; 3808 } 3809 3810 *my_pathp = 0x00; 3811 strcat( my_pathp, &g_target_path[0] ); 3812 strcat( my_pathp, "/" ); 3813 3814 /* create a test file */ 3815 my_err = create_random_name( my_pathp, 1 ); 3816 if ( my_err != 0 ) { 3817 goto test_failed_exit; 3818 } 3819 3820 /* test flock */ 3821 my_fd = open( my_pathp, O_RDWR, 0 ); 3822 if ( my_fd == -1 ) { 3823 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3824 goto test_failed_exit; 3825 } 3826 3827 my_err = flock( my_fd, LOCK_EX ); 3828 if ( my_err == -1 ) { 3829 printf( "flock - LOCK_EX - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3830 goto test_failed_exit; 3831 } 3832 3833 /* 3834 * spin off a child process that we will use for testing. 3835 */ 3836 my_pid = fork( ); 3837 if ( my_pid == -1 ) { 3838 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 3839 goto test_failed_exit; 3840 } 3841 if ( my_pid == 0 ) { 3842 /* 3843 * child process. 3844 */ 3845 int my_child_fd = -1; 3846 int my_child_err; 3847 3848 my_child_fd = open( my_pathp, O_RDWR, 0 ); 3849 if ( my_child_fd == -1 ) { 3850 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3851 my_child_err = -1; 3852 goto child_exit; 3853 } 3854 3855 my_err = flock( my_child_fd, (LOCK_EX | LOCK_NB) ); 3856 if ( my_err == -1 ) { 3857 if ( errno != EWOULDBLOCK ) { 3858 printf( "flock call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3859 my_child_err = -1; 3860 goto child_exit; 3861 } 3862 } 3863 else { 3864 printf( "flock call should have failed with EWOULDBLOCK err \n" ); 3865 my_child_err = -1; 3866 goto child_exit; 3867 } 3868 my_child_err = 0; 3869child_exit: 3870 if ( my_child_fd != -1 ) 3871 close( my_child_fd ); 3872 exit( my_child_err ); 3873 } 3874 3875 /* parent process - 3876 * wait for child to exit 3877 */ 3878 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 3879 if ( my_wait_pid == -1 ) { 3880 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 3881 goto test_failed_exit; 3882 } 3883 3884 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 3885 goto test_failed_exit; 3886 } 3887 3888 my_err = flock( my_fd, LOCK_UN ); 3889 if ( my_err == -1 ) { 3890 printf( "flock - LOCK_UN - failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3891 goto test_failed_exit; 3892 } 3893 3894 my_err = 0; 3895 goto test_passed_exit; 3896 3897test_failed_exit: 3898 my_err = -1; 3899 3900test_passed_exit: 3901 if ( my_fd != -1 ) 3902 close( my_fd ); 3903 if ( my_pathp != NULL ) { 3904 remove( my_pathp ); 3905 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 3906 } 3907 return( my_err ); 3908} 3909 3910/* ************************************************************************************************************** 3911 * Test mkfifo system calls. 3912 * ************************************************************************************************************** 3913 */ 3914int mkfifo_test( void * the_argp ) 3915{ 3916 int my_err, my_status; 3917 pid_t my_pid, my_wait_pid; 3918 int my_fd = -1; 3919 char * my_pathp = NULL; 3920 ssize_t my_result; 3921 off_t my_current_offset; 3922 kern_return_t my_kr; 3923 3924 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 3925 if(my_kr != KERN_SUCCESS){ 3926 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3927 goto test_failed_exit; 3928 } 3929 3930 *my_pathp = 0x00; 3931 strcat( my_pathp, &g_target_path[0] ); 3932 strcat( my_pathp, "/" ); 3933 3934 /* get unique name for our fifo */ 3935 my_err = create_random_name( my_pathp, 0 ); 3936 if ( my_err != 0 ) { 3937 goto test_failed_exit; 3938 } 3939 3940 my_err = mkfifo( my_pathp, (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) ); 3941 if ( my_err != 0 ) { 3942 printf( "mkfifo failed with errno %d - %s. \n", errno, strerror( errno ) ); 3943 goto test_failed_exit; 3944 } 3945 3946 /* 3947 * spin off a child process that we will use for testing. 3948 */ 3949 my_pid = fork( ); 3950 if ( my_pid == -1 ) { 3951 printf( "fork failed with errno %d - %s \n", errno, strerror( errno ) ); 3952 goto test_failed_exit; 3953 } 3954 if ( my_pid == 0 ) { 3955 /* 3956 * child process. 3957 */ 3958 int my_child_fd = -1; 3959 int my_child_err; 3960 char my_buffer[64]; 3961 3962 /* open read end of fifo */ 3963 my_child_fd = open( my_pathp, O_RDWR, 0 ); 3964 if ( my_child_fd == -1 ) { 3965 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3966 my_child_err = -1; 3967 goto child_exit; 3968 } 3969 3970 /* read message from parent */ 3971 bzero( (void *)&my_buffer[0], sizeof(my_buffer) ); 3972 my_result = read( my_child_fd, &my_buffer[0], sizeof(my_buffer) ); 3973 if ( my_result == -1 ) { 3974 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3975 my_child_err = -1; 3976 goto child_exit; 3977 } 3978 if ( strcmp( "parent to child", &my_buffer[0] ) != 0 ) { 3979 printf( "read wrong message from parent \n" ); 3980 my_child_err = -1; 3981 goto child_exit; 3982 } 3983 3984 my_child_err = 0; 3985child_exit: 3986 if ( my_child_fd != -1 ) 3987 close( my_child_fd ); 3988 exit( my_child_err ); 3989 } 3990 3991 /* parent process - open write end of fifo 3992 */ 3993 my_fd = open( my_pathp, O_WRONLY, 0 ); 3994 if ( my_fd == -1 ) { 3995 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 3996 goto test_failed_exit; 3997 } 3998 3999 /* make sure we can't seek on a fifo */ 4000 my_current_offset = lseek( my_fd, 0, SEEK_CUR ); 4001 if ( my_current_offset != -1 ) { 4002 printf( "lseek on fifo should fail but did not \n" ); 4003 goto test_failed_exit; 4004 } 4005 4006 my_result = write( my_fd, "parent to child", 15 ); 4007 if ( my_result == -1 ) { 4008 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4009 goto test_failed_exit; 4010 } 4011 4012 my_wait_pid = wait4( my_pid, &my_status, 0, NULL ); 4013 if ( my_wait_pid == -1 ) { 4014 printf( "wait4 failed with errno %d - %s \n", errno, strerror( errno ) ); 4015 goto test_failed_exit; 4016 } 4017 4018 if ( WIFEXITED( my_status ) && WEXITSTATUS( my_status ) != 0 ) { 4019 goto test_failed_exit; 4020 } 4021 4022 my_err = 0; 4023 goto test_passed_exit; 4024 4025test_failed_exit: 4026 my_err = -1; 4027 4028test_passed_exit: 4029 if ( my_fd != -1 ) 4030 close( my_fd ); 4031 if ( my_pathp != NULL ) { 4032 remove( my_pathp ); 4033 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 4034 } 4035 return( my_err ); 4036} 4037 4038/* ************************************************************************************************************** 4039 * Test quotactl system calls. 4040 * ************************************************************************************************************** 4041 */ 4042int quotactl_test( void * the_argp ) 4043{ 4044#if !TARGET_OS_EMBEDDED 4045 int my_err; 4046 int is_quotas_on = 0; 4047 struct dqblk my_quota_blk; 4048 4049 if ( g_skip_setuid_tests != 0 ) { 4050 printf( "\t skipping this test \n" ); 4051 my_err = 0; 4052 goto test_passed_exit; 4053 } 4054 4055 /* start off by checking the status of quotas on the boot volume */ 4056 my_err = quotactl( "/mach_kernel", QCMD(Q_QUOTASTAT, USRQUOTA), 0, (caddr_t)&is_quotas_on ); 4057 if ( my_err == -1 ) { 4058 printf( "quotactl - Q_QUOTASTAT - failed with errno %d - %s \n", errno, strerror( errno ) ); 4059 goto test_failed_exit; 4060 } 4061 4062 if ( is_quotas_on == 0 ) { 4063 /* quotas are off */ 4064 my_err = 0; 4065 goto test_passed_exit; 4066 } 4067 4068 my_err = quotactl( "/mach_kernel", QCMD(Q_GETQUOTA, USRQUOTA), getuid(), (caddr_t)&my_quota_blk ); 4069 if ( my_err == -1 ) { 4070 printf( "quotactl - Q_GETQUOTA - failed with errno %d - %s \n", errno, strerror( errno ) ); 4071 goto test_failed_exit; 4072 } 4073 4074 my_err = 0; 4075 goto test_passed_exit; 4076 4077test_failed_exit: 4078 my_err = -1; 4079 4080test_passed_exit: 4081 return( my_err ); 4082#else 4083 printf( "\t--> Not supported on EMBEDDED TARGET\n" ); 4084 return 0; 4085#endif 4086} 4087 4088/* ************************************************************************************************************** 4089 * Test getrlimit, setrlimit system calls. 4090 * ************************************************************************************************************** 4091 */ 4092int limit_tests( void * the_argp ) 4093{ 4094 int my_err; 4095 struct rlimit my_current_rlimit; 4096 struct rlimit my_rlimit; 4097 4098 my_err = getrlimit( RLIMIT_NOFILE, &my_current_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_current_rlimit.rlim_cur != RLIM_INFINITY ) { 4104 if ( my_current_rlimit.rlim_cur != my_current_rlimit.rlim_max ) 4105 my_current_rlimit.rlim_cur += 1; 4106 else 4107 my_current_rlimit.rlim_cur -= 1; 4108 my_rlimit.rlim_cur = my_current_rlimit.rlim_cur; 4109 my_rlimit.rlim_max = my_current_rlimit.rlim_max; 4110 my_err = setrlimit( RLIMIT_NOFILE, &my_rlimit ); 4111 if ( my_err == -1 ) { 4112 printf( "setrlimit - failed with errno %d - %s \n", errno, strerror( errno ) ); 4113 goto test_failed_exit; 4114 } 4115 4116 /* verify that we set a new limit */ 4117 bzero( (void *) &my_rlimit, sizeof( my_rlimit ) ); 4118 my_err = getrlimit( RLIMIT_NOFILE, &my_rlimit ); 4119 if ( my_err == -1 ) { 4120 printf( "getrlimit - failed with errno %d - %s \n", errno, strerror( errno ) ); 4121 goto test_failed_exit; 4122 } 4123 if ( my_rlimit.rlim_cur != my_current_rlimit.rlim_cur ) { 4124 printf( "failed to get/set new RLIMIT_NOFILE soft limit \n" ); 4125 printf( "soft limits - current %lld should be %lld \n", my_rlimit.rlim_cur, my_current_rlimit.rlim_cur ); 4126 goto test_failed_exit; 4127 } 4128 4129#if CONFORMANCE_CHANGES_IN_XNU // can't do this check until conformance changes get into xnu 4130 printf( "hard limits - current %lld should be %lld \n", my_rlimit.rlim_max, my_current_rlimit.rlim_max ); 4131 if ( my_rlimit.rlim_max != my_current_rlimit.rlim_max ) { 4132 printf( "failed to get/set new RLIMIT_NOFILE hard limit \n" ); 4133 goto test_failed_exit; 4134 } 4135#endif 4136 4137 /* 4138 * A test for a limit that won't fit in a signed 32 bits, a la 5414697 4139 * Note: my_rlimit should still have a valid rlim_max. 4140 */ 4141 long long biglim = 2147483649ll; /* Just over 2^31 */ 4142 my_rlimit.rlim_cur = biglim; 4143 my_err = setrlimit(RLIMIT_CPU, &my_rlimit); 4144 if (my_err == -1) { 4145 printf("failed to set large limit.\n"); 4146 goto test_failed_exit; 4147 } 4148 4149 bzero(&my_rlimit, sizeof(struct rlimit)); 4150 my_err = getrlimit(RLIMIT_CPU, &my_rlimit); 4151 if (my_err == -1) { 4152 printf("after setting large value, failed to getrlimit().\n"); 4153 goto test_failed_exit; 4154 } 4155 4156 if (my_rlimit.rlim_cur != biglim) { 4157 printf("didn't retrieve large limit.\n"); 4158 goto test_failed_exit; 4159 } 4160 } 4161 4162 my_err = 0; 4163 goto test_passed_exit; 4164 4165test_failed_exit: 4166 my_err = -1; 4167 4168test_passed_exit: 4169 return( my_err ); 4170} 4171 4172/* ************************************************************************************************************** 4173 * Test getattrlist, getdirentriesattr, setattrlist system calls. 4174 * ************************************************************************************************************** 4175 */ 4176struct test_attr_buf { 4177 uint32_t length; 4178 fsobj_type_t obj_type; 4179 fsobj_id_t obj_id; 4180 struct timespec backup_time; 4181}; 4182 4183typedef struct test_attr_buf test_attr_buf; 4184 4185int directory_tests( void * the_argp ) 4186{ 4187 int my_err, done, found_it, i; 4188 int my_fd = -1; 4189 int is_ufs = 0; 4190 char * my_pathp = NULL; 4191 char * my_bufp = NULL; 4192 char * my_file_namep; 4193#ifdef __LP64__ 4194 unsigned int my_base; 4195 unsigned int my_count; 4196 unsigned int my_new_state; 4197#else 4198 unsigned long my_base; 4199 unsigned long my_count; 4200 unsigned long my_new_state; 4201#endif 4202 fsobj_id_t my_obj_id; 4203 struct timespec my_new_backup_time; 4204 struct attrlist my_attrlist; 4205 test_attr_buf my_attr_buf[4]; 4206 struct statfs my_statfs_buf; 4207 kern_return_t my_kr; 4208 4209 /* need to know type of file system */ 4210 my_err = statfs( &g_target_path[0], &my_statfs_buf ); 4211 if ( my_err == -1 ) { 4212 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4213 goto test_failed_exit; 4214 } 4215 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) { 4216 is_ufs = 1; 4217 } 4218 4219 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_bufp, (1024 * 5), VM_FLAGS_ANYWHERE); 4220 if(my_kr != KERN_SUCCESS){ 4221 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4222 goto test_failed_exit; 4223 } 4224 4225 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 4226 if(my_kr != KERN_SUCCESS){ 4227 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4228 goto test_failed_exit; 4229 } 4230 4231 *my_pathp = 0x00; 4232 strcat( my_pathp, &g_target_path[0] ); 4233 strcat( my_pathp, "/" ); 4234 4235 /* create a test file */ 4236 my_err = create_random_name( my_pathp, 1 ); 4237 if ( my_err != 0 ) { 4238 goto test_failed_exit; 4239 } 4240 4241 /* get pointer to just the file name */ 4242 my_file_namep = strrchr( my_pathp, '/' ); 4243 my_file_namep++; 4244 4245 /* check out the test directory */ 4246 my_fd = open( &g_target_path[0], (O_RDONLY), 0 ); 4247 if ( my_fd == -1 ) { 4248 printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4249 goto test_failed_exit; 4250 } 4251 4252 /* test get/setattrlist */ 4253 memset( &my_attrlist, 0, sizeof(my_attrlist) ); 4254 my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT; 4255 my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME); 4256 my_err = getattrlist( my_pathp, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf[0]), 0 ); 4257 4258 if ( my_err != 0 ) { 4259 if ( errno == ENOTSUP && is_ufs ) { 4260 /* getattr calls not supported on ufs */ 4261 my_err = 0; 4262 goto test_passed_exit; 4263 } 4264 printf( "getattrlist call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4265 goto test_failed_exit; 4266 } 4267 /* validate returned data */ 4268 if ( my_attr_buf[0].obj_type != VREG ) { 4269 printf( "getattrlist returned incorrect obj_type data. \n" ); 4270 goto test_failed_exit; 4271 } 4272 4273 /* set new backup time */ 4274 my_obj_id = my_attr_buf[0].obj_id; 4275 my_new_backup_time = my_attr_buf[0].backup_time; 4276 my_new_backup_time.tv_sec += 60; 4277 my_attr_buf[0].backup_time.tv_sec = my_new_backup_time.tv_sec; 4278 my_attrlist.commonattr = (ATTR_CMN_BKUPTIME); 4279 my_err = setattrlist( my_pathp, &my_attrlist, &my_attr_buf[0].backup_time, sizeof(my_attr_buf[0].backup_time), 0 ); 4280 if ( my_err != 0 ) { 4281 printf( "setattrlist call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4282 goto test_failed_exit; 4283 } 4284 4285 /* validate setattrlist using getdirentriesattr */ 4286 close( my_fd ); 4287 my_fd = open( &g_target_path[0], (O_RDONLY), 0 ); 4288 if ( my_fd == -1 ) { 4289 printf( "open failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4290 goto test_failed_exit; 4291 } 4292 memset( &my_attrlist, 0, sizeof(my_attrlist) ); 4293 memset( &my_attr_buf, 0, sizeof(my_attr_buf) ); 4294 my_attrlist.bitmapcount = ATTR_BIT_MAP_COUNT; 4295 my_attrlist.commonattr = (ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID | ATTR_CMN_BKUPTIME); 4296 my_count = 4; 4297 my_base = 0; 4298 my_err = getdirentriesattr( my_fd, &my_attrlist, &my_attr_buf[0], sizeof(my_attr_buf), &my_count, 4299 &my_base, &my_new_state, 0 ); 4300 if ( my_err < 0 ) { 4301 printf( "getdirentriesattr call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4302 goto test_failed_exit; 4303 } 4304 4305 found_it = 0; 4306 for ( i = 0; i < my_count; i++ ) { 4307 if ( my_attr_buf[i].obj_id.fid_objno == my_obj_id.fid_objno && 4308 my_attr_buf[i].obj_id.fid_generation == my_obj_id.fid_generation ) { 4309 found_it = 1; 4310 if ( my_attr_buf[i].backup_time.tv_sec != my_new_backup_time.tv_sec ) { 4311 printf( "setattrlist failed to set backup time. \n" ); 4312 goto test_failed_exit; 4313 } 4314 } 4315 } 4316 if ( found_it == 0 ) { 4317 printf( "getdirentriesattr failed to find test file. \n" ); 4318 goto test_failed_exit; 4319 } 4320 4321 my_err = 0; 4322 goto test_passed_exit; 4323 4324test_failed_exit: 4325 if(my_err != 0) 4326 my_err = -1; 4327 4328test_passed_exit: 4329 if ( my_fd != -1 ) 4330 close( my_fd ); 4331 if ( my_pathp != NULL ) { 4332 remove( my_pathp ); 4333 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 4334 } 4335 if ( my_bufp != NULL ) { 4336 vm_deallocate(mach_task_self(), (vm_address_t)my_bufp, (1024 * 5)); 4337 } 4338 return( my_err ); 4339} 4340 4341/* ************************************************************************************************************** 4342 * Test exchangedata system calls. 4343 * ************************************************************************************************************** 4344 */ 4345int exchangedata_test( void * the_argp ) 4346{ 4347 int my_err; 4348 int my_fd1 = -1; 4349 int my_fd2 = -1; 4350 char * my_file1_pathp = NULL; 4351 char * my_file2_pathp = NULL; 4352 ssize_t my_result; 4353 char my_buffer[16]; 4354 struct statfs my_statfs_buf; 4355 kern_return_t my_kr; 4356 4357 /* need to know type of file system */ 4358 my_err = statfs( &g_target_path[0], &my_statfs_buf ); 4359 if ( my_err == -1 ) { 4360 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4361 goto test_failed_exit; 4362 } 4363 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) { 4364 /* ufs does not support exchangedata */ 4365 my_err = 0; 4366 goto test_passed_exit; 4367 } 4368 4369 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file1_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 4370 if(my_kr != KERN_SUCCESS){ 4371 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4372 goto test_failed_exit; 4373 } 4374 4375 *my_file1_pathp = 0x00; 4376 strcat( my_file1_pathp, &g_target_path[0] ); 4377 strcat( my_file1_pathp, "/" ); 4378 4379 /* create a test file */ 4380 my_err = create_random_name( my_file1_pathp, 1 ); 4381 if ( my_err != 0 ) { 4382 printf( "create_random_name my_err: %d\n", my_err ); 4383 goto test_failed_exit; 4384 } 4385 my_fd1 = open( my_file1_pathp, O_RDWR, 0 ); 4386 if ( my_fd1 == -1 ) { 4387 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4388 goto test_failed_exit; 4389 } 4390 my_result = write( my_fd1, "11111111", 8 ); 4391 if ( my_result == -1 ) { 4392 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4393 goto test_failed_exit; 4394 } 4395 4396 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file2_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 4397 if(my_kr != KERN_SUCCESS){ 4398 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4399 goto test_failed_exit; 4400 } 4401 4402 *my_file2_pathp = 0x00; 4403 strcat( my_file2_pathp, &g_target_path[0] ); 4404 strcat( my_file2_pathp, "/" ); 4405 4406 /* create a test file */ 4407 my_err = create_random_name( my_file2_pathp, 1 ); 4408 if ( my_err != 0 ) { 4409 printf( "create_random_name my_err: %d\n", my_err ); 4410 goto test_failed_exit; 4411 } 4412 my_fd2 = open( my_file2_pathp, O_RDWR, 0 ); 4413 if ( my_fd2 == -1 ) { 4414 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4415 goto test_failed_exit; 4416 } 4417 my_result = write( my_fd2, "22222222", 8 ); 4418 if ( my_result == -1 ) { 4419 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4420 goto test_failed_exit; 4421 } 4422 close(my_fd1); 4423 my_fd1 = -1; 4424 close(my_fd2); 4425 my_fd2 = -1; 4426 4427 /* test exchangedata */ 4428 my_err = exchangedata( my_file1_pathp, my_file2_pathp, 0 ); 4429 if ( my_err == -1 ) { 4430 printf( "exchangedata failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4431 goto test_failed_exit; 4432 } 4433 4434 /* now validate exchange */ 4435 my_fd1 = open( my_file1_pathp, O_RDONLY, 0 ); 4436 if ( my_fd1 == -1 ) { 4437 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4438 goto test_failed_exit; 4439 } 4440 bzero( (void *)&my_buffer[0], sizeof(my_buffer) ); 4441 my_result = read( my_fd1, &my_buffer[0], 8 ); 4442 if ( my_result == -1 ) { 4443 printf( "write call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4444 goto test_failed_exit; 4445 } 4446 4447 if ( memcmp( &my_buffer[0], "22222222", 8 ) != 0 ) { 4448 printf( "exchangedata failed - incorrect data in file \n" ); 4449 goto test_failed_exit; 4450 } 4451 4452 my_err = 0; 4453 goto test_passed_exit; 4454 4455test_failed_exit: 4456 my_err = -1; 4457 4458test_passed_exit: 4459 if ( my_fd1 != -1 ) 4460 close( my_fd1 ); 4461 if ( my_file1_pathp != NULL ) { 4462 remove( my_file1_pathp ); 4463 vm_deallocate(mach_task_self(), (vm_address_t)my_file1_pathp, PATH_MAX); 4464 } 4465 if ( my_fd2 != -1 ) 4466 close( my_fd2 ); 4467 if ( my_file2_pathp != NULL ) { 4468 remove( my_file2_pathp ); 4469 vm_deallocate(mach_task_self(), (vm_address_t)my_file2_pathp, PATH_MAX); 4470 } 4471 return( my_err ); 4472} 4473 4474 4475/* ************************************************************************************************************** 4476 * Test searchfs system calls. 4477 * ************************************************************************************************************** 4478 */ 4479 4480struct packed_name_attr { 4481 u_int32_t size; /* Of the remaining fields */ 4482 struct attrreference ref; /* Offset/length of name itself */ 4483 char name[ PATH_MAX ]; 4484}; 4485 4486struct packed_attr_ref { 4487 u_int32_t size; /* Of the remaining fields */ 4488 struct attrreference ref; /* Offset/length of attr itself */ 4489}; 4490 4491struct packed_result { 4492 u_int32_t size; /* Including size field itself */ 4493 attrreference_t obj_name; 4494 struct fsobj_id obj_id; 4495 struct timespec obj_create_time; 4496 char room_for_name[ 64 ]; 4497}; 4498typedef struct packed_result packed_result; 4499typedef struct packed_result * packed_result_p; 4500 4501#define MAX_MATCHES 10 4502#define MAX_EBUSY_RETRIES 5 4503 4504int searchfs_test( void * the_argp ) 4505{ 4506#if !TARGET_OS_EMBEDDED 4507 int my_err, my_items_found = 0, my_ebusy_count; 4508 char * my_pathp = NULL; 4509 unsigned long my_matches; 4510 unsigned long my_search_options; 4511 struct fssearchblock my_search_blk; 4512 struct attrlist my_return_list; 4513 struct searchstate my_search_state; 4514 struct packed_name_attr my_info1; 4515 struct packed_attr_ref my_info2; 4516 packed_result my_result_buffer[ MAX_MATCHES ]; 4517 struct statfs my_statfs_buf; 4518 kern_return_t my_kr; 4519 4520 /* need to know type of file system */ 4521 my_err = statfs( &g_target_path[0], &my_statfs_buf ); 4522 if ( my_err == -1 ) { 4523 printf( "statfs call failed. got errno %d - %s. \n", errno, strerror( errno ) ); 4524 goto test_failed_exit; 4525 } 4526 if ( memcmp( &my_statfs_buf.f_fstypename[0], "ufs", 3 ) == 0 ) { 4527 /* ufs does not support exchangedata */ 4528 my_err = 0; 4529 goto test_passed_exit; 4530 } 4531 4532 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 4533 if(my_kr != KERN_SUCCESS){ 4534 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4535 goto test_failed_exit; 4536 } 4537 4538 *my_pathp = 0x00; 4539 strcat( my_pathp, &g_target_path[0] ); 4540 strcat( my_pathp, "/" ); 4541 4542 /* create test files */ 4543 my_err = create_file_with_name( my_pathp, "foo", 0 ); 4544 if ( my_err < 0 ) { 4545 printf( "failed to create a test file name in \"%s\" \n", my_pathp ); 4546 goto test_failed_exit; 4547 } 4548 4549 my_err = create_file_with_name( my_pathp, "foobar", 0 ); 4550 if ( my_err < 0 ) { 4551 printf( "failed to create a test file name in \"%s\" \n", my_pathp ); 4552 goto test_failed_exit; 4553 } 4554 4555 my_err = create_file_with_name( my_pathp, "foofoo", 0 ); 4556 if ( my_err < 0 ) { 4557 printf( "failed to create a test file name in \"%s\" \n", my_pathp ); 4558 goto test_failed_exit; 4559 } 4560 4561 my_err = create_file_with_name( my_pathp, "xxxfoo", 0 ); 4562 if ( my_err < 0 ) { 4563 printf( "failed to create a test file name in \"%s\" \n", my_pathp ); 4564 goto test_failed_exit; 4565 } 4566 4567 /* EBUSY count updated below the catalogue_changed label */ 4568 my_ebusy_count = 0; 4569 4570catalogue_changed: 4571 /* search target volume for all file system objects with "foo" in the name */ 4572 /* Set up the attributes we're searching on. */ 4573 my_items_found = 0; /* Set this here in case we're completely restarting */ 4574 my_search_blk.searchattrs.bitmapcount = ATTR_BIT_MAP_COUNT; 4575 my_search_blk.searchattrs.reserved = 0; 4576 my_search_blk.searchattrs.commonattr = ATTR_CMN_NAME; 4577 my_search_blk.searchattrs.volattr = 0; 4578 my_search_blk.searchattrs.dirattr = 0; 4579 my_search_blk.searchattrs.fileattr = 0; 4580 my_search_blk.searchattrs.forkattr = 0; 4581 4582 /* Set up the attributes we want for all returned matches. */ 4583 /* Why is returnattrs a pointer instead of an embedded struct? */ 4584 my_search_blk.returnattrs = &my_return_list; 4585 my_return_list.bitmapcount = ATTR_BIT_MAP_COUNT; 4586 my_return_list.reserved = 0; 4587 my_return_list.commonattr = ATTR_CMN_NAME | ATTR_CMN_OBJID | ATTR_CMN_CRTIME; 4588 my_return_list.volattr = 0; 4589 my_return_list.dirattr = 0; 4590 my_return_list.fileattr = 0; 4591 my_return_list.forkattr = 0; 4592 4593 /* Allocate a buffer for returned matches */ 4594 my_search_blk.returnbuffer = my_result_buffer; 4595 my_search_blk.returnbuffersize = sizeof(my_result_buffer); 4596 4597 /* Pack the searchparams1 into a buffer */ 4598 /* NOTE: A name appears only in searchparams1 */ 4599 strcpy( my_info1.name, "foo" ); 4600 my_info1.ref.attr_dataoffset = sizeof(struct attrreference); 4601 my_info1.ref.attr_length = strlen(my_info1.name) + 1; 4602 my_info1.size = sizeof(struct attrreference) + my_info1.ref.attr_length; 4603 my_search_blk.searchparams1 = &my_info1; 4604 my_search_blk.sizeofsearchparams1 = my_info1.size + sizeof(u_int32_t); 4605 4606 /* Pack the searchparams2 into a buffer */ 4607 my_info2.size = sizeof(struct attrreference); 4608 my_info2.ref.attr_dataoffset = sizeof(struct attrreference); 4609 my_info2.ref.attr_length = 0; 4610 my_search_blk.searchparams2 = &my_info2; 4611 my_search_blk.sizeofsearchparams2 = sizeof(my_info2); 4612 4613 /* Maximum number of matches we want */ 4614 my_search_blk.maxmatches = MAX_MATCHES; 4615 4616 /* Maximum time to search, per call */ 4617 my_search_blk.timelimit.tv_sec = 1; 4618 my_search_blk.timelimit.tv_usec = 0; 4619 4620 my_search_options = (SRCHFS_START | SRCHFS_MATCHPARTIALNAMES | 4621 SRCHFS_MATCHFILES | SRCHFS_MATCHDIRS); 4622 do { 4623 char * my_end_ptr; 4624 char * my_ptr; 4625 int i; 4626 4627 my_err = searchfs( my_pathp, &my_search_blk, &my_matches, 0, my_search_options, &my_search_state ); 4628 if ( my_err == -1 ) 4629 my_err = errno; 4630 if ( (my_err == 0 || my_err == EAGAIN) && my_matches > 0 ) { 4631 /* Unpack the results */ 4632 // printf("my_matches %d \n", my_matches); 4633 my_ptr = (char *) &my_result_buffer[0]; 4634 my_end_ptr = (my_ptr + sizeof(my_result_buffer)); 4635 for ( i = 0; i < my_matches; ++i ) { 4636 packed_result_p my_result_p = (packed_result_p) my_ptr; 4637 char * my_name_p; 4638 4639 /* see if we foound all our test files */ 4640 my_name_p = (((char *)(&my_result_p->obj_name)) + my_result_p->obj_name.attr_dataoffset); 4641 if ( memcmp( my_name_p, "foo", 3 ) == 0 || 4642 memcmp( my_name_p, "foobar", 6 ) == 0 || 4643 memcmp( my_name_p, "foofoo", 6 ) == 0 || 4644 memcmp( my_name_p, "xxxfoo", 6 ) == 0 ) { 4645 my_items_found++; 4646 } 4647#if DEBUG 4648 printf("obj_name \"%.*s\" \n", 4649 (int) my_result_p->obj_name.attr_length, 4650 (((char *)(&my_result_p->obj_name)) + 4651 my_result_p->obj_name.attr_dataoffset)); 4652 printf("size %d fid_objno %d fid_generation %d tv_sec 0x%02LX \n", 4653 my_result_p->size, my_result_p->obj_id.fid_objno, 4654 my_result_p->obj_id.fid_generation, 4655 my_result_p->obj_create_time.tv_sec); 4656#endif 4657 my_ptr = (my_ptr + my_result_p->size); 4658 if (my_ptr > my_end_ptr) 4659 break; 4660 } 4661 } 4662 4663 /* EBUSY indicates catalogue change; retry a few times. */ 4664 if ((my_err == EBUSY) && (my_ebusy_count++ < MAX_EBUSY_RETRIES)) { 4665 goto catalogue_changed; 4666 } 4667 if ( !(my_err == 0 || my_err == EAGAIN) ) { 4668 printf( "searchfs failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4669 } 4670 my_search_options &= ~SRCHFS_START; 4671 } while ( my_err == EAGAIN ); 4672 4673 if ( my_items_found < 4 ) { 4674 printf( "searchfs failed to find all test files \n" ); 4675 goto test_failed_exit; 4676 } 4677 4678 my_err = 0; 4679 goto test_passed_exit; 4680 4681test_failed_exit: 4682 my_err = -1; 4683 4684test_passed_exit: 4685 if ( my_pathp != NULL ) { 4686 char * my_ptr = (my_pathp + strlen( my_pathp )); 4687 strcat( my_pathp, "foo" ); 4688 remove( my_pathp ); 4689 *my_ptr = 0x00; 4690 strcat( my_pathp, "foobar" ); 4691 remove( my_pathp ); 4692 *my_ptr = 0x00; 4693 strcat( my_pathp, "foofoo" ); 4694 remove( my_pathp ); 4695 *my_ptr = 0x00; 4696 strcat( my_pathp, "xxxfoo" ); 4697 remove( my_pathp ); 4698 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 4699 } 4700 return( my_err ); 4701#else 4702 printf( "\t--> Not supported on EMBEDDED TARGET\n" ); 4703 return 0; 4704#endif 4705} 4706 4707 4708#define AIO_TESTS_BUFFER_SIZE (1024 * 4000) 4709#define AIO_TESTS_OUR_COUNT 5 4710/* ************************************************************************************************************** 4711 * Test aio_error, aio_read, aio_return, aio_suspend, aio_write, fcntl system calls. 4712 * ************************************************************************************************************** 4713 */ 4714int aio_tests( void * the_argp ) 4715{ 4716 int my_err, i; 4717 char * my_pathp; 4718 struct aiocb * my_aiocbp; 4719 ssize_t my_result; 4720 struct timespec my_timeout; 4721 int my_fd_list[ AIO_TESTS_OUR_COUNT ]; 4722 char * my_buffers[ AIO_TESTS_OUR_COUNT ]; 4723 struct aiocb * my_aiocb_list[ AIO_TESTS_OUR_COUNT ]; 4724 struct aiocb my_aiocbs[ AIO_TESTS_OUR_COUNT ]; 4725 char * my_file_paths[ AIO_TESTS_OUR_COUNT ]; 4726 kern_return_t my_kr; 4727 4728 /* set up to have the ability to fire off up to AIO_TESTS_OUR_COUNT async IOs at once */ 4729 memset( &my_fd_list[0], 0xFF, sizeof( my_fd_list ) ); 4730 memset( &my_buffers[0], 0x00, sizeof( my_buffers ) ); 4731 memset( &my_aiocb_list[0], 0x00, sizeof( my_aiocb_list ) ); 4732 memset( &my_file_paths[0], 0x00, sizeof( my_file_paths ) ); 4733 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) { 4734 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_buffers[ i ], AIO_TESTS_BUFFER_SIZE, VM_FLAGS_ANYWHERE); 4735 if(my_kr != KERN_SUCCESS){ 4736 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4737 goto test_failed_exit; 4738 } 4739 4740 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_file_paths[ i ], PATH_MAX, VM_FLAGS_ANYWHERE); 4741 if(my_kr != KERN_SUCCESS){ 4742 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4743 goto test_failed_exit; 4744 } 4745 4746 my_pathp = my_file_paths[ i ]; 4747 *my_pathp = 0x00; 4748 strcat( my_pathp, &g_target_path[0] ); 4749 strcat( my_pathp, "/" ); 4750 4751 /* create a test file */ 4752 my_err = create_random_name( my_pathp, 1 ); 4753 if ( my_err != 0 ) { 4754 goto test_failed_exit; 4755 } 4756 my_fd_list[ i ] = open( my_pathp, O_RDWR, 0 ); 4757 if ( my_fd_list[ i ] <= 0 ) { 4758 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4759 goto test_failed_exit; 4760 } 4761 4762 my_aiocbp = &my_aiocbs[ i ]; 4763 my_aiocb_list[ i ] = my_aiocbp; 4764 memset( my_aiocbp, 0x00, sizeof( *my_aiocbp ) ); 4765 my_aiocbp->aio_fildes = my_fd_list[ i ]; 4766 my_aiocbp->aio_buf = (char *) my_buffers[ i ]; 4767 my_aiocbp->aio_nbytes = 1024; 4768 my_aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE; // no signals at completion; 4769 my_aiocbp->aio_sigevent.sigev_signo = 0; 4770 } 4771 4772 /* test direct IO (F_NOCACHE) and aio_write */ 4773 my_err = fcntl( my_fd_list[ 0 ], F_NOCACHE, 1 ); 4774 if ( my_err != 0 ) { 4775 printf( "malloc failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4776 goto test_failed_exit; 4777 } 4778 4779 my_aiocbp = &my_aiocbs[ 0 ]; 4780 my_aiocbp->aio_fildes = my_fd_list[ 0 ]; 4781 my_aiocbp->aio_offset = 4096; 4782 my_aiocbp->aio_buf = my_buffers[ 0 ]; 4783 my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE; 4784 my_aiocbp->aio_reqprio = 0; 4785 my_aiocbp->aio_sigevent.sigev_notify = 0; 4786 my_aiocbp->aio_sigevent.sigev_signo = 0; 4787 my_aiocbp->aio_sigevent.sigev_value.sival_int = 0; 4788 my_aiocbp->aio_sigevent.sigev_notify_function = NULL; 4789 my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL; 4790 my_aiocbp->aio_lio_opcode = 0; 4791 4792 /* write some data */ 4793 memset( my_buffers[ 0 ], 'j', AIO_TESTS_BUFFER_SIZE ); 4794 my_err = aio_write( my_aiocbp ); 4795 if ( my_err != 0 ) { 4796 printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4797 goto test_failed_exit; 4798 } 4799 4800 while ( 1 ) { 4801 my_err = aio_error( my_aiocbp ); 4802 if ( my_err == EINPROGRESS ) { 4803 /* wait for IO to complete */ 4804 sleep( 1 ); 4805 continue; 4806 } 4807 else if ( my_err == 0 ) { 4808 ssize_t my_result; 4809 my_result = aio_return( my_aiocbp ); 4810 break; 4811 } 4812 else { 4813 printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) ); 4814 goto test_failed_exit; 4815 } 4816 } /* while loop */ 4817 4818 /* read some data */ 4819 memset( my_buffers[ 0 ], 'x', AIO_TESTS_BUFFER_SIZE ); 4820 my_err = aio_read( my_aiocbp ); 4821 4822 while ( 1 ) { 4823 my_err = aio_error( my_aiocbp ); 4824 if ( my_err == EINPROGRESS ) { 4825 /* wait for IO to complete */ 4826 sleep( 1 ); 4827 continue; 4828 } 4829 else if ( my_err == 0 ) { 4830 ssize_t my_result; 4831 my_result = aio_return( my_aiocbp ); 4832 4833 if ( *(my_buffers[ 0 ]) != 'j' || *(my_buffers[ 0 ] + AIO_TESTS_BUFFER_SIZE - 1) != 'j' ) { 4834 printf( "aio_read or aio_write failed - wrong data read \n" ); 4835 goto test_failed_exit; 4836 } 4837 break; 4838 } 4839 else { 4840 printf( "aio_read failed with error %d - \"%s\" \n", my_err, strerror( my_err ) ); 4841 goto test_failed_exit; 4842 } 4843 } /* while loop */ 4844 4845 /* test aio_fsync */ 4846 close( my_fd_list[ 0 ] ); 4847 my_fd_list[ 0 ] = open( my_pathp, O_RDWR, 0 ); 4848 if ( my_fd_list[ 0 ] == -1 ) { 4849 printf( "open call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4850 goto test_failed_exit; 4851 } 4852 4853 my_aiocbp = &my_aiocbs[ 0 ]; 4854 my_aiocbp->aio_fildes = my_fd_list[ 0 ]; 4855 my_aiocbp->aio_offset = 0; 4856 my_aiocbp->aio_buf = my_buffers[ 0 ]; 4857 my_aiocbp->aio_nbytes = 1024; 4858 my_aiocbp->aio_reqprio = 0; 4859 my_aiocbp->aio_sigevent.sigev_notify = 0; 4860 my_aiocbp->aio_sigevent.sigev_signo = 0; 4861 my_aiocbp->aio_sigevent.sigev_value.sival_int = 0; 4862 my_aiocbp->aio_sigevent.sigev_notify_function = NULL; 4863 my_aiocbp->aio_sigevent.sigev_notify_attributes = NULL; 4864 my_aiocbp->aio_lio_opcode = 0; 4865 4866 /* write some data */ 4867 memset( my_buffers[ 0 ], 'e', 1024 ); 4868 my_err = aio_write( my_aiocbp ); 4869 if ( my_err != 0 ) { 4870 printf( "aio_write failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4871 goto test_failed_exit; 4872 } 4873 while ( 1 ) { 4874 my_err = aio_error( my_aiocbp ); 4875 if ( my_err == EINPROGRESS ) { 4876 /* wait for IO to complete */ 4877 sleep( 1 ); 4878 continue; 4879 } 4880 else if ( my_err == 0 ) { 4881 ssize_t my_result; 4882 my_result = aio_return( my_aiocbp ); 4883 break; 4884 } 4885 else { 4886 printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) ); 4887 goto test_failed_exit; 4888 } 4889 } /* while loop */ 4890 4891 my_err = aio_fsync( O_SYNC, my_aiocbp ); 4892 if ( my_err != 0 ) { 4893 printf( "aio_fsync failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4894 goto test_failed_exit; 4895 } 4896 while ( 1 ) { 4897 my_err = aio_error( my_aiocbp ); 4898 if ( my_err == EINPROGRESS ) { 4899 /* wait for IO to complete */ 4900 sleep( 1 ); 4901 continue; 4902 } 4903 else if ( my_err == 0 ) { 4904 aio_return( my_aiocbp ); 4905 break; 4906 } 4907 else { 4908 printf( "aio_error failed with error %d - \"%s\" \n", my_err, strerror( my_err ) ); 4909 goto test_failed_exit; 4910 } 4911 } /* while loop */ 4912 4913 /* validate write */ 4914 memset( my_buffers[ 0 ], 0x20, 16 ); 4915 lseek( my_fd_list[ 0 ], 0, SEEK_SET ); 4916 my_result = read( my_fd_list[ 0 ], my_buffers[ 0 ], 16); 4917 if ( my_result == -1 ) { 4918 printf( "read call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4919 goto test_failed_exit; 4920 } 4921 if ( *(my_buffers[ 0 ]) != 'e' || *(my_buffers[ 0 ] + 16 - 1) != 'e' ) { 4922 printf( "aio_fsync or aio_write failed - wrong data read \n" ); 4923 goto test_failed_exit; 4924 } 4925 4926 /* test aio_suspend and lio_listio */ 4927 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) { 4928 memset( my_buffers[ i ], 'a', AIO_TESTS_BUFFER_SIZE ); 4929 my_aiocbp = &my_aiocbs[ i ]; 4930 my_aiocbp->aio_nbytes = AIO_TESTS_BUFFER_SIZE; 4931 my_aiocbp->aio_lio_opcode = LIO_WRITE; 4932 } 4933 my_err = lio_listio( LIO_NOWAIT, my_aiocb_list, AIO_TESTS_OUR_COUNT, NULL ); 4934 if ( my_err != 0 ) { 4935 printf( "lio_listio call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4936 goto test_failed_exit; 4937 } 4938 4939 my_timeout.tv_sec = 1; 4940 my_timeout.tv_nsec = 0; 4941 my_err = aio_suspend( (const struct aiocb *const*) my_aiocb_list, AIO_TESTS_OUR_COUNT, &my_timeout ); 4942 if ( my_err != 0 ) { 4943 printf( "aio_suspend call failed with error %d - \"%s\" \n", errno, strerror( errno) ); 4944 goto test_failed_exit; 4945 } 4946 4947 /* test aio_cancel */ 4948 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) { 4949 my_aiocbp = &my_aiocbs[ i ]; 4950 my_err = aio_cancel( my_aiocbp->aio_fildes, my_aiocbp ); 4951 if ( my_err != AIO_ALLDONE && my_err != AIO_CANCELED && my_err != AIO_NOTCANCELED ) { 4952 printf( "aio_cancel failed with error %d - \"%s\" \n", my_err, strerror( my_err) ); 4953 goto test_failed_exit; 4954 } 4955 } 4956 4957 my_err = 0; 4958 goto test_passed_exit; 4959 4960test_failed_exit: 4961 my_err = -1; 4962 4963test_passed_exit: 4964 for ( i = 0; i < AIO_TESTS_OUR_COUNT; i++ ) { 4965 if ( my_fd_list[ i ] != -1 ) { 4966 close( my_fd_list[ i ] ); 4967 my_fd_list[ i ] = -1; 4968 } 4969 if ( my_file_paths[ i ] != NULL ) { 4970 remove( my_file_paths[ i ] ); 4971 vm_deallocate(mach_task_self(), (vm_address_t)my_file_paths[ i ], PATH_MAX); 4972 my_file_paths[ i ] = NULL; 4973 } 4974 if ( my_buffers[ i ] != NULL ) { 4975 vm_deallocate(mach_task_self(), (vm_address_t)my_buffers[ i ], AIO_TESTS_BUFFER_SIZE); 4976 my_buffers[ i ] = NULL; 4977 } 4978 } 4979 return( my_err ); 4980} 4981 4982 4983/* ************************************************************************************************************** 4984 * Test msgctl, msgget, msgrcv, msgsnd system calls. 4985 * ************************************************************************************************************** 4986 */ 4987int message_queue_tests( void * the_argp ) 4988{ 4989#if !TARGET_OS_EMBEDDED 4990 int my_err; 4991 int my_msg_queue_id = -1; 4992 ssize_t my_result; 4993 struct msqid_ds my_msq_ds; 4994 struct testing_msq_message { 4995 long msq_type; 4996 char msq_buffer[ 32 ]; 4997 } my_msg; 4998 4999 /* get a message queue established for our use */ 5000 my_msg_queue_id = msgget( IPC_PRIVATE, (IPC_CREAT | IPC_EXCL | IPC_R | IPC_W) ); 5001 if ( my_msg_queue_id == -1 ) { 5002 printf( "msgget failed with errno %d - %s \n", errno, strerror( errno ) ); 5003 goto test_failed_exit; 5004 } 5005 5006 /* get some stats on our message queue */ 5007 my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds ); 5008 if ( my_err == -1 ) { 5009 printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) ); 5010 goto test_failed_exit; 5011 } 5012 if ( my_msq_ds.msg_perm.cuid != geteuid( ) ) { 5013 printf( "msgctl IPC_STAT failed to get correct creator uid \n" ); 5014 goto test_failed_exit; 5015 } 5016 if ( (my_msq_ds.msg_perm.mode & (IPC_R | IPC_W)) == 0 ) { 5017 printf( "msgctl IPC_STAT failed to get correct mode \n" ); 5018 goto test_failed_exit; 5019 } 5020 5021 /* put a message into our queue */ 5022 my_msg.msq_type = 1; 5023 strcpy( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" ); 5024 my_err = msgsnd( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0 ); 5025 if ( my_err == -1 ) { 5026 printf( "msgsnd failed with errno %d - %s \n", errno, strerror( errno ) ); 5027 goto test_failed_exit; 5028 } 5029 5030 my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds ); 5031 if ( my_err == -1 ) { 5032 printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) ); 5033 goto test_failed_exit; 5034 } 5035 if ( my_msq_ds.msg_qnum != 1 ) { 5036 printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" ); 5037 goto test_failed_exit; 5038 } 5039 5040 /* pull message off the queue */ 5041 bzero( (void *)&my_msg, sizeof( my_msg ) ); 5042 my_result = msgrcv( my_msg_queue_id, &my_msg, sizeof( my_msg.msq_buffer ), 0, 0 ); 5043 if ( my_result == -1 ) { 5044 printf( "msgrcv failed with errno %d - %s \n", errno, strerror( errno ) ); 5045 goto test_failed_exit; 5046 } 5047 if ( my_result != sizeof( my_msg.msq_buffer ) ) { 5048 printf( "msgrcv failed to return the correct number of bytes in our buffer \n" ); 5049 goto test_failed_exit; 5050 } 5051 if ( strcmp( &my_msg.msq_buffer[ 0 ], "testing 1, 2, 3" ) != 0 ) { 5052 printf( "msgrcv failed to get the correct message \n" ); 5053 goto test_failed_exit; 5054 } 5055 5056 my_err = msgctl( my_msg_queue_id, IPC_STAT, &my_msq_ds ); 5057 if ( my_err == -1 ) { 5058 printf( "msgctl failed with errno %d - %s \n", errno, strerror( errno ) ); 5059 goto test_failed_exit; 5060 } 5061 if ( my_msq_ds.msg_qnum != 0 ) { 5062 printf( "msgctl IPC_STAT failed to get correct number of messages on the queue \n" ); 5063 goto test_failed_exit; 5064 } 5065 5066 /* tear down the message queue */ 5067 my_err = msgctl( my_msg_queue_id, IPC_RMID, NULL ); 5068 if ( my_err == -1 ) { 5069 printf( "msgctl IPC_RMID failed with errno %d - %s \n", errno, strerror( errno ) ); 5070 goto test_failed_exit; 5071 } 5072 my_msg_queue_id = -1; 5073 5074 my_err = 0; 5075 goto test_passed_exit; 5076 5077test_failed_exit: 5078 my_err = -1; 5079 5080test_passed_exit: 5081 if ( my_msg_queue_id != -1 ) { 5082 msgctl( my_msg_queue_id, IPC_RMID, NULL ); 5083 } 5084 return( my_err ); 5085#else 5086 printf( "\t--> Not supported on EMBEDDED TARGET \n" ); 5087 return 0; 5088#endif 5089} 5090 5091 5092 5093/* ************************************************************************************************************** 5094 * Test execution from data and stack areas. 5095 * ************************************************************************************************************** 5096 */ 5097int data_exec_tests( void * the_argp ) 5098{ 5099 int my_err = 0; 5100 int arch, bits; 5101 posix_spawnattr_t attrp; 5102 char *argv[] = { "helpers/data_exec32nonxspawn", NULL }; 5103 5104 int my_pid, my_status, ret; 5105 5106 if ((arch = get_architecture()) == -1) { 5107 printf("data_exec_test: couldn't determine architecture\n"); 5108 goto test_failed_exit; 5109 } 5110 5111 bits = get_bits(); 5112 5113 /* 5114 * If the machine is 64-bit capable, run both the 32 and 64 bit versions of the test. 5115 * Otherwise, just run the 32-bit version. 5116 */ 5117 5118 if (arch == INTEL) { 5119 if (bits == 64) { 5120 if (system("arch -arch x86_64 helpers/data_exec") != 0) { 5121 printf("data_exec-x86_64 failed\n"); 5122 goto test_failed_exit; 5123 } 5124 } 5125 5126 if (system("arch -arch i386 helpers/data_exec") != 0) { 5127 printf("data_exec-i386 failed\n"); 5128 goto test_failed_exit; 5129 } 5130 5131 posix_spawnattr_init(&attrp); 5132 posix_spawnattr_setflags(&attrp, _POSIX_SPAWN_ALLOW_DATA_EXEC ); 5133 ret = posix_spawn(&my_pid, "helpers/data_exec32nonxspawn", NULL, &attrp, argv, NULL); 5134 if (ret) { 5135 printf("data_exec-i386 failed in posix_spawn %s\n", strerror(errno)); 5136 goto test_failed_exit; 5137 } 5138 ret = wait4(my_pid, &my_status, 0, NULL); 5139 if (ret == -1) { 5140 printf("data_exec-i386 wait4 failed with errno %d - %s\n", errno, strerror(errno)); 5141 goto test_failed_exit; 5142 } 5143 if (WEXITSTATUS(my_status) != 0) { 5144 printf("data_exec-i386 _POSIX_SPAWN_ALLOW_DATA_EXEC failed\n"); 5145 goto test_failed_exit; 5146 } 5147 } 5148 5149 /* Add new architectures here similar to the above. */ 5150 5151 goto test_passed_exit; 5152 5153test_failed_exit: 5154 my_err = -1; 5155 5156test_passed_exit: 5157 return my_err; 5158} 5159 5160/* ************************************************************************************************************** 5161 * Test KASLR-related functionality 5162 * ************************************************************************************************************** 5163 */ 5164int kaslr_test( void * the_argp ) 5165{ 5166 int result = 0; 5167 uint64_t slide = 0; 5168 size_t size; 5169 int slide_enabled; 5170 5171 size = sizeof(slide_enabled); 5172 result = sysctlbyname("kern.slide", &slide_enabled, &size, NULL, 0); 5173 if (result != 0) { 5174 printf("sysctlbyname(\"kern.slide\") failed with errno %d\n", errno); 5175 goto test_failed_exit; 5176 } 5177 5178 /* Test positive case first */ 5179 size = sizeof(slide); 5180 result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size); 5181 if (result == 0) { 5182 /* syscall supported, slide must be non-zero if running latest xnu and KASLR is enabled */ 5183 if (slide_enabled && (slide == 0)) { 5184 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported slide of 0x%016llx\n", slide); 5185 goto test_failed_exit; 5186 } 5187 if (size != sizeof(slide)) { 5188 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) reported size of %lu\n", size); 5189 goto test_failed_exit; 5190 } 5191 } else { 5192 /* Only ENOTSUP is allowed. If so, assume all calls will be unsupported */ 5193 if (errno == ENOTSUP) { 5194 return 0; 5195 } else { 5196 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, &slide, &size) returned unexpected errno (errno %d)\n", errno); 5197 goto test_failed_exit; 5198 } 5199 } 5200 5201 /* Negative cases for expected failures */ 5202 size = sizeof(slide); 5203 result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, &size); 5204 if ((result == 0) || (errno != EFAULT)) { 5205 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno); 5206 goto test_failed_exit; 5207 } 5208 5209 size = sizeof(slide) + 1; /* EINVAL */ 5210 result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size); 5211 if ((result == 0) || (errno != EINVAL)) { 5212 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, &size+1) returned unexpected success or errno (result %d errno %d)\n", result, errno); 5213 goto test_failed_exit; 5214 } 5215 5216 result = kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL /* EFAULT */, NULL /* EFAULT */); 5217 if ((result == 0) || (errno != EFAULT)) { 5218 printf("kas_info(KAS_INFO_KERNEL_TEXT_SLIDE_SELECTOR, NULL, NULL) returned unexpected success or errno (result %d errno %d)\n", result, errno); 5219 goto test_failed_exit; 5220 } 5221 5222 size = sizeof(slide); 5223 result = kas_info(KAS_INFO_MAX_SELECTOR /* EINVAL */, &slide, &size); 5224 if ((result == 0) || (errno != EINVAL)) { 5225 printf("kas_info(KAS_INFO_MAX_SELECTOR, &slide, &size) returned unexpected success or errno (result %d errno %d)\n", result, errno); 5226 goto test_failed_exit; 5227 } 5228 5229 return 0; 5230 5231test_failed_exit: 5232 return -1; 5233} 5234 5235#if TEST_SYSTEM_CALLS 5236 5237/* ************************************************************************************************************** 5238 * Test xxxxxxxxx system calls. 5239 * ************************************************************************************************************** 5240 */ 5241int sample_test( void * the_argp ) 5242{ 5243 int my_err; 5244 int my_fd = -1; 5245 char * my_pathp = NULL; 5246 kern_return_t my_kr; 5247 5248 my_kr = vm_allocate((vm_map_t) mach_task_self(), (vm_address_t*)&my_pathp, PATH_MAX, VM_FLAGS_ANYWHERE); 5249 if(my_kr != KERN_SUCCESS){ 5250 printf( "vm_allocate failed with error %d - \"%s\" \n", errno, strerror( errno) ); 5251 goto test_failed_exit; 5252 } 5253 5254 *my_pathp = 0x00; 5255 strcat( my_pathp, &g_target_path[0] ); 5256 strcat( my_pathp, "/" ); 5257 5258 /* create a test file */ 5259 my_err = create_random_name( my_pathp, 1 ); 5260 if ( my_err != 0 ) { 5261 goto test_failed_exit; 5262 } 5263 5264 /* add your test code here... */ 5265 5266 5267 my_err = 0; 5268 goto test_passed_exit; 5269 5270test_failed_exit: 5271 my_err = -1; 5272 5273test_passed_exit: 5274 if ( my_fd != -1 ) 5275 close( my_fd ); 5276 if ( my_pathp != NULL ) { 5277 remove( my_pathp ); 5278 vm_deallocate(mach_task_self(), (vm_address_t)my_pathp, PATH_MAX); 5279 } 5280 return( my_err ); 5281} 5282 5283#endif 5284