]> granicus.if.org Git - postgresql/commitdiff
Allow sepgsql labels to depend on object name.
authorRobert Haas <rhaas@postgresql.org>
Thu, 28 Mar 2013 19:38:35 +0000 (15:38 -0400)
committerRobert Haas <rhaas@postgresql.org>
Thu, 28 Mar 2013 19:41:38 +0000 (15:41 -0400)
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

13 files changed:
configure
configure.in
contrib/sepgsql/database.c
contrib/sepgsql/expected/label.out
contrib/sepgsql/proc.c
contrib/sepgsql/relation.c
contrib/sepgsql/schema.c
contrib/sepgsql/selinux.c
contrib/sepgsql/sepgsql-regtest.te
contrib/sepgsql/sepgsql.h
contrib/sepgsql/sql/label.sql
contrib/sepgsql/uavc.c
doc/src/sgml/sepgsql.sgml

index 9efd866059fea207a711e8bd8e2e7c669828a2ca..b391308d810ae82e8e137c4e678802298224b1d1 100755 (executable)
--- 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
 
index f31f7efda018f443ed838985f7d3be974960b3e9..f81fda75641f53bef60beb18dbe56b03eb5d2b55 100644 (file)
@@ -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
index 64d37a3ca9939b17bb31ac878a89c4141333fce5..91e6c4f441ea3446d0c4a04298dfaedf06b7fa43 100644 (file)
@@ -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
index d4a6f8ae9620fa5cda86fa22da057268e8429524..0a15f279f8446673e19e7805a99be7d29c9e8e35 100644 (file)
@@ -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;
index 53b941d85583e19976fd53aaead03f7fda9f598b..afc37553f2528167567d50770bdbb16995970d5c 100644 (file)
@@ -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
index 8bcaa41d312e1e20e0a02d10443562b449159c1f..dd4593dd3ac22d8ccd05beb30de21a7dcbba3c13 100644 (file)
@@ -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
index ecdfd738d911cef23b1d1e9affdaba34b8fb071f..74e16678cb5e8c55fcbc50dc63b07143ff3758ba 100644 (file)
@@ -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,
index f70254f2a7446dbb6ee192ed396587072f590d54..863f0c143ffa2f073902f373021d8ea695f91836 100644 (file)
@@ -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: "
index d8729450747473f949af38a3e380ff0cec703592..790c4e85bb49235a93ead0bffbe89491b75abd0e 100644 (file)
@@ -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
 #
index d4ee94be5a08d62e1cfea65fc75952da40b45cf3..f7448cdeb68b35d47887c13e011bfbdf414b4b2b 100644 (file)
@@ -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,
index e63b5f691dcbe4853a2640a6707f7320f96c349d..6201cd77214f03b5770b354fc63d4c5bd5e9db02 100644 (file)
@@ -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;
index 84839c4867baee71d55472afbb47696322d3185a..4e67aa02d1fa7c6a8a71cdd89cbf9d645995aea7 100644 (file)
@@ -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);
index 5ee08e1dee2b36553c39f9c9af5b9c16ed1bc932..7c7f953f9191ab6a18b5282780d68ccb01cd53b8 100644 (file)
@@ -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>