All of lore.kernel.org
 help / color / mirror / Atom feed
* The prototype of SE-PostgreSQL
@ 2006-12-03 16:09 KaiGai Kohei
  0 siblings, 0 replies; only message in thread
From: KaiGai Kohei @ 2006-12-03 16:09 UTC (permalink / raw)
  To: selinux; +Cc: jbrindle, russell

[-- Attachment #1: Type: text/plain, Size: 2644 bytes --]

Hi,

In recent days, I'm working for development of SE-PostgreSQL as we talked
about two month earlier.
It does NOT have enough functionality compared to its specifications yet,
but we can apply access controls on the simple SQL statements.

The prototype versions of SE-PostgreSQL is now available at:
  http://code.google.com/p/sepgsql/

The very quick documentation is here:
  http://www.kaigai.gr.jp/index.php?sepgsql
  It also describes the way to checkout and building the SE-PostgreSQL.

The attached files are the patch of security policy which includes
the definition of new object classes and access vectors, and the
example SQL to define some table and tuples.

I would like to merge the patch, or the part of the definition of
new object classes and access vectors at least.

And we can play it as fllows:
[kaigai@masu ~]$ id -Z
root:system_r:unconfined_t:s0-s0:c0.c1023  <- more than 's0:c0.c1' is necessary to set up
[kaigai@masu ~]$ psql -f mytest.sql postgres
[kaigai@masu ~]$ psql postgres
kaigai=# select * from drink;
 id |  name  | price | cost | alcohol
----+--------+-------+------+---------
  1 | coffee |   120 |   80 | f
  2 | tea    |   120 |   70 | f
  5 | water  |   110 |   40 | f
  6 | coke   |   110 |   50 | f
  3 | wine   |   360 |  260 | t
  4 | beer   |   240 |  180 | t
(6 rows)

kaigai=# select * from person;
 uid | uname  | passwd
-----+--------+--------
   1 | KaiGai | aaa
   2 | ymj    | bbb
   3 | tak    | xyz
(3 rows)

kaigai=# \q
[kaigai@masu ~]$ runcon -l s0 bash
[kaigai@masu ~]$ id -Z
root:system_r:unconfined_t:s0
[kaigai@masu ~]$ psql postgres
kaigai=# select * from drink;
NOTICE:  denied { select } scontext=root:system_r:unconfined_t:s0
	tcontext=user_u:object_r:sepgsql_table_t:s0:c0 tclass=tuple
NOTICE:  denied { select } scontext=root:system_r:unconfined_t:s0
	tcontext=user_u:object_r:sepgsql_table_t:s0:c0 tclass=tuple
 id |  name  | price | cost | alcohol
----+--------+-------+------+---------
  1 | coffee |   120 |   80 | f
  2 | tea    |   120 |   70 | f
  5 | water  |   110 |   40 | f
  6 | coke   |   110 |   50 | f
(4 rows)  <-- alcohols are filtered

kaigai=# select * from person;
ERROR:  SELinux: denied { select } scontext=root:system_r:unconfined_t:s0
	tcontext=user_u:object_r:sepgsql_table_t:s0:c1 tclass=column name=passwd
kaigai=# select uid, uname, check_person_passwd(uid, 'xyz') from person;
 uid | uname  | check_person_passwd
-----+--------+---------------------
   1 | KaiGai | f
   2 | ymj    | f
   3 | tak    | t
(3 rows)  <-- using the trusted procedure instead of reference to 'passwd' column.

kaigai=# \q

Thanks,
-- 
KaiGai Kohei <kaigai@kaigai.gr.jp>

[-- Attachment #2: policy-sepgsql.patch --]
[-- Type: text/x-patch, Size: 9026 bytes --]

diff -rNU3 serefpolicy-2.4.5.orig/policy/flask/access_vectors serefpolicy-2.4.5.sepgsql/policy/flask/access_vectors
--- serefpolicy-2.4.5.orig/policy/flask/access_vectors	2006-11-27 12:00:21.000000000 +0900
+++ serefpolicy-2.4.5.sepgsql/policy/flask/access_vectors	2006-11-27 12:17:56.000000000 +0900
@@ -80,6 +80,20 @@
 }
 
 #
+#  Define a common prefix for userspace database object access vectors.
+#
+
+common database
+{
+	create
+	drop
+	getattr
+	setattr
+	relabelfrom
+	relabelto
+}
+
+#
 # Define the access vectors.
 #
 # class class_name [ inherits common_name ] { permission_name ... }
@@ -639,3 +653,55 @@
 	translate
 	contains
 }
