From 2f8e73932b1068caf696582487de9e100fcd46be Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Mon, 13 May 2024 07:55:55 +0200 Subject: [PATCH v1] Convert sepgsql tests to TAP Add a TAP test for sepgsql. This automates the previously required manual setup before the test. The actual tests are still run by pg_regress, but not called from within the TAP Perl script. TODO: remove the old test scripts? --- contrib/sepgsql/.gitignore | 3 + contrib/sepgsql/Makefile | 3 + contrib/sepgsql/meson.build | 11 +- contrib/sepgsql/t/001_sepgsql.pl | 248 +++++++++++++++++++++++++++++++ doc/src/sgml/regress.sgml | 11 ++ doc/src/sgml/sepgsql.sgml | 2 + meson.build | 1 + src/Makefile.global.in | 1 + 8 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 contrib/sepgsql/t/001_sepgsql.pl diff --git a/contrib/sepgsql/.gitignore b/contrib/sepgsql/.gitignore index 31613e011f5..7cadb9419e9 100644 --- a/contrib/sepgsql/.gitignore +++ b/contrib/sepgsql/.gitignore @@ -1,7 +1,10 @@ /sepgsql.sql +# FIXME /sepgsql-regtest.fc /sepgsql-regtest.if /sepgsql-regtest.pp /tmp # Generated subdirectories +/log/ /results/ +/tmp_check/ diff --git a/contrib/sepgsql/Makefile b/contrib/sepgsql/Makefile index afca75b693f..5cc9697736c 100644 --- a/contrib/sepgsql/Makefile +++ b/contrib/sepgsql/Makefile @@ -15,6 +15,9 @@ OBJS = \ DATA_built = sepgsql.sql PGFILEDESC = "sepgsql - SELinux integration" +TAP_TESTS = 1 + +# FIXME # Note: because we don't tell the Makefile there are any regression tests, # we have to clean those result files explicitly EXTRA_CLEAN = -r $(pg_regress_clean_files) tmp/ *.pp sepgsql-regtest.if sepgsql-regtest.fc diff --git a/contrib/sepgsql/meson.build b/contrib/sepgsql/meson.build index 9544efe0287..5817ba30a58 100644 --- a/contrib/sepgsql/meson.build +++ b/contrib/sepgsql/meson.build @@ -40,4 +40,13 @@ contrib_targets += custom_target('sepgsql.sql', install_dir: contrib_data_args['install_dir'], ) -# TODO: implement sepgsql tests +tests += { + 'name': 'sepgsql', + 'sd': meson.current_source_dir(), + 'bd': meson.current_build_dir(), + 'tap': { + 'tests': [ + 't/001_sepgsql.pl', + ], + }, +} diff --git a/contrib/sepgsql/t/001_sepgsql.pl b/contrib/sepgsql/t/001_sepgsql.pl new file mode 100644 index 00000000000..82bba5774ce --- /dev/null +++ b/contrib/sepgsql/t/001_sepgsql.pl @@ -0,0 +1,248 @@ + +# Copyright (c) 2024, PostgreSQL Global Development Group + +use strict; +use warnings FATAL => 'all'; + +use PostgreSQL::Test::Cluster; +use PostgreSQL::Test::Utils; + +use Test::More; + +if (!$ENV{PG_TEST_EXTRA} || $ENV{PG_TEST_EXTRA} !~ /\bsepgsql\b/) +{ + plan skip_all => + 'Potentially unsafe test sepgsql not enabled in PG_TEST_EXTRA'; +} + +note "checking selinux environment"; + +# matchpathcon must be present to assess whether the installation environment +# is OK. +note "checking for matchpathcon"; +if (system('matchpathcon -n . >/dev/null 2>&1') != 0) +{ + diag </dev/null 2>&1') != 0) +{ + diag </dev/null 2>&1') != 0) +{ + diag </dev/null | sed 's/:/ /g' | awk '{print \$3}'`; +chomp $DOMAIN; +note "current user domain is '$DOMAIN'"; +if ($DOMAIN ne 'unconfined_t') +{ + diag <<'EOS'; + +The regression tests must be launched from the unconfined_t domain. + +The unconfined_t domain is typically the default domain for user +shell processes. If the default has been changed on your system, +you can revert the changes like this: + + $ sudo semanage login -d `whoami` + +Or, you can add a setting to log in using the unconfined_t domain: + + $ sudo semanage login -a -s unconfined_u -r s0-s0:c0.c255 `whoami` + +EOS + die; +} + +# SELinux must be configured in enforcing mode +note "checking selinux operating mode"; +my $CURRENT_MODE = + `LANG=C sestatus | grep '^Current mode:' | awk '{print \$3}'`; +chomp $CURRENT_MODE; +note "current operating mode is '$CURRENT_MODE'"; +if ($CURRENT_MODE eq 'enforcing') +{ + # OK +} +elsif ($CURRENT_MODE eq 'permissive' || $CURRENT_MODE eq 'disabled') +{ + diag <<'EOS'; + +Before running the regression tests, SELinux must be enabled and +must be running in enforcing mode. + +If SELinux is currently running in permissive mode, you can +switch to enforcing mode using the 'setenforce' command. + + $ sudo setenforce 1 + +The system default setting is configured in /etc/selinux/config, +or using a kernel boot parameter. +EOS + die; +} +else +{ + diag <new('test'); +$node->init; +$node->append_conf('postgresql.conf', 'log_statement=none'); + +{ + local %ENV = $node->_get_env(); + + my $result = run_log( + [ + 'postgres', '--single', + '-F', '-c', + 'exit_on_error=true', '-D', + $node->data_dir, 'template0' + ], + '<', + $ENV{builddir} . '/sepgsql.sql'); + ok($result, 'sepgsql installation script'); +} + +$node->append_conf('postgresql.conf', 'shared_preload_libraries=sepgsql'); +$node->start; + +my @tests = qw(label dml ddl alter misc); + +# Check if the truncate permission exists in the loaded policy, and if so, +# run the truncate test +# +# Testing the TRUNCATE regression test can be done by manually adding +# the permission with CIL if necessary: +# sudo semodule -cE base +# sudo sed -i -E 's/(class db_table.*?) \)/\1 truncate\)/' base.cil +# sudo semodule -i base.cil +push @tests, 'truncate' if -f '/sys/fs/selinux/class/db_table/perms/truncate'; + +$node->command_ok( + [ + $ENV{PG_REGRESS}, '--bindir=', '--inputdir=.', '--launcher', + './launcher', @tests + ], + 'sepgsql tests'); + +done_testing(); diff --git a/doc/src/sgml/regress.sgml b/doc/src/sgml/regress.sgml index d1042e02228..9aebd9f3bed 100644 --- a/doc/src/sgml/regress.sgml +++ b/doc/src/sgml/regress.sgml @@ -284,6 +284,17 @@ Additional Test Suites + + sepgsql + + + Runs the test suite under contrib/sepgsql. This + requires an SELinux environment that is set up in a specific way; see + . + + + + ssl diff --git a/doc/src/sgml/sepgsql.sgml b/doc/src/sgml/sepgsql.sgml index 1b848f1977c..a21e2d86279 100644 --- a/doc/src/sgml/sepgsql.sgml +++ b/doc/src/sgml/sepgsql.sgml @@ -151,6 +151,8 @@ Installation Regression Tests + + Due to the nature of SELinux, running the regression tests for sepgsql requires several extra diff --git a/meson.build b/meson.build index 1c0579d5a6b..49e61b33960 100644 --- a/meson.build +++ b/meson.build @@ -3375,6 +3375,7 @@ foreach test_dir : tests # Add temporary install, the build directory for non-installed binaries and # also test/ for non-installed test binaries built separately. env = test_env + env.set('builddir', test_dir['bd']) env.prepend('PATH', temp_install_bindir, test_dir['bd'], test_dir['bd'] / 'test') foreach name, value : t.get('env', {}) diff --git a/src/Makefile.global.in b/src/Makefile.global.in index a00c909681e..9f87cae879b 100644 --- a/src/Makefile.global.in +++ b/src/Makefile.global.in @@ -477,6 +477,7 @@ echo "# +++ tap check in $(subdir) +++" && \ rm -rf '$(CURDIR)'/tmp_check && \ $(MKDIR_P) '$(CURDIR)'/tmp_check && \ cd $(srcdir) && \ + builddir='$(CURDIR)' \ TESTLOGDIR='$(CURDIR)/tmp_check/log' \ TESTDATADIR='$(CURDIR)/tmp_check' \ $(with_temp_install) \ base-commit: 3ca43dbbb67fbfb96dec8de2e268b96790555148 -- 2.44.0