Re: Proposal of SE-PostgreSQL patches (for CommitFest:Sep)

From: KaiGai Kohei <kaigai(at)ak(dot)jp(dot)nec(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Cc: KaiGai Kohei <kaigai(at)kaigai(dot)gr(dot)jp>, Josh Berkus <josh(at)agliodbs(dot)com>, Peter Eisentraut <peter_e(at)gmx(dot)net>, bruce(at)momjian(dot)us, ams(at)oryx(dot)com
Subject: Re: Proposal of SE-PostgreSQL patches (for CommitFest:Sep)
Date: 2008-09-12 09:26:30
Message-ID: 48CA35C6.8020307@ak.jp.nec.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello,

The latest SE-PostgreSQL patches are updated here:

[1/4] http://sepgsql.googlecode.com/files/sepostgresql-sepgsql-8.4devel-3-r1005.patch
[2/4] http://sepgsql.googlecode.com/files/sepostgresql-pg_dump-8.4devel-3-r1005.patch
[3/4] http://sepgsql.googlecode.com/files/sepostgresql-policy-8.4devel-3-r1005.patch
[4/4] http://sepgsql.googlecode.com/files/sepostgresql-docs-8.4devel-3-r1005.patch

They contains rebasing to the CVS HEAD, because we cannot apply the previous ones
correctly due to progress in the base version.
Rest of changes are here:
- A new PGACE hook: pgaceIsAllowExecutorRunHook().
It enables to control overriding ExecutorRun_hook, because several important
hooks are invoked from standard_ExecutorRun().
- T_SEvalItem related equalXXXX() functions are added to nodes/equalfuncs.c.
# I've left for implement them.
- Fix typo in src/include/security/pgace.h

BTW, I thought I have to show the overview of the patch to help reviwers.
The main patch ([1/4]) is especially big and contains new concepts.

The following explanation shows several key concept of SE-PostgreSQL.
I'm happy if it can reduce the load of reviwers.

No need to say, please feel free to ask me anything. :-)

Thanks,

Security hooks
--------------
We called it as PostgreSQL Access Control Extention (PGACE).
The "src/include/security/pgace.h" newly added declares these hooks as
inline functions. If HAVE_SELINUX is available at build time, they have
a valid implementation to invoke functions to make access control decision.
When the SE-PostgreSQL feature is disabled at build time or run time,
it does not change any existing behavior.

These hooks have a prefix of "pgace", like pgaceHeapTupleInsert().
This hook is invoked just before inserting a new tuple into a relation,
and the SE-PostgreSQL subsystem can make its decision.

Its argument provides information to make a decision. The pgaceHeapTupleInsert()
has four arguments like the target Relation object and newly inserted HeapTuple.

Specifications of each hooks are described in the "src/include/security/pgace.h".

Security attribute management
-----------------------------
We need a security attribute of tuple to use it as a basic of access control
decision. SELinux calls it as "security context", and most of security aware
operating system has similar idea called as label.
It is represented as a text format like "system_u:object_r:etc_t:s0", and has
its characteristic that many objects tend to share a single security context.

We stores text represented security attribute into "pg_security" system catalog
and put an alternate key (oid of pg_security) on each tuples, because it is
unacceptable approach to put a raw string data on individual tuples.

The alternate key is stored in the tail of HeapTupleHeader, as "oid" doing.
This field is valid when t_infomask has HEAP_HASSECURITY bit.

HeapTupleHeader
+-----------------+
| : |
+-----------------+
| t_infomask |
+-----------------+ pg_security system catalog
| t_hoff o-------+ +-------+---------------------------------------------+
+-----------------+ | | oid | seclabel |
| : | | +-------+---------------------------------------------+
| : | | | 16389 | system_u:object_r:sepgsql_table_t:s0 |
+-----------------+ | | 16401 | system_u:object_r:sepgsql_proc_t:s0 |
|*Oid security_id*|---------> | 16402 | system_u:object_r:sepgsql_secret_table_t:s0 |
+-----------------+ | | : | : |
| Oid object_id | |
+-----------------+ <--+
| Data field |
| : |

The alternate key is just a internal representation, so we have to translate
it to/from text format when communicating to in-kernel SELinux, or export/import
them.

Note that the security attribute is also assigned to tuples within system
catalogs. A security attribute of a tuple within pg_attribute means column's
security attribute, and used to column-level access controls, for example.

The src/backend/security/pgaceCommon.c have functions to traslate them:

char *pgaceLookupSecurityLabel(Oid security_id);
Oid pgaceLookupSecurityId(char *security_label);

When a new security_label is given and not found on pg_security,
pgaceLookupSecurityId() tries to insert a new tuple into pg_security and
returns its object id as an alternate key.