+
+# definition for SE-PostgreSQL
+class database
+inherits database
+{
+	access
+	create_obj
+	drop_obj
+}
+
+class table
+inherits database
+{
+	select
+	update
+	insert
+	delete
+}
+
+class procedure
+inherits database
+{
+	execute
+	entrypoint
+}
+
+class column
+inherits database
+{
+	select
+	update
+	insert
+#	delete	# arguable one
+}
+
+class tuple
+{
+	relabelfrom
+	relabelto
+	select
+	update
+	insert
+	delete
+}
+
+class blob
+inherits database
+{
+	read
+	write
+}
+
diff -rNU3 serefpolicy-2.4.5.orig/policy/flask/security_classes serefpolicy-2.4.5.sepgsql/policy/flask/security_classes
--- serefpolicy-2.4.5.orig/policy/flask/security_classes	2006-11-17 22:47:47.000000000 +0900
+++ serefpolicy-2.4.5.sepgsql/policy/flask/security_classes	2006-11-27 12:13:29.000000000 +0900
@@ -95,4 +95,12 @@
 
 class context			# userspace
 
+# SE-PostgreSQL relation
+class database			# userspace
+class table			# userspace
+class procedure			# userspace
+class column			# userspace
+class tuple			# userspace
+class blob			# userspace
+
 # FLASK
diff -rNU3 serefpolicy-2.4.5.orig/policy/mcs serefpolicy-2.4.5.sepgsql/policy/mcs
--- serefpolicy-2.4.5.orig/policy/mcs	2006-11-17 22:47:47.000000000 +0900
+++ serefpolicy-2.4.5.sepgsql/policy/mcs	2006-11-27 13:10:04.000000000 +0900
@@ -98,4 +98,28 @@
 mlsconstrain process { sigkill sigstop }
 	(( h1 dom h2 ) or ( t1 == mcskillall ));
 
+# MCS policy for SE-PostgreSQL
+#-------------------------------
+
+# Any database object must be dominated by the relabeling subject
+# clearance, also the objects are single-level.
+mlsconstrain { database table procedure column blob } { create relabelto }
+	((h1 dom h2) and ( l1 domby h2 ) and ( l2 eq h2 ));
+mlsconstrain tuple { insert relabelto }
+	(( h1 dom h2 ) and ( l1 domby h2 ) and ( l2 eq h2 ));
+
+# Access control for any database objects based on MCS rules.
+mlsconstrain database { drop setattr relabelfrom access create_obj drop_obj }
+	( h1 dom h2 );
+mlsconstrain table { drop setattr relabelfrom select update insert delete }
+	( h1 dom h2 );
+mlsconstrain column { drop setattr relabelfrom select update insert }
+	( h1 dom h2 );
+mlsconstrain tuple { relabelfrom select update delete }
+	( h1 dom h2 );
+mlsconstrain procedure { execute }
+	( h1 dom h2 );
+mlsconstrain blob { drop setattr relabelfrom read write }
+	( h1 dom h2 );
+
 ') dnl end enable_mcs
diff -rNU3 serefpolicy-2.4.5.orig/policy/modules/services/postgresql.if serefpolicy-2.4.5.sepgsql/policy/modules/services/postgresql.if
--- serefpolicy-2.4.5.orig/policy/modules/services/postgresql.if	2006-11-17 22:47:48.000000000 +0900
+++ serefpolicy-2.4.5.sepgsql/policy/modules/services/postgresql.if	2006-11-27 13:40:33.000000000 +0900
@@ -118,3 +118,79 @@
         # Some versions of postgresql put the sock file in /tmp
 	allow $1 postgresql_tmp_t:sock_file write;
 ')
