|
| 1 | + |
| 2 | +# Copyright (c) 2024, PostgreSQL Global Development Group |
| 3 | + |
| 4 | +use strict; |
| 5 | +use warnings FATAL => 'all'; |
| 6 | + |
| 7 | +use PostgreSQL::Test::Cluster; |
| 8 | +use PostgreSQL::Test::Utils; |
| 9 | + |
| 10 | +use Test::More; |
| 11 | + |
| 12 | +if (!$ENV{PG_TEST_EXTRA} || $ENV{PG_TEST_EXTRA} !~ /\bsepgsql\b/) |
| 13 | +{ |
| 14 | + plan skip_all => |
| 15 | + 'Potentially unsafe test sepgsql not enabled in PG_TEST_EXTRA'; |
| 16 | +} |
| 17 | + |
| 18 | +note "checking selinux environment"; |
| 19 | + |
| 20 | +# matchpathcon must be present to assess whether the installation environment |
| 21 | +# is OK. |
| 22 | +note "checking for matchpathcon"; |
| 23 | +if (system('matchpathcon -n . >/dev/null 2>&1') != 0) |
| 24 | +{ |
| 25 | + diag <<EOS; |
| 26 | +
|
| 27 | +The matchpathcon command must be available. |
| 28 | +Please install it or update your PATH to include it |
| 29 | +(it is typically in '/usr/sbin', which might not be in your PATH). |
| 30 | +matchpathcon is typically included in the libselinux-utils package. |
| 31 | +EOS |
| 32 | + die; |
| 33 | +} |
| 34 | + |
| 35 | +# runcon must be present to launch psql using the correct environment |
| 36 | +note "checking for runcon"; |
| 37 | +if (system('runcon --help >/dev/null 2>&1') != 0) |
| 38 | +{ |
| 39 | + diag <<EOS; |
| 40 | +
|
| 41 | +The runcon command must be available. |
| 42 | +runcon is typically included in the coreutils package. |
| 43 | +EOS |
| 44 | + die; |
| 45 | +} |
| 46 | + |
| 47 | +# check sestatus too, since that lives in yet another package |
| 48 | +note "checking for sestatus"; |
| 49 | +if (system('sestatus >/dev/null 2>&1') != 0) |
| 50 | +{ |
| 51 | + diag <<EOS; |
| 52 | +
|
| 53 | +The sestatus command must be available. |
| 54 | +sestatus is typically included in the policycoreutils package. |
| 55 | +EOS |
| 56 | + die; |
| 57 | +} |
| 58 | + |
| 59 | +# check that the user is running in the unconfined_t domain |
| 60 | +note "checking current user domain"; |
| 61 | +my $DOMAIN = (split /:/, `id -Z 2>/dev/null`)[2]; |
| 62 | +note "current user domain is '$DOMAIN'"; |
| 63 | +if ($DOMAIN ne 'unconfined_t') |
| 64 | +{ |
| 65 | + diag <<'EOS'; |
| 66 | +
|
| 67 | +The regression tests must be launched from the unconfined_t domain. |
| 68 | +
|
| 69 | +The unconfined_t domain is typically the default domain for user |
| 70 | +shell processes. If the default has been changed on your system, |
| 71 | +you can revert the changes like this: |
| 72 | +
|
| 73 | + $ sudo semanage login -d `whoami` |
| 74 | +
|
| 75 | +Or, you can add a setting to log in using the unconfined_t domain: |
| 76 | +
|
| 77 | + $ sudo semanage login -a -s unconfined_u -r s0-s0:c0.c255 `whoami` |
| 78 | +
|
| 79 | +EOS |
| 80 | + die; |
| 81 | +} |
| 82 | + |
| 83 | +# SELinux must be configured in enforcing mode |
| 84 | +note "checking selinux operating mode"; |
| 85 | +my $CURRENT_MODE = |
| 86 | + (split /: */, `LANG=C sestatus | grep '^Current mode:'`)[1]; |
| 87 | +chomp $CURRENT_MODE; |
| 88 | +note "current operating mode is '$CURRENT_MODE'"; |
| 89 | +if ($CURRENT_MODE eq 'enforcing') |
| 90 | +{ |
| 91 | + # OK |
| 92 | +} |
| 93 | +elsif ($CURRENT_MODE eq 'permissive' || $CURRENT_MODE eq 'disabled') |
| 94 | +{ |
| 95 | + diag <<'EOS'; |
| 96 | +
|
| 97 | +Before running the regression tests, SELinux must be enabled and |
| 98 | +must be running in enforcing mode. |
| 99 | +
|
| 100 | +If SELinux is currently running in permissive mode, you can |
| 101 | +switch to enforcing mode using the 'setenforce' command. |
| 102 | +
|
| 103 | + $ sudo setenforce 1 |
| 104 | +
|
| 105 | +The system default setting is configured in /etc/selinux/config, |
| 106 | +or using a kernel boot parameter. |
| 107 | +EOS |
| 108 | + die; |
| 109 | +} |
| 110 | +else |
| 111 | +{ |
| 112 | + diag <<EOS; |
| 113 | +
|
| 114 | +Unable to determine the current selinux operating mode. Please |
| 115 | +verify that the sestatus command is installed and in your PATH. |
| 116 | +EOS |
| 117 | + die; |
| 118 | +} |
| 119 | + |
| 120 | +# 'sepgsql-regtest' policy module must be loaded |
| 121 | +note "checking for sepgsql-regtest policy"; |
| 122 | +my $SELINUX_MNT = (split /: */, `sestatus | grep '^SELinuxfs mount:'`)[1]; |
| 123 | +chomp $SELINUX_MNT; |
| 124 | +if ($SELINUX_MNT eq "") |
| 125 | +{ |
| 126 | + diag <<EOS; |
| 127 | +
|
| 128 | +Unable to find SELinuxfs mount point. |
| 129 | +
|
| 130 | +The sestatus command should report the location where SELinuxfs |
| 131 | +is mounted, but did not do so. |
| 132 | +EOS |
| 133 | + die; |
| 134 | +} |
| 135 | +if (!-e "${SELINUX_MNT}/booleans/sepgsql_regression_test_mode") |
| 136 | +{ |
| 137 | + diag <<'EOS'; |
| 138 | +
|
| 139 | +The 'sepgsql-regtest' policy module appears not to be installed. |
| 140 | +Without this policy installed, the regression tests will fail. |
| 141 | +You can install this module using the following commands: |
| 142 | +
|
| 143 | + $ make -f /usr/share/selinux/devel/Makefile |
| 144 | + $ sudo semodule -u sepgsql-regtest.pp |
| 145 | +
|
| 146 | +To confirm that the policy package is installed, use this command: |
| 147 | +
|
| 148 | + $ sudo semodule -l | grep sepgsql |
| 149 | +
|
| 150 | +EOS |
| 151 | + die; |
| 152 | +} |
| 153 | + |
| 154 | +# Verify that sepgsql_regression_test_mode is active. |
| 155 | +note "checking whether policy is enabled"; |
| 156 | +foreach |
| 157 | + my $policy ('sepgsql_regression_test_mode', 'sepgsql_enable_users_ddl') |
| 158 | +{ |
| 159 | + my $POLICY_STATUS = (split ' ', `getsebool $policy`)[2]; |
| 160 | + note "$policy is '$POLICY_STATUS'"; |
| 161 | + if ($POLICY_STATUS ne "on") |
| 162 | + { |
| 163 | + diag <<EOS; |
| 164 | +
|
| 165 | +The SELinux boolean '$policy' must be |
| 166 | +turned on in order to enable the rules necessary to run the |
| 167 | +regression tests. |
| 168 | +
|
| 169 | +EOS |
| 170 | + |
| 171 | + if ($POLICY_STATUS eq "") |
| 172 | + { |
| 173 | + diag <<EOS; |
| 174 | +We attempted to determine the state of this Boolean using |
| 175 | +'getsebool', but that command did not produce the expected |
| 176 | +output. Please verify that getsebool is available and in |
| 177 | +your PATH. |
| 178 | +EOS |
| 179 | + } |
| 180 | + else |
| 181 | + { |
| 182 | + diag <<EOS; |
| 183 | +You can turn on this variable using the following commands: |
| 184 | +
|
| 185 | + \$ sudo setsebool $policy on |
| 186 | +
|
| 187 | +For security reasons, it is suggested that you turn off this |
| 188 | +variable when regression testing is complete and the associated |
| 189 | +rules are no longer needed. |
| 190 | +EOS |
| 191 | + } |
| 192 | + die; |
| 193 | + } |
| 194 | +} |
| 195 | + |
| 196 | + |
| 197 | +# |
| 198 | +# checking complete - let's run the tests |
| 199 | +# |
| 200 | + |
| 201 | +note "running sepgsql regression tests"; |
| 202 | + |
| 203 | +my $node; |
| 204 | + |
| 205 | +$node = PostgreSQL::Test::Cluster->new('test'); |
| 206 | +$node->init; |
| 207 | +$node->append_conf('postgresql.conf', 'log_statement=none'); |
| 208 | + |
| 209 | +{ |
| 210 | + local %ENV = $node->_get_env(); |
| 211 | + |
| 212 | + my $result = run_log( |
| 213 | + [ |
| 214 | + 'postgres', '--single', |
| 215 | + '-F', '-c', |
| 216 | + 'exit_on_error=true', '-D', |
| 217 | + $node->data_dir, 'template0' |
| 218 | + ], |
| 219 | + '<', |
| 220 | + $ENV{share_contrib_dir} . '/sepgsql.sql'); |
| 221 | + ok($result, 'sepgsql installation script'); |
| 222 | +} |
| 223 | + |
| 224 | +$node->append_conf('postgresql.conf', 'shared_preload_libraries=sepgsql'); |
| 225 | +$node->start; |
| 226 | + |
| 227 | +my @tests = qw(label dml ddl alter misc); |
| 228 | + |
| 229 | +# Check if the truncate permission exists in the loaded policy, and if so, |
| 230 | +# run the truncate test |
| 231 | +# |
| 232 | +# Testing the TRUNCATE regression test can be done by manually adding |
| 233 | +# the permission with CIL if necessary: |
| 234 | +# sudo semodule -cE base |
| 235 | +# sudo sed -i -E 's/(class db_table.*?) \)/\1 truncate\)/' base.cil |
| 236 | +# sudo semodule -i base.cil |
| 237 | +push @tests, 'truncate' if -f '/sys/fs/selinux/class/db_table/perms/truncate'; |
| 238 | + |
| 239 | +$node->command_ok( |
| 240 | + [ |
| 241 | + $ENV{PG_REGRESS}, '--bindir=', '--inputdir=.', '--launcher', |
| 242 | + './launcher', @tests |
| 243 | + ], |
| 244 | + 'sepgsql tests'); |
| 245 | + |
| 246 | +done_testing(); |
0 commit comments