1# $OpenBSD: OpenBSD-Unveil.t,v 1.2 2023/07/07 02:07:35 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 my $tmpfile = File::Temp->new("OpenBSD-Unveil-XXXXXXXXX", TMPDIR => 1); 86 $tmpfile->printflush("This is a test\n"); 87 88 ok OpenBSD::Unveil::_unveil("$tmpfile", 'r'), 89 "Unveiled tempfile r"; 90 ok OpenBSD::Unveil::_unveil('/dev/null', 'wc'), 91 "Unvailed /dev/null wc"; 92 93 { 94 ok open(my $wfh, '>', '/dev/null'), 95 "Opened /dev/null for writing"; 96 ok print($wfh "Test\n"), "Printed to /dev/null"; 97 ok close($wfh), "Closed /dev/null"; 98 } 99 100 ok OpenBSD::Unveil::_unveil('/dev/null', 'w'), 101 "Unvailed /dev/null w"; 102 ok OpenBSD::Unveil::_unveil(), 103 "locked unveil"; 104 105 ok !-e '/dev/zero', "Stat says we can't see /dev/zero"; 106 ok -w $tmpfile, "Stat says we can write to tempfile"; 107 ok !-r '/dev/null', "Stat says we can't read from /dev/null"; 108 109 { 110 ok sysopen(my $wfh, '/dev/null', O_WRONLY), 111 "Sysopened /dev/null for writing"; 112 ok syswrite($wfh, "Test\n"), "Wrote to /dev/null"; 113 ok close($wfh), "Closed /dev/null"; 114 } 115 116 { 117 ok open(my $rfh, '<', $tmpfile), "Opened tempfile for reading"; 118 ok read( $rfh, my $data, 64), "Read from tempfile"; 119 ok close($rfh), "Closed tempfile"; 120 } 121 122 { 123 ok !open(my $wfh, '>', $tmpfile), 124 "Unable to 'open' tempfile for writing"; 125 is $!, 'Permission denied', "Expected ERRNO from open"; 126 } 127 128 { 129 ok !open(my $wfh, '>', '/dev/null'), 130 "Unable to 'open' /dev/null without 'create'"; 131 is $!, 'Permission denied', "Expected ERRNO from open"; 132 } 133}; 134 135xsunveil_ok "Invalid Path" => sub { 136 my $dir = File::Temp->newdir('OpenBSD-Unveil-XXXXXXXXX', TMPDIR => 1); 137 ok !OpenBSD::Unveil::_unveil("$dir/nonexist/file", 'r'), 138 "Unable to unveil with incorrect permissions"; 139 is $!, 'No such file or directory', "Expected ERRNO from _unveil"; 140}; 141 142xsunveil_ok "Invalid Permissions" => sub { 143 ok !OpenBSD::Unveil::_unveil('/dev/null', 'abc'), 144 "Unable to unveil with incorrect permissions"; 145 is $!, 'Invalid argument', "Expected ERRNO from _unveil"; 146}; 147 148xsunveil_ok "Try to increase permissions" => sub { 149 ok OpenBSD::Unveil::_unveil('/dev/null', 'r'), 150 "Set /dev/null to r"; 151 TODO: { local $TODO = "Not sure why this fails"; 152 ok !OpenBSD::Unveil::_unveil('/dev/null', 'rwc'), 153 "Unable to increase permissions on /dev/null"; 154 is $!, 'Operation not permitted', "Expected ERRNO from _unveil"; 155 } 156}; 157 158xsunveil_ok "Try to change veil after lock" => sub { 159 ok OpenBSD::Unveil::_unveil(), "Locked unveil"; 160 ok !OpenBSD::Unveil::_unveil('/dev/null', 'r'), 161 "Unable to unveil after lock"; 162 is $!, 'Operation not permitted', "Expected ERRNO from _unveil"; 163}; 164 165######################### 166done_testing; 167 1681; # to shut up critic 169