Two more similar functions are also declared:
char *pgaceSidToSecurityLabel(Oid security_id)
Oid pgaceSecurityLabelToSid(char *security_label)
It also enables to translate between a cosmetic text format and an internal
security identifier.
An example of cosmetic format is:
unconfined_u:unconfined_r:unconfined_t:SystemLow-SystemHigh
^^^^^^^^^^^^^^^^^^^^
We have a case when `pg_security` system catalog is not available because
initdb does not complete to initialize system catalogs yet. In early phase,
this facility caches the pairs of identifier and text representations, then
it writes out to `pg_security` after initial set up completed.
earlySecurityLabelToSid() and earlySidToSecurityLabel() are used while we
are in bootstraping mode, and pgacePostBootstrapingMode() write out them.

Making access control decision
------------------------------
SE-PostgreSQL makes its decision with three steps in major path.

The first step picks up any database objects accessed with the given queries.
For example, the following UPDATE statement contains accesses to 6 objects.

UPDATE t SET a = 5, b = b * 2 WHERE c > 10;
- table t is updated and refered.
- column a is updated.
- column b is updated and refered.
- column c is refered without leaking its contents.
- function int4mul and int4gt are executed.

The sepgsqlProxyQuery() defined at "src/backend/security/sepgsql/proxy.c"
walks on the given Query trees to pick up database objects accessed, and
makes a list of them. This list is chained to Query->pgaceItem which is
a private field of security subsystem, and delivered to private member
of PlannedStmt structure.
In same time, it marks a kind of accesses on RangeTblEntry->pgaceTuplePerms.
This value is copied to Scan->pgaceTuplePerms, and sepgsqlExecScan() hook
refers to identify what is the purpose of this scan.

The second step is evaluations of permission for picked up database objects.
The sepgsqlVerifyQuery() is invoked at the head of ExecutorStart(), to check
whether the client has enough permission
It walk on the list chained to PlannedStmt->pgaceItem which is created at
the first step, and checks whether the client has enough permissions, or not.
If the security policy does not allow the required accesses, SE-PostgreSQL
makes an error to abort query execution.
Tuple-level access controls are not done in this step.

The last step is evaluations of permission for scanned tuples.
The sepgsqlExecScan() defined at "src/baskend/security/sepgsql/hooks.c" is
invoked from ExecScan(). This hook can return bool value, and modified
logic skips a tuple scanned if it returns 'false'.

Other topics
------------

* Default security context

The security policy also contains rules to decide a security context of
newly inserted tuples. If client does not specify any explicit one, the
default one is applied.
We can specify explicit security context with the following Enhanced SQL
statement or writable system column.

* Enhanced SQL statement

It helps to define a new table, column, function and database with specific
security context. We can use the facility as follows:

CREATE TABLE t (
a integer primary key,
b text,
) SECURITY_CONTEXT = 'system_u:object_r:sepgsql_ro_t:s0';
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The above token is represented as DefElem objects in gram.y, and saved on
private member of CreateStmt structure. Then, these are translated to List
of DefElem and delivered to heap_create_with_catalog() with its fifteenth
argument.
pgaceCreateRelationCommon() and pgaceCreateAttributeCommon() are invoked
just before inserting a new tuple into pg_class/pg_attribute. These are
defined at "src/backend/security/pgaceCommon.c", and they invokes PGACE
hooks if the security context of new objects are explicitly specified.

At the next, sepgsqlHeapTupleInsert() is invoked for the new tuple.
It skips to assign default security context, because explicit security
context is already set. Permissions to create table/column is evaluated
for explicitly specified one.

* Writable system column

Security contexts can be exported via "security_context" system column.
In the previous version, system column is read only, so we cannot specify
in an element of INSERT or UPDATE.
SE-PostgreSQL allows to set an explicit value to "security_context" system
column to utilize it as an interface to change security context of tuples.

An example)
UPDATE t SET security_context = security_context || ':c0' WHERE a = 10;

The TargetEntry->resjunk for "security_context" is always turned on for
INSERT, UPDATE and SELECT INTO statement. In the result, its new value
is computed but removed at ExecFilterJunk().
The patched ExecutePlan() fetches the value and stores it on the tail of
HeapTupleHeader with HeapTupleSetSecurity() macro.

This patch changes transformInsertStmt() and updateTargetListEntry()
to turn on TargetEntry->resjunk when attribute number is negative.
Its purpose is to enable writable system column.

Same logic can be applied to writable "oid" system column as a possibility.

* userspace Access vector cache

The "src/backend/security/sepgsql/avc.c" is an implementation of userspace
access vector cache. SE-PostgreSQL ask in-kernel SELinux to check whether
the given access should be allowed, or not.
However, it requires system call invocation which is a bit heavy step.
The userspace AVC caches recently asked access patterns, and enables to
reduce the number of system call invocation.

--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai(at)ak(dot)jp(dot)nec(dot)com>

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Magnus Hagander 2008-09-12 09:29:38 Re: Parsing of pg_hba.conf and authentication inconsistencies
Previous Message Csaba Nagy 2008-09-12 09:21:06 Re: Transaction Snapshots and Hot Standby