sepgsql-v9.3-creation-label-with-name.v1.patch

application/octet-stream

Filename: sepgsql-v9.3-creation-label-with-name.v1.patch
Type: application/octet-stream
Part: 0
Message: [sepgsql 1/3] add name qualified creation label

Patch

Format: unified
Series: patch v9
File+
contrib/sepgsql/database.c 2 1
contrib/sepgsql/expected/ddl.out 1 0
contrib/sepgsql/expected/label.out 32 3
contrib/sepgsql/proc.c 2 1
contrib/sepgsql/relation.c 6 3
contrib/sepgsql/schema.c 9 4
contrib/sepgsql/selinux.c 7 4
contrib/sepgsql/sepgsql.h 2 1
contrib/sepgsql/sepgsql-regtest.te 16 1
contrib/sepgsql/sql/label.sql 8 3
contrib/sepgsql/uavc.c 2 2
 contrib/sepgsql/database.c         |  3 ++-
 contrib/sepgsql/expected/ddl.out   |  1 +
 contrib/sepgsql/expected/label.out | 35 ++++++++++++++++++++++++++++++++---
 contrib/sepgsql/proc.c             |  3 ++-
 contrib/sepgsql/relation.c         |  9 ++++++---
 contrib/sepgsql/schema.c           | 13 +++++++++----
 contrib/sepgsql/selinux.c          | 11 +++++++----
 contrib/sepgsql/sepgsql-regtest.te | 17 ++++++++++++++++-
 contrib/sepgsql/sepgsql.h          |  3 ++-
 contrib/sepgsql/sql/label.sql      | 11 ++++++++---
 contrib/sepgsql/uavc.c             |  4 ++--
 11 files changed, 87 insertions(+), 23 deletions(-)

