aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2013-03-28 15:38:35 -0400
committerRobert Haas <rhaas@postgresql.org>2013-03-28 15:41:38 -0400
commit0f05840bf4c256b838eca8f1be9d7b5be82ccd0e (patch)
tree33f506bd41aad831419e63885a63a2200706344a
parentae7f1c3ef2eef9584e3c9a42c395eb0c0e59a5ed (diff)
downloadpostgresql-0f05840bf4c256b838eca8f1be9d7b5be82ccd0e.tar.gz
postgresql-0f05840bf4c256b838eca8f1be9d7b5be82ccd0e.zip
Allow sepgsql labels to depend on object name.
The main change here is to call security_compute_create_name_raw() rather than security_compute_create_raw(). This ups the minimum requirement for libselinux from 2.0.99 to 2.1.10, but it looks like most distributions will have picked that up before 9.3 is out. KaiGai Kohei
-rwxr-xr-xconfigure24
-rw-r--r--configure.in4
-rw-r--r--contrib/sepgsql/database.c3
-rw-r--r--contrib/sepgsql/expected/label.out35
-rw-r--r--contrib/sepgsql/proc.c3
-rw-r--r--contrib/sepgsql/relation.c9
-rw-r--r--contrib/sepgsql/schema.c13
-rw-r--r--contrib/sepgsql/selinux.c11
-rw-r--r--contrib/sepgsql/sepgsql-regtest.te17
-rw-r--r--contrib/sepgsql/sepgsql.h3
-rw-r--r--contrib/sepgsql/sql/label.sql11
-rw-r--r--contrib/sepgsql/uavc.c4
-rw-r--r--doc/src/sgml/sepgsql.sgml7
13 files changed, 104 insertions, 40 deletions
diff --git a/configure b/configure
index 9efd866059f..b391308d810 100755
--- a/configure
+++ b/configure
@@ -9710,9 +9710,9 @@ fi
# for contrib/sepgsql
if test "$with_selinux" = yes; then
-{ $as_echo "$as_me:$LINENO: checking for selinux_status_open in -lselinux" >&5
-$as_echo_n "checking for selinux_status_open in -lselinux... " >&6; }
-if test "${ac_cv_lib_selinux_selinux_status_open+set}" = set; then
+{ $as_echo "$as_me:$LINENO: checking for security_compute_create_name in -lselinux" >&5
+$as_echo_n "checking for security_compute_create_name in -lselinux... " >&6; }
+if test "${ac_cv_lib_selinux_security_compute_create_name+set}" = set; then
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
@@ -9730,11 +9730,11 @@ cat >>conftest.$ac_ext <<_ACEOF
#ifdef __cplusplus
extern "C"
#endif
-char selinux_status_open ();
+char security_compute_create_name ();
int
main ()
{
-return selinux_status_open ();
+return security_compute_create_name ();
;
return 0;
}
@@ -9760,12 +9760,12 @@ $as_echo "$ac_try_echo") >&5
test "$cross_compiling" = yes ||
$as_test_x conftest$ac_exeext
}; then
- ac_cv_lib_selinux_selinux_status_open=yes
+ ac_cv_lib_selinux_security_compute_create_name=yes
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
- ac_cv_lib_selinux_selinux_status_open=no
+ ac_cv_lib_selinux_security_compute_create_name=no
fi
rm -rf conftest.dSYM
@@ -9773,9 +9773,9 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_selinux_selinux_status_open" >&5
-$as_echo "$ac_cv_lib_selinux_selinux_status_open" >&6; }
-if test "x$ac_cv_lib_selinux_selinux_status_open" = x""yes; then
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_selinux_security_compute_create_name" >&5
+$as_echo "$ac_cv_lib_selinux_security_compute_create_name" >&6; }
+if test "x$ac_cv_lib_selinux_security_compute_create_name" = x""yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBSELINUX 1
_ACEOF
@@ -9783,8 +9783,8 @@ _ACEOF
LIBS="-lselinux $LIBS"
else
- { { $as_echo "$as_me:$LINENO: error: library 'libselinux', version 2.0.99 or newer, is required for SELinux support" >&5
-$as_echo "$as_me: error: library 'libselinux', version 2.0.99 or newer, is required for SELinux support" >&2;}
+ { { $as_echo "$as_me:$LINENO: error: library 'libselinux', version 2.1.10 or newer, is required for SELinux support" >&5
+$as_echo "$as_me: error: library 'libselinux', version 2.1.10 or newer, is required for SELinux support" >&2;}
{ (exit 1); exit 1; }; }
fi
diff --git a/configure.in b/configure.in
index f31f7efda01..f81fda75641 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 64d37a3ca99..91e6c4f441e 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/label.out b/contrib/sepgsql/expected/label.out
index d4a6f8ae962..0a15f279f84 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 53b941d8558..afc37553f25 100644
--- a/contrib/sepgsql/proc.c
+++ b/contrib/sepgsql/proc.c
@@ -95,7 +95,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 (install)} permission
diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c
index 8bcaa41d312..dd4593dd3ac 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
@@ -309,7 +310,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
@@ -363,7 +365,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 ecdfd738d91..74e16678cb5 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 f70254f2a74..863f0c143ff 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 d8729450747..790c4e85bb4 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 d4ee94be5a0..f7448cdeb68 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 e63b5f691dc..6201cd77214 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 84839c4867b..4e67aa02d1f 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 5ee08e1dee2..7c7f953f919 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>