+
+########################################
+## <summary>
+##     Marks the specified type as a database object type.
+## </summary>
+## <param name="type">
+##     <summary>
+##     Type marked as a database object type.
+##     </summary>
+## </param>
+#
+interface(`sepgsql_database_object',`
+	gen_require(`
+		attribute sepgsql_database_object;
+	')
+	typeattribute $1 sepgsql_database_object;
+')
+
+########################################
+## <summary>
+##     Allows the specified domain unconfined access.
+## </summary>
+## <param name="domain">
+##     <summary>
+##     Domain allowed to access.
+##     </summary>
+## </param>
+#
+interface(`sepgsql_full_access',`
+	gen_require(`
+		class database  database_full_perms;
+		class table     table_full_perms;
+		class procedure proc_full_perms;
+		class column    column_full_perms;
+		class tuple     tuple_full_perms;
+		class blob      blob_full_perms;
+
+		bool sepgsql_enable_auditallow;
+
+		type postgresql_t;
+		type sepgsql_db_t;
+		type sepgsql_table_t;
+		type sepgsql_proc_t;
+		type sepgsql_trusted_proc_t;
+		type sepgsql_blob_t;
+	')
+	allow $1 sepgsql_db_t : database database_full_perms;
+	allow $1 sepgsql_table_t : table table_full_perms;
+	allow $1 sepgsql_table_t : column column_full_perms;
+	allow $1 sepgsql_table_t : tuple tuple_full_perms;
+	allow $1 sepgsql_proc_t : procedure proc_full_perms;
+	allow $1 sepgsql_trusted_proc_t : procedure proc_full_perms;
+	allow $1 sepgsql_blob_t : blob blob_full_perms;
+
+	if (sepgsql_enable_auditallow) {
+		auditallow $1 sepgsql_db_t : database database_full_perms;
+		auditallow $1 sepgsql_table_t : table table_full_perms;
+		auditallow $1 sepgsql_table_t : column column_full_perms;
+		auditallow $1 sepgsql_table_t : tuple tuple_full_perms;
+		auditallow $1 sepgsql_proc_t : procedure proc_full_perms;
+		auditallow $1 sepgsql_trusted_proc_t : procedure proc_full_perms;
+		auditallow $1 sepgsql_blob_t : blob blob_full_perms;
+	}
+
+	type_transition $1 { $1 postgresql_t } : database sepgsql_db_t;
+	type_transition $1 sepgsql_db_t : table sepgsql_table_t;
+	type_transition $1 sepgsql_db_t : procedure sepgsql_proc_t;
+	type_transition $1 sepgsql_db_t : blob sepgsql_blob_t;
+        ifdef(`enable_mcs',`
+		range_transition $1 sepgsql_trusted_proc_t mcs_systemhigh;
+        ')
+	ifdef(`enable_mls',`
+		range_transition $1 sepgsql_trusted_proc_t mls_systemhigh;
+	')
+')
+
diff -rNU3 serefpolicy-2.4.5.orig/policy/modules/services/postgresql.te serefpolicy-2.4.5.sepgsql/policy/modules/services/postgresql.te
--- serefpolicy-2.4.5.orig/policy/modules/services/postgresql.te	2006-11-17 22:47:49.000000000 +0900
+++ serefpolicy-2.4.5.sepgsql/policy/modules/services/postgresql.te	2006-11-27 13:29:10.000000000 +0900
@@ -27,6 +27,14 @@
 type postgresql_var_run_t;
 files_pid_file(postgresql_var_run_t)
 
+# SE-PostgreSQL related
+bool sepgsql_enable_auditallow false;
+type sepgsql_db_t;
+type sepgsql_table_t;
+type sepgsql_proc_t;
+type sepgsql_trusted_proc_t;
+type sepgsql_blob_t;
+
 ########################################
 #
 # postgresql Local policy
@@ -142,6 +150,8 @@
 
 mta_getattr_spool(postgresql_t)
 
+sepgsql_full_access(postgresql_t)
+
 ifdef(`targeted_policy', `
 	files_dontaudit_read_root_files(postgresql_t)
 	term_dontaudit_use_generic_ptys(postgresql_t)
diff -rNU3 serefpolicy-2.4.5.orig/policy/modules/system/unconfined.te serefpolicy-2.4.5.sepgsql/policy/modules/system/unconfined.te
--- serefpolicy-2.4.5.orig/policy/modules/system/unconfined.te	2006-11-27 12:00:21.000000000 +0900
+++ serefpolicy-2.4.5.sepgsql/policy/modules/system/unconfined.te	2006-11-27 13:42:36.000000000 +0900
@@ -135,6 +135,10 @@
 	')
 
 	optional_policy(`
+		sepgsql_full_access(unconfined_t)
+	')
+
+	optional_policy(`
 		# cjp: this should probably be removed:
 		rpc_domtrans_nfsd(unconfined_t)
 	')
diff -rNU3 serefpolicy-2.4.5.orig/policy/support/obj_perm_sets.spt serefpolicy-2.4.5.sepgsql/policy/support/obj_perm_sets.spt
--- serefpolicy-2.4.5.orig/policy/support/obj_perm_sets.spt	2006-11-17 22:47:50.000000000 +0900
+++ serefpolicy-2.4.5.sepgsql/policy/support/obj_perm_sets.spt	2006-11-27 13:43:14.000000000 +0900
@@ -224,3 +224,25 @@
 #
 define(`client_stream_socket_perms', `{ create ioctl read getattr write setattr append bind getopt setopt shutdown }')
 define(`server_stream_socket_perms', `{ client_stream_socket_perms listen accept }')
+
+#
+# Database objects (used in Security Enhanced PostgreSQL)
+#
+define(`database_full_perms', `{ create drop getattr setattr relabelfrom relabelto access create_obj drop_obj }')
+define(`database_user_perms', `{ getattr access create_obj drop_obj }')
+
+define(`table_full_perms', `{ create drop getattr setattr relabelfrom relabelto select update insert delete }')
+define(`table_user_perms', `{ create drop getattr setattr select update insert delete }')
+
+define(`proc_full_perms', `{ create drop getattr setattr relabelfrom relabelto execute entrypoint }')
+define(`proc_user_perms', `{ getattr execute entrypoint }')
+
+define(`column_full_perms', `{ create drop getattr setattr relabelfrom relabelto select update insert }')
+define(`column_user_perms', `{ create drop getattr setattr select update insert }')
+
+define(`tuple_full_perms', `{ relabelfrom relabelto select update insert delete }')
+define(`tuple_user_perms', `{ select update insert delete }')
+
+define(`blob_full_perms', `{ create drop getattr setattr relabelfrom relabelto read write }')
+define(`blob_user_perms', `{ create drop getattr setattr read write }')
+

[-- Attachment #3: mytest.sql --]
[-- Type: text/plain, Size: 1303 bytes --]

create table drink (
	id serial primary key,
	name text,
	price integer,
	cost integer,
	alcohol bool
);
insert into drink(name, price, cost, alcohol) values('coffee', 120, 80, false);
insert into drink(name, price, cost, alcohol) values('tea', 120, 70, false);
insert into drink(name, price, cost, alcohol) values('wine', 360, 260, true);
insert into drink(name, price, cost, alcohol) values('beer', 240, 180, true);
insert into drink(name, price, cost, alcohol) values('water', 110, 40, false);
insert into drink(name, price, cost, alcohol) values('coke', 110, 50, false);

update drink set security_context = 'user_u:object_r:sepgsql_table_t:s0:c0'
	where alcohol = true; 

create table person (
	uid serial primary key,
	uname text,
	passwd varchar(24)
);

insert into person (uname, passwd) values('KaiGai', 'aaa');
insert into person (uname, passwd) values('ymj', 'bbb');
insert into person (uname, passwd) values('tak', 'xyz');

create or replace function check_person_passwd (integer, text)
	returns bool language 'sql'
	as 'select passwd = $2 from person where uid=$1';

update pg_attribute set attselcon = 'user_u:object_r:sepgsql_table_t:s0:c1'
	where attrelid in (select tableoid from person) and attname='passwd';
update pg_proc set proselcon = 'user_u:object_r:sepgsql_trusted_proc_t:s0';

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-12-03 16:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-03 16:09 The prototype of SE-PostgreSQL KaiGai Kohei

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.