diff --git a/contrib/sepgsql/database.c b/contrib/sepgsql/database.c
index 975c1d4..1c58d4d 100644
--- a/contrib/sepgsql/database.c
+++ b/contrib/sepgsql/database.c
@@ -92,7 +92,8 @@ sepgsql_database_post_create(Oid databaseId, const char *dtemplate)
 
 	ncontext = sepgsql_compute_create(sepgsql_get_client_label(),
 									  tcontext,
-									  SEPG_CLASS_DB_DATABASE);
+									  SEPG_CLASS_DB_DATABASE,
+									  NameStr(datForm->datname));
 
 	/*
 	 * check db_database:{create} permission
diff --git a/contrib/sepgsql/expected/ddl.out b/contrib/sepgsql/expected/ddl.out
index 1f7ea88..be321de 100644
--- a/contrib/sepgsql/expected/ddl.out
+++ b/contrib/sepgsql/expected/ddl.out
@@ -61,6 +61,7 @@ CREATE SEQUENCE regtest_seq;
 LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
 LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_seq"
 CREATE TYPE regtest_comptype AS (a int, b text);
+LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
 CREATE FUNCTION regtest_func(text,int[]) RETURNS bool LANGUAGE plpgsql
 	   AS 'BEGIN RAISE NOTICE ''regtest_func => %'', $1; RETURN true; END';
 LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
diff --git a/contrib/sepgsql/expected/label.out b/contrib/sepgsql/expected/label.out
index d4a6f8a..0a15f27 100644
--- a/contrib/sepgsql/expected/label.out
+++ b/contrib/sepgsql/expected/label.out
@@ -64,10 +64,16 @@ SELECT sepgsql_getcon();	-- confirm client privilege
 
 CREATE TABLE t3 (s int, t text);
 INSERT INTO t3 VALUES (1, 'sss'), (2, 'ttt'), (3, 'uuu');
+SELECT sepgsql_getcon();	-- confirm client privilege
+                   sepgsql_getcon                   
+----------------------------------------------------
+ unconfined_u:unconfined_r:sepgsql_regtest_dba_t:s0
+(1 row)
+
+CREATE TABLE t4 (m int, n text);
+INSERT INTO t4 VALUES (1,'mmm'), (2,'nnn'), (3,'ooo');
 SELECT objtype, objname, label FROM pg_seclabels
-    WHERE provider = 'selinux'
-     AND  objtype in ('table', 'column')
-     AND  objname in ('t1', 't2', 't3');
+    WHERE provider = 'selinux' AND objtype = 'table' AND objname in ('t1', 't2', 't3');
  objtype | objname |                     label                     
 ---------+---------+-----------------------------------------------
  table   | t1      | unconfined_u:object_r:sepgsql_table_t:s0
@@ -75,6 +81,28 @@ SELECT objtype, objname, label FROM pg_seclabels
  table   | t3      | unconfined_u:object_r:user_sepgsql_table_t:s0
 (3 rows)
 
+SELECT objtype, objname, label FROM pg_seclabels
+    WHERE provider = 'selinux' AND objtype = 'column' AND (objname like 't3.%' OR objname like 't4.%');
+ objtype |   objname   |                     label                     
+---------+-------------+-----------------------------------------------
+ column  | t3.t        | unconfined_u:object_r:user_sepgsql_table_t:s0
+ column  | t3.s        | unconfined_u:object_r:user_sepgsql_table_t:s0
+ column  | t3.ctid     | unconfined_u:object_r:user_sepgsql_table_t:s0
+ column  | t3.xmin     | unconfined_u:object_r:user_sepgsql_table_t:s0
+ column  | t3.cmin     | unconfined_u:object_r:user_sepgsql_table_t:s0
+ column  | t3.xmax     | unconfined_u:object_r:user_sepgsql_table_t:s0
+ column  | t3.cmax     | unconfined_u:object_r:user_sepgsql_table_t:s0
+ column  | t3.tableoid | unconfined_u:object_r:user_sepgsql_table_t:s0
+ column  | t4.n        | unconfined_u:object_r:sepgsql_table_t:s0
+ column  | t4.m        | unconfined_u:object_r:sepgsql_table_t:s0
+ column  | t4.ctid     | unconfined_u:object_r:sepgsql_sysobj_t:s0
+ column  | t4.xmin     | unconfined_u:object_r:sepgsql_sysobj_t:s0
+ column  | t4.cmin     | unconfined_u:object_r:sepgsql_sysobj_t:s0
+ column  | t4.xmax     | unconfined_u:object_r:sepgsql_sysobj_t:s0
+ column  | t4.cmax     | unconfined_u:object_r:sepgsql_sysobj_t:s0
+ column  | t4.tableoid | unconfined_u:object_r:sepgsql_sysobj_t:s0
+(16 rows)
+
 --
 -- Tests for SECURITY LABEL
 --
@@ -456,6 +484,7 @@ SELECT sepgsql_getcon();	-- confirm client privilege
 DROP TABLE IF EXISTS t1 CASCADE;
 DROP TABLE IF EXISTS t2 CASCADE;
 DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE IF EXISTS t4 CASCADE;
 DROP FUNCTION IF EXISTS f1() CASCADE;
 DROP FUNCTION IF EXISTS f2() CASCADE;
 DROP FUNCTION IF EXISTS f3() CASCADE;
diff --git a/contrib/sepgsql/proc.c b/contrib/sepgsql/proc.c
index b47c880..a09270b 100644
--- a/contrib/sepgsql/proc.c
+++ b/contrib/sepgsql/proc.c
@@ -93,7 +93,8 @@ sepgsql_proc_post_create(Oid functionId)
 	tcontext = sepgsql_get_label(NamespaceRelationId,
 								 proForm->pronamespace, 0);
 	ncontext = sepgsql_compute_create(scontext, tcontext,
-									  SEPG_CLASS_DB_PROCEDURE);
+									  SEPG_CLASS_DB_PROCEDURE,
+									  NameStr(proForm->proname));
 
 	/*
 	 * check db_procedure:{create} permission
diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c
index a277fab..b6ea8d8 100644
--- a/contrib/sepgsql/relation.c
+++ b/contrib/sepgsql/relation.c
@@ -88,7 +88,8 @@ sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
 	scontext = sepgsql_get_client_label();
 	tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
 	ncontext = sepgsql_compute_create(scontext, tcontext,
-									  SEPG_CLASS_DB_COLUMN);
+									  SEPG_CLASS_DB_COLUMN,
+									  NameStr(attForm->attname));
 
 	/*
 	 * check db_column:{create} permission
@@ -279,7 +280,8 @@ sepgsql_relation_post_create(Oid relOid)
 	scontext = sepgsql_get_client_label();
 	tcontext = sepgsql_get_label(NamespaceRelationId,
 								 classForm->relnamespace, 0);
-	rcontext = sepgsql_compute_create(scontext, tcontext, tclass);
+	rcontext = sepgsql_compute_create(scontext, tcontext, tclass,
+									  NameStr(classForm->relname));
 
 	/*
 	 * check db_xxx:{create} permission
@@ -333,7 +335,8 @@ sepgsql_relation_post_create(Oid relOid)
 
 			ccontext = sepgsql_compute_create(scontext,
 											  rcontext,
-											  SEPG_CLASS_DB_COLUMN);
+											  SEPG_CLASS_DB_COLUMN,
+											  NameStr(attForm->attname));
 
 			/*
 			 * check db_column:{create} permission
diff --git a/contrib/sepgsql/schema.c b/contrib/sepgsql/schema.c
index 75b2826..932b5f2 100644
--- a/contrib/sepgsql/schema.c
+++ b/contrib/sepgsql/schema.c
@@ -42,6 +42,7 @@ sepgsql_schema_post_create(Oid namespaceId)
 	char	   *tcontext;
 	char	   *ncontext;
 	char		audit_name[NAMEDATALEN + 20];
+	const char *nsp_name;
 	ObjectAddress object;
 	Form_pg_namespace nspForm;
 
@@ -67,17 +68,21 @@ sepgsql_schema_post_create(Oid namespaceId)
 		elog(ERROR, "catalog lookup failed for namespace %u", namespaceId);
 
 	nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
+	nsp_name = NameStr(nspForm->nspname);
+	if (strncmp(nsp_name, "pg_temp_", 8) == 0)
+		nsp_name = "pg_temp";
+	else if (strncmp(nsp_name, "pg_toast_temp_", 14) == 0)
+		nsp_name = "pg_toast_temp";
 
 	tcontext = sepgsql_get_label(DatabaseRelationId, MyDatabaseId, 0);
 	ncontext = sepgsql_compute_create(sepgsql_get_client_label(),
 									  tcontext,
-									  SEPG_CLASS_DB_SCHEMA);
-
+									  SEPG_CLASS_DB_SCHEMA,
+									  nsp_name);
 	/*
 	 * check db_schema:{create}
 	 */
