diff --git a/contrib/sepgsql/.gitignore b/contrib/sepgsql/.gitignore index 1e4a297b09b..811143c074c 100644 --- a/contrib/sepgsql/.gitignore +++ b/contrib/sepgsql/.gitignore @@ -1 +1,5 @@ /sepgsql.sql +/sepgsql-regtest.fc +/sepgsql-regtest.if +/sepgsql-regtest.pp +/tmp diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c index cfa436d37d9..684b5ee8e61 100644 --- a/contrib/sepgsql/dml.c +++ b/contrib/sepgsql/dml.c @@ -171,12 +171,12 @@ check_relation_privileges(Oid relOid, SEPG_DB_TABLE__DELETE)) != 0) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("selinux: hardwired security policy violation"))); + errmsg("SELinux: hardwired security policy violation"))); if (relkind == RELKIND_TOASTVALUE) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("selinux: hardwired security policy violation"))); + errmsg("SELinux: hardwired security policy violation"))); } /* diff --git a/contrib/sepgsql/hooks.c b/contrib/sepgsql/hooks.c index 6b55e484cfd..bc7ce51cf15 100644 --- a/contrib/sepgsql/hooks.c +++ b/contrib/sepgsql/hooks.c @@ -91,7 +91,7 @@ sepgsql_client_auth(Port *port, int status) if (getpeercon_raw(port->sock, &context) < 0) ereport(FATAL, (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("selinux: failed to get the peer label"))); + errmsg("SELinux: unable to get peer label"))); sepgsql_set_client_label(context); @@ -318,7 +318,7 @@ sepgsql_utility_command(Node *parsetree, { ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("SELinux: LOAD is not allowed anyway."))); + errmsg("SELinux: LOAD is not permitted"))); } break; default: @@ -352,8 +352,8 @@ _PG_init(void) */ if (IsUnderPostmaster) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("Not allowed to load SE-PostgreSQL now"))); + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("sepgsql must be loaded via shared_preload_libraries"))); /* * Check availability of SELinux on the platform. @@ -414,7 +414,7 @@ _PG_init(void) if (getcon_raw(&context) < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("selinux: unable to get security label of server"))); + errmsg("SELinux: failed to get server security label"))); sepgsql_set_client_label(context); /* Security label provider hook */ diff --git a/contrib/sepgsql/label.c b/contrib/sepgsql/label.c index bc28adfea55..ad568f8aa6b 100644 --- a/contrib/sepgsql/label.c +++ b/contrib/sepgsql/label.c @@ -81,7 +81,7 @@ sepgsql_get_label(Oid classId, Oid objectId, int32 subId) if (security_get_initial_context_raw("unlabeled", &unlabeled) < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("selinux: unable to get initial security label"))); + errmsg("SELinux: failed to get initial security label"))); PG_TRY(); { label = pstrdup(unlabeled); @@ -114,7 +114,7 @@ sepgsql_object_relabel(const ObjectAddress *object, const char *seclabel) security_check_context_raw((security_context_t) seclabel) < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), - errmsg("invalid security label: \"%s\"", seclabel))); + errmsg("SELinux: invalid security label: \"%s\"", seclabel))); /* * Do actual permission checks for each object classes */ @@ -154,13 +154,11 @@ sepgsql_getcon(PG_FUNCTION_ARGS) char *client_label; if (!sepgsql_is_enabled()) - ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("SELinux: now disabled"))); + PG_RETURN_NULL(); client_label = sepgsql_get_client_label(); - PG_RETURN_POINTER(cstring_to_text(client_label)); + PG_RETURN_TEXT_P(cstring_to_text(client_label)); } /* @@ -179,14 +177,14 @@ sepgsql_mcstrans_in(PG_FUNCTION_ARGS) if (!sepgsql_is_enabled()) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("SELinux: now disabled"))); + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("sepgsql is not enabled"))); if (selinux_trans_to_raw_context(text_to_cstring(label), &raw_label) < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("SELinux: internal error on mcstrans"))); + errmsg("SELinux: could not translate security label"))); PG_TRY(); { @@ -200,7 +198,7 @@ sepgsql_mcstrans_in(PG_FUNCTION_ARGS) PG_END_TRY(); freecon(raw_label); - PG_RETURN_POINTER(cstring_to_text(result)); + PG_RETURN_TEXT_P(cstring_to_text(result)); } /* @@ -219,14 +217,14 @@ sepgsql_mcstrans_out(PG_FUNCTION_ARGS) if (!sepgsql_is_enabled()) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("SELinux: now disabled"))); + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("sepgsql is not currently enabled"))); if (selinux_raw_to_trans_context(text_to_cstring(label), &qual_label) < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("SELinux: internal error on mcstrans"))); + errmsg("SELinux: could not translate security label"))); PG_TRY(); { @@ -240,7 +238,7 @@ sepgsql_mcstrans_out(PG_FUNCTION_ARGS) PG_END_TRY(); freecon(qual_label); - PG_RETURN_POINTER(cstring_to_text(result)); + PG_RETURN_TEXT_P(cstring_to_text(result)); } /* @@ -360,8 +358,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId) break; default: - elog(ERROR, "Bug? %u is not supported to set initial labels", - catalogId); + elog(ERROR, "unexpected catalog id: %u", catalogId); break; } @@ -387,12 +384,12 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId) } else if (errno == ENOENT) ereport(WARNING, - (errmsg("no valid initial label on %s (type=%d), skipped", + (errmsg("SELinux: no initial label assigned for %s (type=%d), skipping", objname, objtype))); else ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("libselinux: internal error"))); + errmsg("SELinux: could not determine initial security label for %s (type=%d)", objname, objtype))); } systable_endscan(sscan); @@ -422,8 +419,8 @@ sepgsql_restorecon(PG_FUNCTION_ARGS) */ if (!sepgsql_is_enabled()) ereport(ERROR, - (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), - errmsg("SELinux: now disabled"))); + (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), + errmsg("sepgsql is not currently enabled"))); /* * Check DAC permission. Only superuser can set up initial * security labels, like root-user in filesystems @@ -431,7 +428,7 @@ sepgsql_restorecon(PG_FUNCTION_ARGS) if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be superuser to restore initial contexts"))); + errmsg("SELinux: must be superuser to restore initial contexts"))); /* * Open selabel_lookup(3) stuff. It provides a set of mapping @@ -452,7 +449,7 @@ sepgsql_restorecon(PG_FUNCTION_ARGS) if (!sehnd) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), - errmsg("SELinux internal error"))); + errmsg("SELinux: failed to initialize labeling handle"))); PG_TRY(); { /* diff --git a/doc/src/sgml/sepgsql.sgml b/doc/src/sgml/sepgsql.sgml index 91b8614b81a..d95d121f4b1 100644 --- a/doc/src/sgml/sepgsql.sgml +++ b/doc/src/sgml/sepgsql.sgml @@ -8,9 +8,12 @@ </indexterm> <para> - The <filename>sepgsql</> is a module which performs as an external - security provider; to support label based mandatory access control - (MAC) base on <productname>SELinux</> policy. + <filename>sepgsql</> is a loadable module which supports label-based + mandatory access control (MAC) based on <productname>SELinux</> security + policy. This implementation is not complete, and primarily provides + protection for Data Manipulation Language statements (DML). Support for + fine-grained access control of Data Definition Language (DDL) and Data + Control Language (DCL) statements may be added in a future release. </para> <para> This extension won't build at all unless the installation was configured @@ -21,59 +24,44 @@ <title>Overview</title> <para> - <productname>PostgreSQL</> provides various kind of hooks. Some of these - hooks can be utilized to make access control decision on the supplied - users' accesses on database objects. - We call plug-in modules making access control decision based on its own - security model as an external security provider. + This module integrates with <productname>SELinux</> to provide an + additional layer of security checking above and beyond what is normaly + provided by <productname>PostgreSQL</productname>. From the perspective of + <productname>SELinux</>, this module allows + <productname>PostgreSQL</productname> to function as a user-space object + manager. Each table or function access initiated by a DML query will be + checked against the system security policy. This check is an additional to + the usual permissions checking performed by + <productname>PostgreSQL</productname>. </para> + <para> - This module acquires control on these strategic points, then it asks - <productname>SELinux</> to check whether the supplied access shall be - allowed, or not. Then, it returns its access control decision. - If violated, this module prevents this access with rising an error for - example. + <productname>SELinux</productname> access control decisions are made using + security labels, which are represented by strings such as + <literal>system_u:object_r:sepgsql_table_t:s0</>. Each access control + decision involves two labels: the label of the subject attempting to + perform the action, and the label of the object on which the operation is + to be performed. Since these labels can be applied to any sort of object, + access control decisions for objects stored within the database can be + (and, with this module, are) subjected to the same general criteria used + for objects of any other type (e.g. files). This design is intended to + allow a centralized security policy to protect information assets + independent of the particulars of how those assets are stored. </para> + <para> - A series of making decision is done independently from the default - database privilege mechanism. Users must be allowed with both of access - control models, whenever they try to access something. - </para> - <para> - We can see <productname>SELinux</> as a function which takes two arguments - then returns a bool value; allowed or denied. The first argument in this - analogy is label of subject which tries to reference a certain obejct. - The other one is label of the object being referenced in this operation. - </para> - <para> - Label is a formatted string, - like <literal>system_u:object_r:sepgsql_table_t:s0</>. - It is not a property depending on characteristics of a certain kind of - object, so we can apply common credentials on either database objects - or others. - </para> - <para> - <productname>PostgreSQL</> 9.1 or later supports - <xref linkend="sql-security-label"> statement that allows to assign - a security label on specified database objects, if user wants to change - label from the creation default. - Also <productname>SELinux</> provides an interface to obtain security - label of the peer process that connected to. - </para> - <para> - These facilities enable to integrate <productname>SELinux</> model within - access controls to database objects. Because it makes access control - decision according to a common centralized security policy (a set of rules), - its decision will be always consistent independent from the way to store - information assets. + The <xref linkend="sql-security-label"> statement allows assignment of + a security label to a database object. </para> + </sect2> <sect2 id="sepgsql-installation"> <title>Installation</title> + <para> - The <filename>sepgsql</> module requires the following packages to install. - Please check it at first. + This module has several prerequisites. </para> + <variablelist> <varlistentry> <term><productname>Linux kernel</productname></term> @@ -103,14 +91,14 @@ </para> <para> The default security policy provides a set of access control rules. - Some of distribution may backports necessary rules, even if base - policy was older than above version. + Some distributions may backport necessary rules to older policy versions. </para> </listitem> </varlistentry> </variablelist> <para> - <productname>SE-PostgreSQL</> needs <productname>SELinux</> being + + <productname>sepgsql</> needs <productname>SELinux</> being available on the platform. You can check the current setting using <command>sestatus</>. <screen> @@ -122,38 +110,41 @@ Mode from config file: enforcing Policy version: 24 Policy from config file: targeted </screen> - If disabled or not-installed, you need to set up <productname>SELinux</> - prior to all the installation step of <productname>SE-PostgreSQL</>. + If <productname>SELinux</> is disabled or not installed, you must set + that product up first before installing this module. </para> + <para> - On the compile time, add <literal>--with-selinux</> option to - the <command>configure</> script to check existence of - the <productname>libselinux</>, and to set a flag whether - we build this contrib module, or not. + At compile time, pass the <literal>--with-selinux</> option to + the <command>configure</> script to enable this module. + <screen> $ ./configure --enable-debug --enable-cassert --with-selinux $ make $ make install </screen> </para> - <para> - Next to the <command>initdb</>, add <literal>'$libdir/sepgsql'</> - to <xref linkend="guc-shared-preload-libraries"> in - the <filename>postgresql.conf</>. - It enables to load <filename>sepgsql</> on the starting up of - postmaster process. - </para> <para> - Then, load the <filename>sepgsql.sql</filename> script for each databases. - It installs functions corresponding to security label management, and - tries to assign initial labels on the target objects. + Following <command>initdb</>, add <literal>'$libdir/sepgsql'</> + to <xref linkend="guc-shared-preload-libraries"> in + the <filename>postgresql.conf</>. Note that <productname>sepgsql</> + must be loaded at server startup. </para> + + <para> + Next, load the <filename>sepgsql.sql</filename> script for each database. + It installs functions for security label management, and attempts to assign + initial labels to the target objects. + </para> + <para> The following instruction assumes your installation is under the <filename>/usr/local/pgsql</> directory, and the database cluster is in - <filename>/usr/local/pgsql/data</>. Substitute your paths appropriately. + <filename>/usr/local/pgsql/data</>. Adjust the paths shown below as + appropriate for your installaton. </para> + <screen> $ initdb -D $PGDATA $ vi $PGDATA/postgresql.conf @@ -162,34 +153,32 @@ $ for DBNAME in template0 template1 postgres; do < /usr/local/pgsql/share/contrib/sepgsql.sql > /dev/null done </screen> + <para> - If all the installation process was done with no errors, start postmaster - process. <productname>SE-PostgreSQL</> shall prevent violated accesses - according to the security policy of <productname>SELinux</>. + If the installation process completes without error, you can now start the + server normally. </para> </sect2> <sect2 id="sepgsql-regression"> <title>Regression Tests</title> <para> - The regression test of this module requires a few more configurations - on the platform system, in addition to the above installation process. - See the following steps. + Due to the nature of <productname>SELinux</productname>, running the + regression tests for this module requires several additional configuration + steps. </para> + <para> - First, install the policy package for regression test. + First, install the policy package for the regression test. The <filename>sepgsql-regtest.pp</> is a special purpose policy package - that provides a set of rules to be allowed during the regression test - cases. It shall be installed at <filename>/usr/local/pgsql/share/contrib</> - directory in the default setup. - </para> - <para> - You need to install this policy package using <command>semodule</> - command which enables to link supplied policy packages and load them - into the kernel space. If you could install the pakage correctly, - <literal><command>semodule</> -l</> prints sepgsql-regtest as a part - of policy packages currently available. + which provides a set of rules to be allowed during the regression tests. + You need to install this policy package using the <command>semodule</> + command, which links supplied policy packages and loads them + into the kernel space. If this packages is correctly installed, + <literal><command>semodule</> -l</> should list sepgsql-regtest as an + available policy package. </para> + <screen> $ su # semodule -u /usr/local/pgsql/share/contrib/sepgsql-regtest.pp @@ -198,78 +187,50 @@ $ su sepgsql-regtest 1.03 : </screen> + <para> - Second, turn on the <literal>sepgsql_regression_test_mode</>. + Second, turn on <literal>sepgsql_regression_test_mode</>. We don't enable all the rules in the <filename>sepgsql-regtest.pp</> - in the default, for your system's safety. + by default, for your system's safety. The <literal>sepgsql_regression_test_mode</literal> parameter is associated with rules to launch regression test. It can be turned on using <command>setsebool</> command. </para> + <screen> $ su # setsebool sepgsql_regression_test_mode on # getsebool sepgsql_regression_test_mode sepgsql_regression_test_mode --> on </screen> + <para> Last, kick the regression test from the <literal>unconfined_t</> domain. </para> - <para> - This test policy is designed to kick each test cases from the - <literal>unconfined_t</> domain that is a default choice in most of - the known <literal>SELinux</> installation base. - So, you don't need to set up anything special, as long as you didn't - change default configuration of SELinux before. - </para> + <para> The <command>id</> command tells us the current working domain. - Confirm your shell is now performing with <literal>unconfined_t</> + Confirm your shell is now performing with the <literal>unconfined_t</> domain as follows. </para> <screen> $ id -Z unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 </screen> - <para> - If not an expected one, you should revert this configuration. - The <xref linkend="sepgsql-resources"> section will give you - some useful hints. - </para> - <para> - Then, you will see the all-green result of regression test, - if we have no problem here. - </para> -<screen> -$ make -C contrib/sepgsql/ installcheck - : -../../src/test/regress/pg_regress --inputdir=. --psqldir=/usr/local/pgsql/bin \ - --dbname=contrib_regression --launcher ../../contrib/sepgsql/launcher \ - label dml -(using postmaster on Unix socket, default port) -============== dropping database "contrib_regression" ============== -DROP DATABASE -============== creating database "contrib_regression" ============== -CREATE DATABASE -ALTER DATABASE -============== running regression test queries ============== -test label ... ok -test dml ... ok -test misc ... ok -===================== - All 3 tests passed. -===================== -</screen> <para> - If <command>pg_regress</> failed to launch <command>psql</> command, - here is a hint to fix up the matter. - - When we try to launch <command>psql</> command with restrictive - privileges, the <command>psql</> must eb labeled as <literal>bin_t</>. - If not, try to run <command>restorecon</> to fix up security label of - the commands as expected. + See <xref linkend="sepgsql-resources"> for details on adjusting your + working domain, if necessary. </para> + + <para> + If <command>pg_regress</> fails to launch the <command>psql</> command, + you may need to ensure that the <command>psql</> command is labeled + as <literal>bin_t</>. If it is not, the <command>restorecon</> command can + often be used to fix up security labels within the + <productname>PostgreSQL</productname> installation directory. + </para> + <screen> $ restorecon -R /usr/local/pgsql/ </screen> @@ -286,28 +247,20 @@ $ restorecon -R /usr/local/pgsql/ </indexterm> <listitem> <para> - This parameter enables to perform <productname>SE-PostgreSQL</> - in permissive mode independent from the system setting. - The default is off (according to the system setting). + This parameter enables <productname>SE-PostgreSQL</> to function + in permissive mode, regardless of the system setting. + The default is off. This parameter can only be set in the <filename>postgresql.conf</> file or on the server command line. </para> + <para> - We have two performing mode except for disabled; The one is enforcing - mode that checks the security policy on references and actually prevents - violated accesses. The other is permissive mode that only checks - the security policy, but does not prevents anything except for log - generation. - This log shall be utilized for debugging of the security policy itself. - </para> - <para> - When this parameter is on, <productname>SE-PostgreSQL</> performs - in permissive mode, even if the platform system is working on enforcing - mode. - We recommend users to keep the default setting, except for the case - when we develop security policy by ourself. + When this parameter is on, <productname>SE-PostgreSQL</> functions + in permissive mode, even if the platform system is working in enforcing + mode. This parameter is primarily useful for testing purposes. </para> </listitem> + </varlistentry> <varlistentry id="guc-sepgsql-debug-audit" xreflabel="sepgsql.debug_audit"> <term><varname>sepgsql.debug_audit</> (<type>boolean</>)</> @@ -316,21 +269,21 @@ $ restorecon -R /usr/local/pgsql/ </indexterm> <listitem> <para> - This parameter enables to print audit messages independent from + This parameter enables the printing of audit messages independent from the policy setting. The default is off (according to the security policy setting). </para> + <para> The security policy of <productname>SELinux</> also has rules to - control what accesses shall be logged, or not. - In the default, any access violations are logged, but any allowed - accesses are not logged. + control whether or not particular accesses are logged. + By default, access violations are logged, but allowed + accesses are not. </para> + <para> - When this parameter is on, all the possible logs shall be printed - independently from the policy settings. - We recommend to keep the variable turned off in normal cases to - avoid noisy messages. + This parameter forces all possible logging to be turned on, regardless + of the system policy. </para> </listitem> </varlistentry> @@ -344,48 +297,35 @@ $ restorecon -R /usr/local/pgsql/ <para> The security model of <productname>SELinux</> describes all the access control rules as a relationship between a subject entity (typically, - it is a client of database) and an object entity. - And, these entities are identified by a security label. + it is a client of database) and an object entity, each of which is + identified by a security label. If access to an unlabelled object is + attempted, the object is treated as if it were assigned the label + <literal>unlabeled_t</>. </para> + <para> - We call a set of these rules as security policy. - All the access control decision shall be made according to the security - policy, when we ask SELinux whether the required action shall be allowed - or not. - Thus, we have no way to control accesses on any sort of objects without - security labels. - (<productname>SELinux</> assumes <literal>unlabeled_t</> is assigned, - if no valid security label is assigned on the target object.) + Currently, <productname>sepgsql</productname> allows security labels to be + assigned to schemas, tables, columns, sequences, views, and functions. + When <productname>sepgsql</productname> is in use, security labels are + automatically assigned to suppoted database objects at creation time. + This label is called as a default security label, being 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. </para> + <para> - This version of <productname>SE-PostgreSQL</> supports to assign - a security label on these database object classes: schema, table, column, - sequence, view and procedure. - Other database object classes are not supported to assign security label - on, right now. - </para> - <para> - A security label shall be automatically assigned to the supported - database objects on their creation time. - This label is called as a default security label; being decided according - to the security policy, or a pair of security label of the client and - upper object for more correctly. - </para> - <para> - A new database object basically inherits security label of the upper - object. A new column inherits security label of its parent table for - instance. - If and when the security policy has special rules called as - type-transition on a pair of the client and upper object, we can assign - an individual label as a default. The upper object depends on sort of - object classes as follows. + A new database object basically inherits security label of the parent + object, except when the security policy has special rules known as + type-transition rules, in which case a different label may be applied. + The meaning of the term "parent object" varies by object class, as follows. </para> + <variablelist> <varlistentry> <term>schema</term> <listitem> <para> - Its upper object is the current database. + The parent object is the current database. </para> </listitem> </varlistentry> @@ -393,7 +333,7 @@ $ restorecon -R /usr/local/pgsql/ <term>table</term> <listitem> <para> - Its upper object is the schema object which owns the new table. + The parent object is the containing schema. </para> </listitem> </varlistentry> @@ -401,7 +341,7 @@ $ restorecon -R /usr/local/pgsql/ <term>column</term> <listitem> <para> - Its upper object is the table object which owns the new column. + The parent object is the table. </para> </listitem> </varlistentry> @@ -409,7 +349,7 @@ $ restorecon -R /usr/local/pgsql/ <term>sequence</term> <listitem> <para> - Its upper object is the schema object which owns the new sequence. + The parent object is the containing schema. </para> </listitem> </varlistentry> @@ -417,15 +357,15 @@ $ restorecon -R /usr/local/pgsql/ <term>view</term> <listitem> <para> - Its upper object is the schema object which owns the new view. + The parent object is the containing schema. </para> </listitem> </varlistentry> <varlistentry> - <term>procedure</term> + <term>function</term> <listitem> <para> - Its upper object is the schema object which owns the new procedure. + Its parent object is the containing schema. </para> </listitem> </varlistentry> @@ -433,56 +373,62 @@ $ restorecon -R /usr/local/pgsql/ </sect3> <sect3> <title>DML Permissions</title> + <para> This section introduces what permissions shall be checked on DML; <literal>SELECT</>, <literal>INSERT</>, <literal>UPDATE</> and <literal>DELETE</>. </para> + <para> DML statements are used to reference or modify contents within the specified database objects; such as tables or columns. - We basically checks access rights of the client on all the appeared - objects in the given statement, and kind of privileges depend on - class of object and sort of accesses. + We basically checks access rights of the client on all the objects + mentioned in the given statement, and the kind of privileges checked + depend on the class of the object and the type of access. </para> + <para> For tables, <literal>db_table:select</>, <literal>db_table:insert</>, - <literal>db_table:update</> or <literal>db_table:delete</> shall be + <literal>db_table:update</> or <literal>db_table:delete</> is checked for all the appeared target tables depending on the sort of statement; - In addition, <literal>db_table:select</> shall be also checked for + in addition, <literal>db_table:select</> is also checked for all the tables that containin the columns to be referenced in <literal>WHERE</> or <literal>RETURNING</> clause, as a data source of <literal>UPDATE</>, and so on. </para> + <para> <synopsis> UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100; </synopsis> + In this case, we must have <literal>db_table:select</>, not only <literal>db_table:update</>, because <literal>t1.a</> is referenced - within <literal>WHERE</> clause. - Also note that column-level permission shall be checked individually. + within <literal>WHERE</> clause. Column-level permissions will be + checked as well, for each referenced column. </para> + <para> The client must be allowed to reference all the appeared tables and - columns, even if they are originated from views then expanded, unlike - the default database privileges, because we intend to apply consistent - access control rules independent from the route to reference contents - of the tables. + columns, even if they are originated from views then expanded, because we + intend to apply consistent access control rules independent from the + manner in which the table contents are referenced. </para> + <para> - For columns, <literal>db_column:select</> shall be also checked on + For columns, <literal>db_column:select</> is checked on not only the columns being read using <literal>SELECT</>, but being referenced in other DML statement. </para> + <para> Of course, it also checks <literal>db_column:update</> or <literal>db_column:insert</> on the column being modified by <literal>UPDATE</> or <literal>INSERT</>. - Note that we have no definition of column-level delete permission, - like as the default database privilege doing. </para> + <para> <synopsis> UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100; @@ -495,31 +441,35 @@ UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100; Also note that <literal>db_table:{select update}</> shall be checked in the table-level granularity. </para> + <para> For sequences, <literal>db_sequence:get_value</> when we reference - a sequence object using <literal>SELECT</>, however, note that we + a sequence object using <literal>SELECT</>; however, note that we cannot check permissions on execution of corresponding functions such as <literal>lastval()</> right now, although they performs same job, because here is no object access hook to acquire controls. </para> + <para> For views, <literal>db_view:expand</> shall be checked, then any other corresponding permissions shall be also checked on the objects being expanded from the view, individually. - Note that both of permissions have to be allowed. </para> + <para> - For procedures, <literal>db_procedure:{execute}</> is defined, but not + For functions, <literal>db_procedure:{execute}</> is defined, but not checked in this version. </para> + <para> Here is a few more corner cases. The default database privilege system allows database superusers to modify system catalogs using DML commands, and reference or modify - toast tables, however, both of the cases shall be denied when - <productname>SE-PostgreSQL</> is enabled. + toast tables. These operations are prohibited when + <productname>sepgsql</> is enabled. </para> </sect3> + <sect3> <title>DDL Permissions</title> <para> @@ -528,17 +478,15 @@ UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100; with an old security label, then <literal>relabelto</> on the supplied new security label. </para> + <para> In a case when multiple label providers are installed and user tries to set a security label, but is not managed by <productname>SELinux</>, only <literal>setattr</> should be checked here. - However, it is not unavailable because of limitation of the hook. - </para> - <para> - As we will describe in <xref linkend="sepgsql-limitations"> section, - <productname>SE-PostgreSQL</> does not control any other DDL operations. + This is currently not done due to implementation restrictions. </para> </sect3> + <sect3> <title>Trusted Procedure</title> <para> @@ -548,6 +496,7 @@ UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100; for more correctness) during execution of certain functions; being called as trusted procedures. </para> + <para> A trusted function is a function with a special security label being set up as a trusted procedure. @@ -556,6 +505,7 @@ UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100; The default security policy also provides this special security label. See the following example. </para> + <screen> postgres=# CREATE TABLE customer ( cid int primary key, @@ -575,9 +525,11 @@ postgres=# SECURITY LABEL ON FUNCTION show_credit(int) IS 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0'; SECURITY LABEL </screen> + <para> Above operations shall be done by administrative users. </para> + <screen> postgres=# SELECT * FROM customer; ERROR: SELinux: security policy violation @@ -588,71 +540,71 @@ postgres=# SELECT cid, cname, show_credit(cid) FROM customer; 2 | hanako | 5555-6666-7777-xxxx (2 rows) </screen> + <para> In this case, a regular user cannot reference <literal>customer.credit</> directly, but a trusted procedure <literal>show_credit</> enables us to print credit number of customers with a bit modification. </para> </sect3> + <sect3> <title>Miscellaneous</title> <para> In this version, we reject <xref linkend="sql-load"> command across - the board, because the binary module can override security hooks to - make access control decision. It means a risk to invalidate all the - control by security providers. + the board, because any module loaded could easily circumvent security + policy enforcement. </para> + </sect3> </sect2> <sect2 id="sepgsql-limitations"> <title>Limitations</title> - <para> - This section introduces limitations of <productname>SE-PostgreSQL</> - in this version. - </para> + <variablelist> <varlistentry> <term>Userspace access vector cache</term> <listitem> <para> - <productname>SE-PostgreSQL</> tells <productname>SELinux</> its access - control decision. It takes system call invocation being heavy, however, - we can reduce number of the invocations using caching mechanism; called - as access vector cache in <productname>SELinux</>. - Because of code size, <productname>SE-PostgreSQL</> does not support - this mechanism yet. + <productname>sepgsql</> does not yet support an access vector cache. + This would likely improve performance. </para> </listitem> </varlistentry> + <varlistentry> - <term>DDL Permissions</term> + <term>Data Definition Language (DDL) Permissions</term> <listitem> <para> - Now <productname>PostgreSQL</> does not provide a set of hooks on - the DDL routines. - It means plugin modules cannot acquire control here, - so <productname>SE-PostgreSQL</> does not check DDL Permissions - right now. + Due to implementation restrictions, DDL permissions are not checked. </para> </listitem> </varlistentry> + + <varlistentry> + <term>Data Control Language (DCL) Permissions</term> + <listitem> + <para> + Due to implementation restrictions, DCL permissions are not checked. + </para> + </listitem> + </varlistentry> + <varlistentry> <term>Row-level access control</term> <listitem> <para> - Now <productname>SE-PostgreSQL</> does not support row-level access - control, because a few needed facilities are not supported yet. - The one is security labels on users' tables. The other is behavior of - optimizer. Also see <xref linkend="rules-privileges"> for more details. - We know similar issue on VIEW. + <productname>PostgreSQL</> does not support row-level access; therefore, + <productname>sepgsql</productname> does not support it either. </para> </listitem> </varlistentry> + <varlistentry> <term>Covert channels</term> <listitem> <para> - <productname>SE-PostgreSQL</> never tries to hide existence of + <productname>sepgsql</> never tries to hide existence of a certain object, even if user is not allowed to reference. For example, we can infer an existence of invisible object using primary-key confliction, foreign-key violation, and so on, even if @@ -662,6 +614,7 @@ postgres=# SELECT cid, cname, show_credit(cid) FROM customer; </varlistentry> </variablelist> </sect2> + <sect2 id="sepgsql-resources"> <title>External Resources</title> <variablelist> @@ -669,7 +622,7 @@ postgres=# SELECT cid, cname, show_credit(cid) FROM customer; <term><ulink url="http://wiki.postgresql.org/wiki/SEPostgreSQL">SE-PostgreSQL Introduction</ulink></term> <listitem> <para> - This wikipage provides a brief-overview, security design, architecture, + This wiki page provides a brief-overview, security design, architecture, administration and upcoming feature for more details. </para> </listitem> @@ -678,9 +631,9 @@ postgres=# SELECT cid, cname, show_credit(cid) FROM customer; <term><ulink url="http://docs.fedoraproject.org/selinux-user-guide/">Fedora SELinux User Guide</ulink></term> <listitem> <para> - This document provides wide spectrum of knowledge to administrate - SELinux on your systems. - It primary focuses on Fedora, but not limited to Fedora. + This document provides wide spectrum of knowledge to administer + <productname>SELinux</> on your systems. + It primary focuses on Fedora, but is not limited to Fedora. </para> </listitem> </varlistentry> @@ -688,13 +641,15 @@ postgres=# SELECT cid, cname, show_credit(cid) FROM customer; <term><ulink url="http://docs.fedoraproject.org/selinux-faq">Fedora SELinux FAQ</ulink></term> <listitem> <para> - This document provides FAQs about SELinux. - It primary focuses on Fedora, but not limited to Fedora. + This document answers frequently asked questins about + <productname>SELinux</productname>. + It primary focuses on Fedora, but is not limited to Fedora. </para> </listitem> </varlistentry> </variablelist> </sect2> + <sect2 id="sepgsql-author"> <title>Author</title> <para>