mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-24 01:29:19 +03:00 
			
		
		
		
	Use SELinux "db_table: { truncate }" to check if permission is granted to
TRUNCATE. Update example SELinux policy to grant needed permission for
TRUNCATE. Add new regression test to demonstrate a positive and negative
cases. Test will only be run if the loaded SELinux policy has the
"db_table: { truncate }" permission. Makes use of recent commit which added
object TRUNCATE hook. Patch by Yuli Khodorkovskiy with minor
editorialization by me. Not back-patched because the object TRUNCATE hook
was not.
Author: Yuli Khodorkovskiy
Reviewed-by: Joe Conway
Discussion: https://postgr.es/m/CAFL5wJcomybj1Xdw7qWmPJRpGuFukKgNrDb6uVBaCMgYS9dkaA%40mail.gmail.com
		
	
		
			
				
	
	
		
			262 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			262 lines
		
	
	
		
			9.5 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)
 | |
| 
 | |
| auth_read_passwd(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)
 | |
| 
 | |
| auth_read_passwd(sepgsql_regtest_dba_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)
 | |
| 
 | |
| auth_read_passwd(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)
 | |
| 
 | |
| auth_read_passwd(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(`
 | |
| 		class db_table { truncate };
 | |
| 	')
 | |
| 
 | |
| 	allow sepgsql_regtest_superuser_t sepgsql_regtest_foo_table_t:db_table { truncate };
 | |
| ')
 | |
| 
 | |
| 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 };
 | |
| ')
 |