-	snprintf(audit_name, sizeof(audit_name),
-			 "schema %s", NameStr(nspForm->nspname));
+	snprintf(audit_name, sizeof(audit_name), "schema %s", nsp_name);
 	sepgsql_avc_check_perms_label(ncontext,
 								  SEPG_CLASS_DB_SCHEMA,
 								  SEPG_DB_SCHEMA__CREATE,
diff --git a/contrib/sepgsql/selinux.c b/contrib/sepgsql/selinux.c
index f70254f..863f0c1 100644
--- a/contrib/sepgsql/selinux.c
+++ b/contrib/sepgsql/selinux.c
@@ -836,7 +836,8 @@ sepgsql_compute_avd(const char *scontext,
 char *
 sepgsql_compute_create(const char *scontext,
 					   const char *tcontext,
-					   uint16 tclass)
+					   uint16 tclass,
+					   const char *objname)
 {
 	security_context_t ncontext;
 	security_class_t tclass_ex;
@@ -853,9 +854,11 @@ sepgsql_compute_create(const char *scontext,
 	 * Ask SELinux what is the default context for the given object class on a
 	 * pair of security contexts
 	 */
-	if (security_compute_create_raw((security_context_t) scontext,
-									(security_context_t) tcontext,
-									tclass_ex, &ncontext) < 0)
+	if (security_compute_create_name_raw((security_context_t) scontext,
+										 (security_context_t) tcontext,
+										 tclass_ex,
+										 objname,
+										 &ncontext) < 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INTERNAL_ERROR),
 				 errmsg("SELinux could not compute a new context: "
diff --git a/contrib/sepgsql/sepgsql-regtest.te b/contrib/sepgsql/sepgsql-regtest.te
index d872945..790c4e8 100644
--- a/contrib/sepgsql/sepgsql-regtest.te
+++ b/contrib/sepgsql/sepgsql-regtest.te
@@ -1,4 +1,4 @@
-policy_module(sepgsql-regtest, 1.04)
+policy_module(sepgsql-regtest, 1.05)
 
 gen_require(`
 	all_userspace_class_perms
@@ -43,6 +43,21 @@ 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
 #
diff --git a/contrib/sepgsql/sepgsql.h b/contrib/sepgsql/sepgsql.h
index 5ae5146..ab4a1a6 100644
--- a/contrib/sepgsql/sepgsql.h
+++ b/contrib/sepgsql/sepgsql.h
@@ -239,7 +239,8 @@ extern void sepgsql_compute_avd(const char *scontext,
 
 extern char *sepgsql_compute_create(const char *scontext,
 					   const char *tcontext,
-					   uint16 tclass);
+					   uint16 tclass,
+					   const char *objname);
 
 extern bool sepgsql_check_perms(const char *scontext,
 					const char *tcontext,
diff --git a/contrib/sepgsql/sql/label.sql b/contrib/sepgsql/sql/label.sql
index e63b5f6..6201cd7 100644
--- a/contrib/sepgsql/sql/label.sql
+++ b/contrib/sepgsql/sql/label.sql
@@ -71,10 +71,14 @@ SECURITY LABEL ON TABLE var_tbl
 CREATE TABLE t3 (s int, t text);
 INSERT INTO t3 VALUES (1, 'sss'), (2, 'ttt'), (3, 'uuu');
 
+-- @SECURITY-CONTEXT=unconfined_u:unconfined_r:sepgsql_regtest_dba_t:s0
+CREATE TABLE t4 (m int, n text);
+INSERT INTO t4 VALUES (1,'mmm'), (2,'nnn'), (3,'ooo');
+
+SELECT objtype, objname, label FROM pg_seclabels
+    WHERE provider = 'selinux' AND objtype = 'table' AND objname in ('t1', 't2', 't3');
 SELECT objtype, objname, label FROM pg_seclabels
-    WHERE provider = 'selinux'
-     AND  objtype in ('table', 'column')
-     AND  objname in ('t1', 't2', 't3');
+    WHERE provider = 'selinux' AND objtype = 'column' AND (objname like 't3.%' OR objname like 't4.%');
 
 --
 -- Tests for SECURITY LABEL
@@ -229,6 +233,7 @@ SELECT sepgsql_getcon();
 DROP TABLE IF EXISTS t1 CASCADE;
 DROP TABLE IF EXISTS t2 CASCADE;
 DROP TABLE IF EXISTS t3 CASCADE;
+DROP TABLE IF EXISTS t4 CASCADE;
 DROP FUNCTION IF EXISTS f1() CASCADE;
 DROP FUNCTION IF EXISTS f2() CASCADE;
 DROP FUNCTION IF EXISTS f3() CASCADE;
diff --git a/contrib/sepgsql/uavc.c b/contrib/sepgsql/uavc.c
index 84839c4..4e67aa0 100644
--- a/contrib/sepgsql/uavc.c
+++ b/contrib/sepgsql/uavc.c
@@ -250,10 +250,10 @@ sepgsql_avc_compute(const char *scontext, const char *tcontext, uint16 tclass)
 	{
 		if (!ucontext)
 			ncontext = sepgsql_compute_create(scontext, tcontext,
-											  SEPG_CLASS_PROCESS);
+											  SEPG_CLASS_PROCESS, NULL);
 		else
 			ncontext = sepgsql_compute_create(scontext, ucontext,
-											  SEPG_CLASS_PROCESS);
+											  SEPG_CLASS_PROCESS, NULL);
 		if (strcmp(scontext, ncontext) == 0)
 		{
 			pfree(ncontext);