# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4 package require tcltest 2 namespace import tcltest::* source "testlib.tcl" test darwintrace_hides_files "Test that a file on the blacklist isn't stat(2)able" \ -setup [setup [list deny $cwd]] \ -cleanup [expect [list "$cwd/stat"]] \ -body {exec -ignorestderr -- ./stat stat 2>@1} \ -result "stat: No such file or directory" test darwintrace_hides_symlinks "Test that a symlink on the blacklist isn't stat(2)able, even if its target is" \ -setup { file link -symbolic link . [setup [list deny "$cwd/link" allow $cwd]] } \ -cleanup { file delete -force link [expect [list "$cwd/link"]] } \ -body {exec -ignorestderr -- ./lstat link 2>@1} \ -result "lstat: No such file or directory" test darwintrace_long_filenames "Test that a long filename does not trigger the stack canary" \ -setup [setup [list allow $cwd]] \ -cleanup [expect] \ -body {exec -ignorestderr -- ./stat [string repeat "ab/de/ghi/" 102] 2>@1} \ -result "stat: No such file or directory" test darwintrace_works_across_fork "Test that darwintrace works across fork(2)" \ -setup [setup [list deny "$cwd/access.c" allow $cwd]] \ -cleanup [expect [list "$cwd/access.c"]] \ -body {exec -ignorestderr -- ./fork ./access.c 2>@1} \ -result [join [list "access(./access.c): No such file or directory" "access(./access.c): No such file or directory"] "\n"] test darwintrace_allow_root "Test that access to / is always possible" \ -setup [setup {}] \ -cleanup [expect] \ -body {exec -ignorestderr -- ./stat / 2>@1} \ -result "" test darwintrace_empty_path "Test that access to and empty path isn't hindered by darwintrace" \ -setup [setup {}] \ -cleanup [expect] \ -body {exec -ignorestderr -- ./stat "" 2>@1} \ -result "stat: No such file or directory" test darwintrace_up_beyond_root_absolute "Test that walking up beyond the root with absolute paths works" \ -setup [setup [list deny "/"]] \ -cleanup [expect [list "/bin/sh"]] \ -body {exec -ignorestderr -- ./stat "/bin/..//..//../bin/sh" 2>@1} \ -result "stat: No such file or directory" test darwintrace_up_beyond_root_relative "Test that walking up beyond the root with relative paths works" \ -setup [setup [list deny "/"]] \ -cleanup [expect [list "/bin/sh"]] \ -body { set levels [llength [regexp -all -inline -- "/" $cwd]] set path [file join [string repeat "../" [expr {$levels + 2}]] bin sh] exec -ignorestderr -- ./stat "$path" 2>@1 } \ -result "stat: No such file or directory" test darwintrace_ignores_rsrc_forks "Test that resource forks are ignored" \ -setup [setup [list deny "/"]] \ -cleanup [expect [list "/bin/sh"]] \ -body {exec -ignorestderr -- ./stat "/bin/sh/..namedfork/rsrc" 2>@1} \ -result "stat: No such file or directory" test darwintrace_on_volfs "Test that /.vol/device/inode works" \ -setup [setup [list deny "/"]] \ -cleanup [expect [list "/bin/sh"]] \ -body { file stat "/bin/sh" st exec -ignorestderr -- ./stat "/.vol/${st(dev)}/${st(ino)}" 2>@1 } \ -result "stat: No such file or directory" test darwintrace_on_looping_symlinks "Test that self-symlinks are handled" \ -setup { set levels [llength [regexp -all -inline -- "/" $cwd]] set path [file join [string repeat "../" [expr {$levels + 2}]] $cwd symlink] exec -ignorestderr -- ln -s $path symlink [setup [list allow "/"]] } \ -cleanup { [expect] file delete -force symlink } \ -body {exec -ignorestderr -- ./stat "$cwd/symlink" 2>@1} \ -result "stat: Too many levels of symbolic links" test darwintrace_checks_symlink_path "Test that accessing a symlink fails, even if the target is in the sandbox" \ -setup { [setup [list deny "$cwd/symlink" allow $cwd]] file link -symbolic symlink stat } \ -cleanup { [expect [list "$cwd/symlink"]] file delete -force symlink } \ -body {exec -ignorestderr -- ./stat "$cwd/symlink" 2>@1} \ -result "stat: No such file or directory" test darwintrace_access_through_symlink_checks_target_permission "Test that file through a symlink checks whether the target is in the sandbox" \ -setup { [setup [list deny "$cwd/stat" allow $cwd]] # while we're here, let's also test absolute symlinks file link -symbolic symlink "$cwd/stat" } \ -cleanup { [expect [list "$cwd/stat"]] file delete -force symlink } \ -body {exec -ignorestderr -- ./stat "$cwd/symlink" 2>@1} \ -result "stat: No such file or directory" test darwintrace_relative_symlink_at_top_level "Test that a relative symlink at the top level works as expected" \ -setup [setup [list allow /]] \ -cleanup [expect] \ -body {exec -ignorestderr -- ./stat "/tmp" 2>@1} \ -result "" test darwintrace_relative_symlinks "Test that resolution of relative symlinks works as expected" \ -setup { set levels [llength [regexp -all -inline -- "/" $cwd]] set path "[string repeat "../" [expr {$levels + 2}]]$cwd//./stat" [setup [list allow "$cwd/symlink"]] exec -ignorestderr -- ln -s $path symlink } \ -cleanup { file delete -force symlink [expect [list "$cwd/stat"]] } \ -body {exec -ignorestderr -- ./stat "$cwd/symlink" 2>@1} \ -result "stat: No such file or directory" test darwintrace_long_symlinks "Test that resolution of long symlinks does not trigger the stack canary" \ -setup { [setup [list allow /]] exec -- ln -s [string repeat "ab/de/ghi/" 102] longlink } \ -cleanup { [expect] file delete -force longlink } \ -body {exec -ignorestderr -- ./stat "$cwd/longlink" 2>@1} \ -result "stat: No such file or directory" test darwintrace_without_log_env_fails "Test that injecting the lib without setting DARWINTRACE_LOG fails" \ -body { set ::env(DYLD_INSERT_LIBRARIES) $darwintrace_lib exec -ignorestderr -- ./stat . 2>@1 } \ -returnCodes [list 1] \ -result "darwintrace: trace library loaded, but DARWINTRACE_LOG not set\nchild killed: SIGABRT" test darwintrace_with_incorrect_log_env_fails "Test that DARWINTRACE_LOG pointing to a non-socket fails" \ -body { set ::env(DYLD_INSERT_LIBRARIES) $darwintrace_lib set ::env(DARWINTRACE_LOG) "GARBAGE.RANDOM.DOES.NOT.EXIST" exec -ignorestderr -- ./stat . 2>@1 } \ -returnCodes [list 1] \ -result "darwintrace: connect: No such file or directory\nchild killed: SIGABRT" cleanupTests