1# $OpenBSD: OpenBSD-Unveil.t,v 1.1 2019/07/09 20:41:54 afresh1 Exp $ # 2## no critic 'version' 3## no critic 'package' 4# Before 'make install' is performed this script should be runnable with 5# 'make test'. After 'make install' it should work as 'perl OpenBSD-Unveil.t' 6 7######################### 8 9use strict; 10use warnings; 11 12use Test2::IPC; 13use Test::More; 14 15use Fcntl qw< O_RDONLY O_WRONLY >; 16use File::Temp; 17 18use POSIX qw< :errno_h >; 19 20BEGIN { use_ok('OpenBSD::Unveil') } 21 22######################### 23# UNVEIL 24######################### 25{ 26 my @calls; 27 no warnings 'redefine'; ## no critic 'warnings'; 28 local *OpenBSD::Unveil::_unveil = sub { push @calls, \@_; return 1 }; 29 use warnings 'redefine'; 30 31 { 32 local $@; 33 eval { local $SIG{__DIE__}; 34 OpenBSD::Unveil::unveil(qw< ab cx yz >) }; 35 my $at = sprintf "at %s line %d.\n", __FILE__, __LINE__ - 1; 36 is $@, 37 "Usage: OpenBSD::Unveil::unveil([path, permissions]) $at", 38 "Expected exception when too many params" 39 } 40 41 { 42 local $@; 43 eval { local $SIG{__DIE__}; 44 OpenBSD::Unveil::unveil(qw< ab >) }; 45 my $at = sprintf "at %s line %d.\n", __FILE__, __LINE__ - 1; 46 is $@, 47 "Usage: OpenBSD::Unveil::unveil([path, permissions]) $at", 48 "Expected exception when not enough params" 49 } 50 51 ok OpenBSD::Unveil::unveil( qw< foo bar > ), "Used two args"; 52 ok OpenBSD::Unveil::unveil(), "Used zero args"; 53 54 is_deeply \@calls, [ [ qw< foo bar > ], [] ], 55 "No modification to params"; 56} 57 58## no critic 'private' 59## no critic 'punctuation' 60######################### 61# _UNVEIL 62######################### 63 64sub xsunveil_ok ($$) ## no critic 'prototypes' 65{ 66 my ( $name, $code ) = @_; 67 local $Test::Builder::Level = 68 $Test::Builder::Level + 1; ## no critic 'package variable' 69 70 my $pid = fork // die "Unable to fork for $name: $!\n"; 71 72 if ( !$pid ) { 73 # for Test2::IPC 74 OpenBSD::Unveil::_unveil('/tmp', 'rwc') || die $!; 75 subtest $name, $code; 76 exit 0; 77 } 78 79 waitpid $pid, 0; 80 return $? >> 8; 81} 82 83 84xsunveil_ok "Basic Usage" => sub { 85 ok OpenBSD::Unveil::_unveil('/dev/random', 'r'), 86 "Unveiled /dev/random r"; 87 ok OpenBSD::Unveil::_unveil('/dev/null', 'wc'), 88 "Unvailed /dev/null wc"; 89 90 ok !-e '/dev/zero', "Can't see /dev/zero"; 91 ok !-w '/dev/random', "Can't write to /dev/random"; 92 ok !-r '/dev/null', "Can't read from /dev/null"; 93 94 ok open(my $rfh, '<', '/dev/random'), "Opened /dev/random for reading"; 95 ok read( $rfh, my $data, 64), "Read from /dev/random"; 96 ok close($rfh), "Closed /dev/random"; 97 98 { 99 ok open(my $wfh, '>', '/dev/null'), 100 "Opened /dev/null for writing"; 101 ok print($wfh $data), "Printed to /dev/null"; 102 ok close($wfh), "Closed /dev/null"; 103 } 104 105 ok OpenBSD::Unveil::_unveil('/dev/null', 'w'), 106 "Unvailed /dev/null w"; 107 ok OpenBSD::Unveil::_unveil(), 108 "locked unveil"; 109 110 { 111 ok sysopen(my $wfh, '/dev/null', O_WRONLY), 112 "Sysopened /dev/null for writing"; 113 ok syswrite($wfh, $data), "Wrote to /dev/null"; 114 ok close($wfh), "Closed /dev/null"; 115 } 116 117 { 118 ok !open(my $wfh, '>', '/dev/null'), 119 "Unable to 'open' without 'create'"; 120 } 121}; 122 123xsunveil_ok "Invalid Path" => sub { 124 chdir "/tmp" or die "Unable to chdir to /tmp"; 125 my $dir = File::Temp->newdir('OpenBSD-Unveil-XXXXXXXXX'); 126 ok !OpenBSD::Unveil::_unveil("$dir/nonexist/file", 'r'), 127 "Unable to unveil with incorrect permissions"; 128 is $!, 'No such file or directory', "Expected ERRNO from _unveil"; 129}; 130 131xsunveil_ok "Invalid Permissions" => sub { 132 ok !OpenBSD::Unveil::_unveil('/dev/null', 'abc'), 133 "Unable to unveil with incorrect permissions"; 134 is $!, 'Invalid argument', "Expected ERRNO from _unveil"; 135}; 136 137xsunveil_ok "Try to increase permissions" => sub { 138 ok OpenBSD::Unveil::_unveil('/dev/null', 'r'), 139 "Set /dev/null to r"; 140 TODO: { local $TODO = "Not sure why this fails"; 141 ok !OpenBSD::Unveil::_unveil('/dev/null', 'rwc'), 142 "Unable to increase permissions on /dev/null"; 143 is $!, 'Operation not permitted', "Expected ERRNO from _unveil"; 144 } 145}; 146 147xsunveil_ok "Try to change veil after lock" => sub { 148 ok OpenBSD::Unveil::_unveil(), "Locked unveil"; 149 ok !OpenBSD::Unveil::_unveil('/dev/null', 'r'), 150 "Unable to unveil after lock"; 151 is $!, 'Operation not permitted', "Expected ERRNO from _unveil"; 152}; 153 154######################### 155done_testing; 156 1571; # to shut up critic 158