mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
794e2558be
The regression tests for sepgsql were broken by changes in the base distro as-shipped policies. Specifically, definition of unconfined_t in the system default policy was changed to bypass multi-category rules, which the regression test depended on. Fix that by defining a custom privileged domain (sepgsql_regtest_superuser_t) and using it instead of system's unconfined_t domain. The new sepgsql_regtest_superuser_t domain performs almost like the current unconfined_t, but restricted by multi-category policy as the traditional unconfined_t was. The custom policy module is a self defined domain, and so should not be affected by related future system policy changes. However, it still uses the unconfined_u:unconfined_r pair for selinux-user and role. Those definitions have not been changed for several years and seem less risky to rely on than the unconfined_t domain. Additionally, if we define custom user/role, they would need to be manually defined at the operating system level, adding more complexity to an already non-standard and complex regression test. Back-patch to 9.3. The regression tests will need more work before working correctly on 9.2. Starting with 9.2, sepgsql has had dependencies on libselinux versions that are only available on newer distros with the changed set of policies (e.g. RHEL 7.x). On 9.1 sepgsql works fine with the older distros with original policy set (e.g. RHEL 6.x), and on which the existing regression tests work fine. We might want eventually change 9.1 sepgsql regression tests to be more independent from the underlying OS policies, however more work will be needed to make that happen and it is not clear that it is worth the effort. Kohei KaiGai with review by Adam Brightwell and me, commentary by Stephen, Alvaro, Tom, Robert, and others.
243 lines
9.2 KiB
Plaintext
243 lines
9.2 KiB
Plaintext
policy_module(sepgsql-regtest, 1.08)
|
|
|
|
gen_require(`
|
|
all_userspace_class_perms
|
|
')
|
|
|
|
## <desc>
|
|
## <p>
|
|
## Allow to launch regression test of SE-PostgreSQL
|
|
## Don't switch to TRUE in normal cases
|
|
## </p>
|
|
## </desc>
|
|
gen_tunable(sepgsql_regression_test_mode, false)
|
|
|
|
#
|
|
# Type definitions for regression test
|
|
#
|
|
type sepgsql_regtest_trusted_proc_exec_t;
|
|
postgresql_procedure_object(sepgsql_regtest_trusted_proc_exec_t)
|
|
type sepgsql_nosuch_trusted_proc_exec_t;
|
|
postgresql_procedure_object(sepgsql_nosuch_trusted_proc_exec_t)
|
|
|
|
type sepgsql_regtest_invisible_schema_t;
|
|
postgresql_schema_object(sepgsql_regtest_invisible_schema_t);
|
|
|
|
#
|
|
# Test domains for self defined unconfined / superuser
|
|
#
|
|
role sepgsql_regtest_superuser_r;
|
|
userdom_base_user_template(sepgsql_regtest_superuser)
|
|
userdom_manage_home_role(sepgsql_regtest_superuser_r, sepgsql_regtest_superuser_t)
|
|
userdom_exec_user_home_content_files(sepgsql_regtest_superuser_t)
|
|
userdom_write_user_tmp_sockets(sepgsql_regtest_superuser_t)
|
|
optional_policy(`
|
|
postgresql_stream_connect(sepgsql_regtest_superuser_t)
|
|
postgresql_unconfined(sepgsql_regtest_superuser_t)
|
|
')
|
|
optional_policy(`
|
|
unconfined_stream_connect(sepgsql_regtest_superuser_t)
|
|
unconfined_rw_pipes(sepgsql_regtest_superuser_t)
|
|
')
|
|
optional_policy(`
|
|
gen_require(`
|
|
attribute sepgsql_client_type;
|
|
')
|
|
allow sepgsql_regtest_superuser_t self : process { setcurrent };
|
|
allow sepgsql_regtest_superuser_t { self sepgsql_client_type } : process { dyntransition };
|
|
')
|
|
|
|
# Type transition rules
|
|
allow sepgsql_regtest_user_t sepgsql_regtest_dba_t : process { transition };
|
|
type_transition sepgsql_regtest_user_t sepgsql_regtest_trusted_proc_exec_t:process sepgsql_regtest_dba_t;
|
|
type_transition sepgsql_regtest_user_t sepgsql_nosuch_trusted_proc_exec_t:process sepgsql_regtest_nosuch_t;
|
|
|
|
#
|
|
# Test domains for database administrators
|
|
#
|
|
role sepgsql_regtest_dba_r;
|
|
userdom_base_user_template(sepgsql_regtest_dba)
|
|
userdom_manage_home_role(sepgsql_regtest_dba_r, sepgsql_regtest_dba_t)
|
|
userdom_exec_user_home_content_files(sepgsql_regtest_dba_t)
|
|
userdom_write_user_tmp_sockets(sepgsql_regtest_user_t)
|
|
optional_policy(`
|
|
postgresql_admin(sepgsql_regtest_dba_t, sepgsql_regtest_dba_r)
|
|
postgresql_stream_connect(sepgsql_regtest_dba_t)
|
|
')
|
|
optional_policy(`
|
|
unconfined_stream_connect(sepgsql_regtest_dba_t)
|
|
unconfined_rw_pipes(sepgsql_regtest_dba_t)
|
|
')
|
|
|
|
# Type transition rules
|
|
allow sepgsql_regtest_dba_t self : process { setcurrent };
|
|
allow sepgsql_regtest_dba_t sepgsql_regtest_user_t : process { dyntransition };
|
|
allow sepgsql_regtest_dba_t sepgsql_regtest_foo_t : process { dyntransition };
|
|
allow sepgsql_regtest_dba_t sepgsql_regtest_var_t : process { dyntransition };
|
|
|
|
# special rule for system columns
|
|
optional_policy(`
|
|
gen_require(`
|
|
attribute sepgsql_table_type;
|
|
type sepgsql_sysobj_t;
|
|
')
|
|
type_transition sepgsql_regtest_dba_t sepgsql_table_type:db_column sepgsql_sysobj_t "ctid";
|
|
type_transition sepgsql_regtest_dba_t sepgsql_table_type:db_column sepgsql_sysobj_t "oid";
|
|
type_transition sepgsql_regtest_dba_t sepgsql_table_type:db_column sepgsql_sysobj_t "xmin";
|
|
type_transition sepgsql_regtest_dba_t sepgsql_table_type:db_column sepgsql_sysobj_t "xmax";
|
|
type_transition sepgsql_regtest_dba_t sepgsql_table_type:db_column sepgsql_sysobj_t "cmin";
|
|
type_transition sepgsql_regtest_dba_t sepgsql_table_type:db_column sepgsql_sysobj_t "cmax";
|
|
type_transition sepgsql_regtest_dba_t sepgsql_table_type:db_column sepgsql_sysobj_t "tableoid";
|
|
')
|
|
|
|
#
|
|
# Dummy domain for unpriv users
|
|
#
|
|
role sepgsql_regtest_user_r;
|
|
userdom_base_user_template(sepgsql_regtest_user)
|
|
userdom_manage_home_role(sepgsql_regtest_user_r, sepgsql_regtest_user_t)
|
|
userdom_exec_user_home_content_files(sepgsql_regtest_user_t)
|
|
userdom_write_user_tmp_sockets(sepgsql_regtest_user_t)
|
|
optional_policy(`
|
|
postgresql_role(sepgsql_regtest_user_r, sepgsql_regtest_user_t)
|
|
postgresql_stream_connect(sepgsql_regtest_user_t)
|
|
')
|
|
optional_policy(`
|
|
unconfined_stream_connect(sepgsql_regtest_user_t)
|
|
unconfined_rw_pipes(sepgsql_regtest_user_t)
|
|
')
|
|
# Type transition rules
|
|
allow sepgsql_regtest_user_t sepgsql_regtest_dba_t : process { transition };
|
|
type_transition sepgsql_regtest_user_t sepgsql_regtest_trusted_proc_exec_t:process sepgsql_regtest_dba_t;
|
|
type_transition sepgsql_regtest_user_t sepgsql_nosuch_trusted_proc_exec_t:process sepgsql_regtest_nosuch_t;
|
|
|
|
#
|
|
# Dummy domain for (virtual) connection pooler software
|
|
#
|
|
# XXX - this test scenario assumes sepgsql_regtest_pool_t domain performs
|
|
# as a typical connection pool server; that switches the client label of
|
|
# this session prior to any user queries. The sepgsql_regtest_(foo|var)_t
|
|
# is allowed to access its own table types, but not allowed to reference
|
|
# other's one.
|
|
#
|
|
role sepgsql_regtest_pool_r;
|
|
userdom_base_user_template(sepgsql_regtest_pool)
|
|
userdom_manage_home_role(sepgsql_regtest_pool_r, sepgsql_regtest_pool_t)
|
|
userdom_exec_user_home_content_files(sepgsql_regtest_pool_t)
|
|
userdom_write_user_tmp_sockets(sepgsql_regtest_pool_t)
|
|
|
|
type sepgsql_regtest_foo_t;
|
|
type sepgsql_regtest_var_t;
|
|
type sepgsql_regtest_foo_table_t;
|
|
type sepgsql_regtest_var_table_t;
|
|
|
|
allow sepgsql_regtest_foo_t sepgsql_regtest_foo_table_t:db_table { getattr select update insert delete lock };
|
|
allow sepgsql_regtest_foo_t sepgsql_regtest_foo_table_t:db_column { getattr select update insert };
|
|
allow sepgsql_regtest_foo_t sepgsql_regtest_foo_table_t:db_tuple { select update insert delete };
|
|
|
|
allow sepgsql_regtest_var_t sepgsql_regtest_var_table_t:db_table { getattr select update insert delete lock };
|
|
allow sepgsql_regtest_var_t sepgsql_regtest_var_table_t:db_column { getattr select update insert };
|
|
allow sepgsql_regtest_var_t sepgsql_regtest_var_table_t:db_tuple { select update insert delete };
|
|
|
|
optional_policy(`
|
|
gen_require(`
|
|
role unconfined_r;
|
|
')
|
|
postgresql_role(unconfined_r, sepgsql_regtest_foo_t)
|
|
postgresql_role(unconfined_r, sepgsql_regtest_var_t)
|
|
postgresql_table_object(sepgsql_regtest_foo_table_t)
|
|
postgresql_table_object(sepgsql_regtest_var_table_t)
|
|
')
|
|
optional_policy(`
|
|
postgresql_stream_connect(sepgsql_regtest_pool_t)
|
|
postgresql_role(sepgsql_regtest_pool_r, sepgsql_regtest_pool_t)
|
|
')
|
|
optional_policy(`
|
|
unconfined_stream_connect(sepgsql_regtest_pool_t)
|
|
unconfined_rw_pipes(sepgsql_regtest_pool_t)
|
|
')
|
|
# type transitions
|
|
allow sepgsql_regtest_pool_t self:process { setcurrent };
|
|
allow sepgsql_regtest_pool_t sepgsql_regtest_dba_t:process { transition };
|
|
type_transition sepgsql_regtest_pool_t sepgsql_regtest_trusted_proc_exec_t:process sepgsql_regtest_dba_t;
|
|
|
|
allow { sepgsql_regtest_foo_t sepgsql_regtest_var_t } self:process { setcurrent };
|
|
allow { sepgsql_regtest_foo_t sepgsql_regtest_var_t } sepgsql_regtest_pool_t:process { dyntransition };
|
|
|
|
#
|
|
# Dummy domain for non-exist users
|
|
#
|
|
role sepgsql_regtest_nosuch_r;
|
|
userdom_base_user_template(sepgsql_regtest_nosuch)
|
|
optional_policy(`
|
|
postgresql_role(sepgsql_regtest_nosuch_r, sepgsql_regtest_nosuch_t)
|
|
')
|
|
|
|
#
|
|
# Rules to launch psql in the dummy domains
|
|
#
|
|
optional_policy(`
|
|
gen_require(`
|
|
role unconfined_r;
|
|
type unconfined_t;
|
|
type sepgsql_trusted_proc_t;
|
|
')
|
|
tunable_policy(`sepgsql_regression_test_mode',`
|
|
allow unconfined_t self : process { setcurrent dyntransition };
|
|
allow unconfined_t sepgsql_regtest_dba_t : process { transition dyntransition };
|
|
allow unconfined_t sepgsql_regtest_superuser_t : process { transition dyntransition };
|
|
allow unconfined_t sepgsql_regtest_user_t : process { transition dyntransition };
|
|
allow unconfined_t sepgsql_regtest_pool_t : process { transition dyntransition };
|
|
')
|
|
role unconfined_r types sepgsql_regtest_dba_t;
|
|
role unconfined_r types sepgsql_regtest_superuser_t;
|
|
role unconfined_r types sepgsql_regtest_user_t;
|
|
role unconfined_r types sepgsql_regtest_nosuch_t;
|
|
role unconfined_r types sepgsql_trusted_proc_t;
|
|
|
|
role unconfined_r types sepgsql_regtest_pool_t;
|
|
role unconfined_r types sepgsql_regtest_foo_t;
|
|
role unconfined_r types sepgsql_regtest_var_t;
|
|
')
|
|
|
|
#
|
|
# Rule to make MCS policy work on regression test
|
|
#
|
|
# NOTE: MCS (multi category security) policy was enabled by default, to
|
|
# allow DAC style access control, in the previous selinux policy.
|
|
# However, its definition was changed later, then a limited number of
|
|
# applications are restricted by MCS policy, for container features
|
|
# mainly. The rules below enables MCS policy for domains of regression
|
|
# test also, even if base security policy does not apply. If base policy
|
|
# is old and MCS is enabled in default, rules below does nothing.
|
|
#
|
|
optional_policy(`
|
|
gen_require(`
|
|
type sepgsql_trusted_proc_t;
|
|
')
|
|
mcs_constrained(sepgsql_regtest_dba_t)
|
|
mcs_constrained(sepgsql_regtest_superuser_t)
|
|
mcs_constrained(sepgsql_regtest_user_t)
|
|
mcs_constrained(sepgsql_regtest_nosuch_t)
|
|
mcs_constrained(sepgsql_trusted_proc_t)
|
|
|
|
mcs_constrained(sepgsql_regtest_pool_t)
|
|
mcs_constrained(sepgsql_regtest_foo_t)
|
|
mcs_constrained(sepgsql_regtest_var_t)
|
|
')
|
|
|
|
#
|
|
# Rule to execute original trusted procedures
|
|
#
|
|
# These rules intends to allow any valid client types to launch trusted-
|
|
# procedures (including ones causes domain transition to invalid domain)
|
|
# being labeled as sepgsql_regtest_trusted_proc_exec_t and
|
|
# sepgsql_nosuch_trusted_proc_exec_t.
|
|
#
|
|
optional_policy(`
|
|
gen_require(`
|
|
attribute sepgsql_client_type;
|
|
')
|
|
allow sepgsql_client_type { sepgsql_regtest_trusted_proc_exec_t sepgsql_nosuch_trusted_proc_exec_t }:db_procedure { getattr execute entrypoint };
|
|
')
|