sepgsql-v9.3-creation-label-with-name.v2.patch
application/octet-stream
Filename: sepgsql-v9.3-creation-label-with-name.v2.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
Series: patch v9
| File | + | − |
|---|---|---|
| configure.in | 2 | 2 |
| 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 |
| doc/src/sgml/sepgsql.sgml | 4 | 3 |
configure.in | 4 ++--
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 ++--
doc/src/sgml/sepgsql.sgml | 7 ++++---
13 files changed, 93 insertions(+), 28 deletions(-)
diff --git a/configure.in b/configure.in
index f31f7ef..f81fda7 100644
--- a/configure.in
+++ b/configure.in
@@ -952,8 +952,8 @@ fi
# for contrib/sepgsql
if test "$with_selinux" = yes; then
- AC_CHECK_LIB(selinux, selinux_status_open, [],
- [AC_MSG_ERROR([library 'libselinux', version 2.0.99 or newer, is required for SELinux support])])
+ AC_CHECK_LIB(selinux, security_compute_create_name, [],
+ [AC_MSG_ERROR([library 'libselinux', version 2.1.10 or newer, is required for SELinux support])])
fi
# for contrib/uuid-ossp
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);
diff --git a/doc/src/sgml/sepgsql.sgml b/doc/src/sgml/sepgsql.sgml
index 522aa8b..fafa3a3 100644
--- a/doc/src/sgml/sepgsql.sgml
+++ b/doc/src/sgml/sepgsql.sgml
@@ -63,7 +63,7 @@
<filename>sepgsql</> can only be used on <productname>Linux</productname>
2.6.28 or higher with <productname>SELinux</productname> enabled.
It is not available on any other platform. You will also need
- <productname>libselinux</> 2.0.99 or higher and
+ <productname>libselinux</> 2.1.10 or higher and
<productname>selinux-policy</> 3.9.13 or higher (although some
distributions may backport the necessary rules into older policy
versions).
@@ -326,8 +326,9 @@ $ sudo semodule -r sepgsql-regtest
When <filename>sepgsql</filename> is in use, security labels are
automatically assigned to supported database objects at creation time.
This label is called a default security label, and is decided according
- to the system security policy, which takes as input the creator's label
- and the label assigned to the new object's parent object.
+ to the system security policy, which takes as input the creator's label,
+ the label assigned to the new object's parent object and optionally name
+ of the constructed object.
</para>
<para>