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