Updates of SE-PostgreSQL 8.4devel patches (r1197)
I updated the patch set of SE-PostgreSQL (revision 1197).
[1/6] http://sepgsql.googlecode.com/files/sepostgresql-sepgsql-8.4devel-3-r1197.patch
[2/6] http://sepgsql.googlecode.com/files/sepostgresql-pg_dump-8.4devel-3-r1197.patch
[3/6] http://sepgsql.googlecode.com/files/sepostgresql-policy-8.4devel-3-r1197.patch
[4/6] http://sepgsql.googlecode.com/files/sepostgresql-docs-8.4devel-3-r1197.patch
[5/6] http://sepgsql.googlecode.com/files/sepostgresql-tests-8.4devel-3-r1197.patch
[6/6] http://sepgsql.googlecode.com/files/sepostgresql-row_acl-8.4devel-3-r1197.patch
List of updates:
- Patches are rebased to the latest CVS HEAD.
- The "NSA SELinux" comments are replaced by the simple "SELinux".
- bugfix: system attributes are preserved prior to invocation of
before-row-update-triggers.
- Add a documentation of row-level database acl, within 6th patch.
Most of patch size increments come from the new documentation.
Draft of the SE-PostgreSQL documentation is here:
http://wiki.postgresql.org/wiki/SEPostgreSQL
By the way, now a week has gone since beginning of the final CommitFest,
however, the reviewers field on the wiki is empty.
Is there anyone who can help to review the patches?
Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>
On Fri, 2008-11-07 at 18:20 +0900, KaiGai Kohei wrote:
I updated the patch set of SE-PostgreSQL (revision 1197).
[1/6] http://sepgsql.googlecode.com/files/sepostgresql-sepgsql-8.4devel-3-r1197.patch
[2/6] http://sepgsql.googlecode.com/files/sepostgresql-pg_dump-8.4devel-3-r1197.patch
[3/6] http://sepgsql.googlecode.com/files/sepostgresql-policy-8.4devel-3-r1197.patch
[4/6] http://sepgsql.googlecode.com/files/sepostgresql-docs-8.4devel-3-r1197.patch
[5/6] http://sepgsql.googlecode.com/files/sepostgresql-tests-8.4devel-3-r1197.patch
[6/6] http://sepgsql.googlecode.com/files/sepostgresql-row_acl-8.4devel-3-r1197.patchList of updates:
- Patches are rebased to the latest CVS HEAD.
- The "NSA SELinux" comments are replaced by the simple "SELinux".
- bugfix: system attributes are preserved prior to invocation of
before-row-update-triggers.
- Add a documentation of row-level database acl, within 6th patch.
Most of patch size increments come from the new documentation.Draft of the SE-PostgreSQL documentation is here:
http://wiki.postgresql.org/wiki/SEPostgreSQLBy the way, now a week has gone since beginning of the final CommitFest,
however, the reviewers field on the wiki is empty.
Is there anyone who can help to review the patches?
Some initial thoughts based upon reading the Wiki. I've not been
involved in things up to now, so if this dredges up old discussions,
well, these are my thoughts.
I want SEPostgreSQL, but I'd like it to work without needing to be a
compile time option so people can just use it as/when needed. Plus we
don't want to support what would be/is essentially a fork of Postgres.
Most CPUs will optimise away a simple if-test in various places.
Some users will be able to take advantage of the facilities without
implementing full MLS. Yet we want the full facilities for Government.
Many people currently run multiple customers in different schemas,
though this would let them just run a single set of tables so is much
better for running many small customers.
I'm very unhappy about putting a nonoptional value on tuple headers,
especially because it is updatable. Do we expect MVCC will work with
updatable security contexts? i.e. when you update the security context
of a tuple that won't effect its visibility to existing system users. I
can't imagine you'd want that would you? It's kind of difficult to *not*
get it though.
Looks to me that this feature is useless without things working at row
level. So we can't leave that part out.
The security context on each row could be an optional column present
only if HEAP_HASSECURITYCONTEXT is set (0x0010 see htup.h), just like
OIDs. Use a specific datatype rather than TEXT. That datatype could be
an identifier to pg_security. Security people have big databases too, so
we need to compress the security context more and take out parse time of
string handling. Don't think we should use Oids, they're too big. Might
be easier to use a 2byte field and restrict access to 32,000 contexts,
which is easily enough. TEXT also makes me nervous, just in case there
is some collation/encoding weirdness that allows contexts to be
subverted. Fixed integers are hard to compromise in that respect.
How will unique indexes work? Do you implicitly add security context as
last column on every unique index, or does the uniqueness violation only
occurs within security contexts, or does the uniqueness violation tested
against all contextx that the inserter can currently see? Is there a
change to system catalogs?
Foreign Key deletions could be handled correctly if you treat them as
updates. If we have the following example
TableA
security_context=y value=2 fk=1
TableB
security_context=x value=1
TableA refers to TableB. Context x cannot see context y.
So if somebody with context x tries to delete value1 from TableB, they
will be refused because of a row they cannot see. In this case the
correct action is to update the tuple in TableB so it now has a
security_context = y. The user with x cannot see it and can be persuaded
he deleted it, while the user with y can still see it.
The section on LOAD doesn't sound very convincing. Loading a module
could immediately subvert security. We could probably tighten up on that
for general use as well. ISTM we need something like a new catalog table
for loadable modules, so we can give them specific security contexts and
potentially store some kind of verification information about them.
Having a single "can load modules" isn't enough with Postgres, since it
would effectively prevent us from loading *any* modules in a secure
database. Which kinda removes much of the benefit of using Postgres.
Is there an issue with relation cache and catalog caches? ISTM that you
should put a security context onto each shared invalidation message, so
that backends know not to maintain caches for data they aren't allowed
to see. Probably overkill, just thinking.
The interaction with SELinux should not be hardcoded. I think we need
some form of plugin/wrapper to allow other systems to work. Not sure
what those are, but this isn't a Linux only project. We want to give
everybody the ability to work with PostgreSQL.
How does Discretionary Access control work with regard to server logs?
You said there was no superuser access, but I don't see any controls for
the logs. Do we need log_max_security_context?
Trusted procedures seem very similar to SECURITY DEFINER functions. Can
you explain what the differences are? I'm sure we don't want to similar
features.
I don't see any reason for the "=" in most of the new DDL syntax. Just
seems superfluous and out of character with normal SQL DDL.
With DDL we already have table options, so why not include
security_context as an option? If we are adding this to databases as
well, it seems a good time to include a generic database-level options
facility and make "security_context" the first option.
The parameter to enable this facility should be something like
enhanced_security = on
My feeling is that if you want to include these features in core
PostgreSQL you won't be able to maintain the "separate branding" of
SEPostgreSQL, logo etc.. Maybe I'll get used to it. But if we are going
to use it, we should say SEPostgresSQL, not SE-PostgreSQL if we are
saying SELinux.
It would make sense for you to look at the work on replication also. Not
much use having SEPostgreSQL if we can't replicate it securely. And
possibly in-place update so that respects label security.
I've not looked at the code and probably won't have time to do that. But
if I did, I'd say "diff -c".
Good, thorough work.
--
Simon Riggs www.2ndQuadrant.com
PostgreSQL Training, Services and Support
Simon Riggs wrote:
Some initial thoughts based upon reading the Wiki. I've not been
involved in things up to now, so if this dredges up old discussions,
well, these are my thoughts.I want SEPostgreSQL, but I'd like it to work without needing to be a
compile time option so people can just use it as/when needed. Plus we
don't want to support what would be/is essentially a fork of Postgres.
Most CPUs will optimise away a simple if-test in various places.
Well, I assume SEPostgreSQL will rely on libraries that only exist on
SELinux, so I am afraid there will have to be some type of compile-time
flag, though the goal is to have as much of it enabled as possible at
the SQL level, as we have discussed and the patch reflects.
Some users will be able to take advantage of the facilities without
implementing full MLS. Yet we want the full facilities for Government.
Many people currently run multiple customers in different schemas,
though this would let them just run a single set of tables so is much
better for running many small customers.I'm very unhappy about putting a nonoptional value on tuple headers,
especially because it is updatable. Do we expect MVCC will work with
updatable security contexts? i.e. when you update the security context
of a tuple that won't effect its visibility to existing system users. I
can't imagine you'd want that would you? It's kind of difficult to *not*
get it though.Looks to me that this feature is useless without things working at row
level. So we can't leave that part out.
Having the security column be optional is an interesting idea, perhaps
like we do with oids and with a GUC variable controlling the default.
I think the patch itself is going to go through many adjustments before
application, I bet.
The security context on each row could be an optional column present
only if HEAP_HASSECURITYCONTEXT is set (0x0010 see htup.h), just like
OIDs. Use a specific datatype rather than TEXT. That datatype could be
an identifier to pg_security. Security people have big databases too, so
we need to compress the security context more and take out parse time of
string handling. Don't think we should use Oids, they're too big. Might
be easier to use a 2byte field and restrict access to 32,000 contexts,
which is easily enough. TEXT also makes me nervous, just in case there
is some collation/encoding weirdness that allows contexts to be
subverted. Fixed integers are hard to compromise in that respect.
I think the security mechanism is more complex than just assigning a
single security identifier, but perhaps not; I am unsure.
How will unique indexes work? Do you implicitly add security context as
last column on every unique index, or does the uniqueness violation only
occurs within security contexts, or does the uniqueness violation tested
against all contextx that the inserter can currently see? Is there a
change to system catalogs?Foreign Key deletions could be handled correctly if you treat them as
updates. If we have the following exampleTableA
security_context=y value=2 fk=1TableB
security_context=x value=1TableA refers to TableB. Context x cannot see context y.
I think this is the "covert channel" we have been discussing.
The interaction with SELinux should not be hardcoded. I think we need
some form of plugin/wrapper to allow other systems to work. Not sure
what those are, but this isn't a Linux only project. We want to give
everybody the ability to work with PostgreSQL.
I think that is why the text security column was used, so other systems
could put their own security text in there.
--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ If your life is a hard drive, Christ can be your backup. +
Foreign Key deletions could be handled correctly if you treat them as
updates. If we have the following exampleTableA
security_context=y value=2 fk=1TableB
security_context=x value=1TableA refers to TableB. Context x cannot see context y.
So if somebody with context x tries to delete value1 from TableB, they
will be refused because of a row they cannot see. In this case the
correct action is to update the tuple in TableB so it now has a
security_context = y. The user with x cannot see it and can be persuaded
he deleted it, while the user with y can still see it.
It seems odd for a low-privilege user to be able to elevate the
privilege of a tuple above their own privilege level. I also don't
believe that the privilege level is a total order, which might make
this something of a sticky wicket. But those are just my thoughts as
a non-guru.
...Robert
On Fri, 2008-11-07 at 13:19 -0500, Bruce Momjian wrote:
The security context on each row could be an optional column present
only if HEAP_HASSECURITYCONTEXT is set (0x0010 see htup.h), just
like
OIDs. Use a specific datatype rather than TEXT. That datatype could
be
an identifier to pg_security. Security people have big databases
too, so
we need to compress the security context more and take out parse
time of
string handling. Don't think we should use Oids, they're too big.
Might
be easier to use a 2byte field and restrict access to 32,000
contexts,
which is easily enough. TEXT also makes me nervous, just in case
there
is some collation/encoding weirdness that allows contexts to be
subverted. Fixed integers are hard to compromise in that respect.I think the security mechanism is more complex than just assigning a
single security identifier, but perhaps not; I am unsure.
Maybe. We already handle such complexity for comboids and multixacts, so
I suggest we do the same thing here.
Any system with more than 32,000 security contexts is going to be
unmanageable and probably therefore insecure...
--
Simon Riggs www.2ndQuadrant.com
PostgreSQL Training, Services and Support
On Fri, 2008-11-07 at 15:12 -0500, Robert Haas wrote:
Foreign Key deletions could be handled correctly if you treat them as
updates. If we have the following exampleTableA
security_context=y value=2 fk=1TableB
security_context=x value=1TableA refers to TableB. Context x cannot see context y.
So if somebody with context x tries to delete value1 from TableB, they
will be refused because of a row they cannot see. In this case the
correct action is to update the tuple in TableB so it now has a
security_context = y. The user with x cannot see it and can be persuaded
he deleted it, while the user with y can still see it.It seems odd for a low-privilege user to be able to elevate the
privilege of a tuple above their own privilege level. I also don't
believe that the privilege level is a total order, which might make
this something of a sticky wicket. But those are just my thoughts as
a non-guru.
The low-privilege user isn't elevating the label. If the tuple was
visible by multiple labels it was already elevated. All I am suggesting
is the system remove the one it can see, leaving the other ones intact.
This makes the row appear to be deleted by the lower privileged user,
whereas in fact it was merely updated. There need not be any ordering to
the labels for this scheme to work.
--
Simon Riggs www.2ndQuadrant.com
PostgreSQL Training, Services and Support
The low-privilege user isn't elevating the label. If the tuple was
visible by multiple labels it was already elevated. All I am suggesting
is the system remove the one it can see, leaving the other ones intact.
This makes the row appear to be deleted by the lower privileged user,
whereas in fact it was merely updated. There need not be any ordering to
the labels for this scheme to work.
I see. That seems like it makes sense, but what about the update case?
...Robert
On Fri, Nov 07, 2008 at 01:50:18PM +0000, Simon Riggs wrote:
How will unique indexes work? Do you implicitly add security context as
last column on every unique index, or does the uniqueness violation only
occurs within security contexts, or does the uniqueness violation tested
against all contextx that the inserter can currently see? Is there a
change to system catalogs?
The wiki clearly states that the unique test is prior to any filtering.
Anything else seems crazy to me.
http://wiki.postgresql.org/wiki/SEPostgreSQL#Unique_constraint
Foreign Key deletions could be handled correctly if you treat them as
updates. If we have the following example
Why? If a client does a delete and the database says OK, the tuple
should be gone, *for everyone*.
http://wiki.postgresql.org/wiki/SEPostgreSQL#Foreign_Key_constraint
It is the responsibility of the DB administrator to worry about covert
channels.
Have a nice day,
--
Martijn van Oosterhout <kleptog@svana.org> http://svana.org/kleptog/
Show quoted text
Please line up in a tree and maintain the heap invariant while
boarding. Thank you for flying nlogn airlines.
Simon Riggs <simon@2ndQuadrant.com> writes:
Any system with more than 32,000 security contexts is going to be
unmanageable and probably therefore insecure...
Perhaps, but it's doubtful that such a restriction will actually save
any space after you consider the alignment behavior. I'd go with an
Oid.
regards, tom lane
Simon Riggs wrote:
So if somebody with context x tries to delete value1 from TableB, they
will be refused because of a row they cannot see. In this case the
correct action is to update the tuple in TableB so it now has a
security_context = y. The user with x cannot see it and can be persuaded
he deleted it, while the user with y can still see it.It seems odd for a low-privilege user to be able to elevate the
privilege of a tuple above their own privilege level. I also don't
believe that the privilege level is a total order, which might make
this something of a sticky wicket. But those are just my thoughts as
a non-guru.The low-privilege user isn't elevating the label. If the tuple was
visible by multiple labels it was already elevated. All I am suggesting
is the system remove the one it can see, leaving the other ones intact.
This makes the row appear to be deleted by the lower privileged user,
whereas in fact it was merely updated. There need not be any ordering to
the labels for this scheme to work.
Simon, would you read the chapter on "covert channels"? You might
understand it better than I do and it might give you some ideas:
http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.33.5950
--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com
+ If your life is a hard drive, Christ can be your backup. +
Simon, Thanks for your comments.
Some initial thoughts based upon reading the Wiki. I've not been
involved in things up to now, so if this dredges up old discussions,
well, these are my thoughts.I want SEPostgreSQL, but I'd like it to work without needing to be a
compile time option so people can just use it as/when needed. Plus we
don't want to support what would be/is essentially a fork of Postgres.
Most CPUs will optimise away a simple if-test in various places.
As Bruce also mentioned, it has to be linked with libselinux to communicate
in-kernel SELinux, but it is not onw of the universal libraries, so, it
has to be enabled/disabled on build-time option.
In addition, we can also disable the feature by the following configuration.
sepostgresql = disabled (at $PGDATA/postgresql.conf )
TODO: add a description about the guc variable. It can have four state:
"default", "enforcing", "permissive" and "disabled".
Some users will be able to take advantage of the facilities without
implementing full MLS. Yet we want the full facilities for Government.
Many people currently run multiple customers in different schemas,
though this would let them just run a single set of tables so is much
better for running many small customers.
SELinux community also provides a MLS enabled policy, but it is not
a default one now. SE-PostgreSQL has all the its access controls
decision externally, so it is out of our coltrols.
I'm very unhappy about putting a nonoptional value on tuple headers,
especially because it is updatable. Do we expect MVCC will work with
updatable security contexts? i.e. when you update the security context
of a tuple that won't effect its visibility to existing system users. I
can't imagine you'd want that would you? It's kind of difficult to *not*
get it though.
When a user updates the security context of some tuples, it is invisible
for other clients until its commit, like as other normal data.
Sorry, it is unclear for me what is the concern you mention.
Looks to me that this feature is useless without things working at row
level. So we can't leave that part out.
I guess you are saying the core PostgreSQL also has table and column
level granularities, but its criteria to make a decision is different.
SE-PostgreSQL makes its decision based on the privileges of peer process,
not a database role.
The security context on each row could be an optional column present
only if HEAP_HASSECURITYCONTEXT is set (0x0010 see htup.h), just like
OIDs. Use a specific datatype rather than TEXT. That datatype could be
an identifier to pg_security. Security people have big databases too, so
we need to compress the security context more and take out parse time of
string handling. Don't think we should use Oids, they're too big. Might
be easier to use a 2byte field and restrict access to 32,000 contexts,
which is easily enough. TEXT also makes me nervous, just in case there
is some collation/encoding weirdness that allows contexts to be
subverted. Fixed integers are hard to compromise in that respect.
An issue is who can decide the existance or needs of security system
attribute. If the table owner can disable it, we cannot say it as
a mandatory access control feature, so the security attribute has to
be always appeared when the security feature is enabled.
Here is an answer for the expected question.
When we refer the "security_context" system column of tuples without
HEAP_HAS_SECURITY, it returns an alternative label called as "unlabeled_t",
because it has no labels.
The reason why we adopt TEXT type is SELinux requires userspace
object manager makes queries via text represented security context,
and it also can be used for other security feature to show client
its security attribute in human readable format.
For your information, in-kernel SELinux can handle 2^32 - 1 of security
context internally in theoretical maximum, so using Oid as a security
identifier is a fair decision to avoid an implementation to handle overflow
cases.
How will unique indexes work? Do you implicitly add security context as
last column on every unique index, or does the uniqueness violation only
occurs within security contexts, or does the uniqueness violation tested
against all contextx that the inserter can currently see? Is there a
change to system catalogs?
The unique/primary key constraint works at the lowest level.
So, it has a possibility that invisible tuple prevent to insert a tuple.
Foreign Key deletions could be handled correctly if you treat them as
updates. If we have the following exampleTableA
security_context=y value=2 fk=1TableB
security_context=x value=1TableA refers to TableB. Context x cannot see context y.
So if somebody with context x tries to delete value1 from TableB, they
will be refused because of a row they cannot see. In this case the
correct action is to update the tuple in TableB so it now has a
security_context = y. The user with x cannot see it and can be persuaded
he deleted it, while the user with y can still see it.
It is also discussed before.
In this case, SE-PostgreSQL prevent to delete a tuple on the TableB
to keep referential integrity. So, it enables unprivileged users to
infer the existance of refering tuples, but it is a limitation called
as "covert channel".
Your example is the simplest case, so it seems to work well, but
most of cases are not obvious. If the TE policy prevent accesses
on tuples with security_context=x, we have no obvious way to decide
what is a proper security context to be updated.
The section on LOAD doesn't sound very convincing. Loading a module
could immediately subvert security. We could probably tighten up on that
for general use as well. ISTM we need something like a new catalog table
for loadable modules, so we can give them specific security contexts and
potentially store some kind of verification information about them.
Having a single "can load modules" isn't enough with Postgres, since it
would effectively prevent us from loading *any* modules in a secure
database. Which kinda removes much of the benefit of using Postgres.
SE-PostgreSQL applies access controls for individual loadable modules.
When a function implemented within an external modules tries to be loaded,
it checks security context between the database and the file of loadable
modules. (No need to say, in-kernel SELinux assigns its security context
for files in common format, so we can compare them each other.)
Perhaps, the description I wrote can easily make misunderstanding.
If you can read it says widespread load modules permission, I'll revise
its representation.
http://wiki.postgresql.org/wiki/SEPostgreSQL#Loading_shared_library_module
Is there an issue with relation cache and catalog caches? ISTM that you
should put a security context onto each shared invalidation message, so
that backends know not to maintain caches for data they aren't allowed
to see. Probably overkill, just thinking.
Sorry, I cannot understand what you concerned.
The pg_security system catalog is only modified when a newly appeared
text representation of security attribute is given. So, it is read only
for most of cases.
The interaction with SELinux should not be hardcoded. I think we need
some form of plugin/wrapper to allow other systems to work. Not sure
what those are, but this isn't a Linux only project. We want to give
everybody the ability to work with PostgreSQL.
The PGACE security framework already enables what you want.
The "rowacl" module is a proof of concept, and we can add a new mechanism
on the framework, if necessary.
Do you know the LSM (Linux Security Module) system?
How does Discretionary Access control work with regard to server logs?
You said there was no superuser access, but I don't see any controls for
the logs. Do we need log_max_security_context?
It writes out server logs to filesystem, so its access controls should
be applied in-kernel SELinux. SE-PostgreSQL does not care system call
invocation, because it should be a task in kernel features.
It works as a reference monitor for SQL queries.
Trusted procedures seem very similar to SECURITY DEFINER functions. Can
you explain what the differences are? I'm sure we don't want to similar
features.
It does not change the working security context of the client.
Please consider whether a set-uid program on operating system makes
unnecessary domain transition of SELinux, or not. They have individual
purposes and roles, so we need both of them.
I don't see any reason for the "=" in most of the new DDL syntax. Just
seems superfluous and out of character with normal SQL DDL.
Because I thought the syntax is most friendliness for end-users
two years ago. It looks obvious the option specifies the security
context of resources.
Sorry, it is not a clear reason, but it easily makes us to understand
the option.
With DDL we already have table options, so why not include
security_context as an option? If we are adding this to databases as
well, it seems a good time to include a generic database-level options
facility and make "security_context" the first option.
How do we implement the "security_context" option for columns?
When we want to define a table with explicitly labeled column,
I don't think the table option is a user friendly interface.
The parameter to enable this facility should be something like
enhanced_security = on
As I noted above, it already provides:
sepostgresql = [ default | enforcing | permissive | disabled ]
My feeling is that if you want to include these features in core
PostgreSQL you won't be able to maintain the "separate branding" of
SEPostgreSQL, logo etc.. Maybe I'll get used to it. But if we are going
to use it, we should say SEPostgresSQL, not SE-PostgreSQL if we are
saying SELinux.
Please fee free to call it as SE-PostgreSQL, SEPostgreSQL, sepgsql
and others. I don't think it is a significant matter.
However, in my hope, I don't want to discard the mascot and logo,
because it was a present from my friend who works as an illustrator.
In Japan, a turtle is used as a mascot of PostgreSQL. :-)
http://www.postgresql.jp/npo/logo/
It would make sense for you to look at the work on replication also. Not
much use having SEPostgreSQL if we can't replicate it securely. And
possibly in-place update so that respects label security.
The log-shipping replication mechanism will works correctly,
but I have not evaluated it yet. In this case, the master
and slaves should have same security policy for databases.
I've not looked at the code and probably won't have time to do that. But
if I did, I'd say "diff -c".
OK, I'll fix the scripts to generate patch set.
The next series will provided with "diff -c" style.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
Simon Riggs wrote:
On Fri, 2008-11-07 at 15:12 -0500, Robert Haas wrote:
Foreign Key deletions could be handled correctly if you treat them as
updates. If we have the following exampleTableA
security_context=y value=2 fk=1TableB
security_context=x value=1TableA refers to TableB. Context x cannot see context y.
So if somebody with context x tries to delete value1 from TableB, they
will be refused because of a row they cannot see. In this case the
correct action is to update the tuple in TableB so it now has a
security_context = y. The user with x cannot see it and can be persuaded
he deleted it, while the user with y can still see it.It seems odd for a low-privilege user to be able to elevate the
privilege of a tuple above their own privilege level. I also don't
believe that the privilege level is a total order, which might make
this something of a sticky wicket. But those are just my thoughts as
a non-guru.The low-privilege user isn't elevating the label. If the tuple was
visible by multiple labels it was already elevated. All I am suggesting
is the system remove the one it can see, leaving the other ones intact.
This makes the row appear to be deleted by the lower privileged user,
whereas in fact it was merely updated. There need not be any ordering to
the labels for this scheme to work.
SELinux does not allow a object has two or more labels.
You implicitly assume the security mechanism allows users to access
when one of the labels allows it, but there is no consensus.
At the past, an idea of multiple labels is discussed in SELinux community,
but it was finally dropped because we cannot define the behavior when the
security policy makes different decision for two different labels.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
On Fri, 2008-11-07 at 16:52 -0500, Bruce Momjian wrote:
Simon Riggs wrote:
So if somebody with context x tries to delete value1 from TableB, they
will be refused because of a row they cannot see. In this case the
correct action is to update the tuple in TableB so it now has a
security_context = y. The user with x cannot see it and can be persuaded
he deleted it, while the user with y can still see it.It seems odd for a low-privilege user to be able to elevate the
privilege of a tuple above their own privilege level. I also don't
believe that the privilege level is a total order, which might make
this something of a sticky wicket. But those are just my thoughts as
a non-guru.The low-privilege user isn't elevating the label. If the tuple was
visible by multiple labels it was already elevated. All I am suggesting
is the system remove the one it can see, leaving the other ones intact.
This makes the row appear to be deleted by the lower privileged user,
whereas in fact it was merely updated. There need not be any ordering to
the labels for this scheme to work.Simon, would you read the chapter on "covert channels"? You might
understand it better than I do and it might give you some ideas:http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.33.5950
It's probably easier just to say "here is the specification we;re
working to implement".
--
Simon Riggs www.2ndQuadrant.com
PostgreSQL Training, Services and Support
On Sat, 2008-11-08 at 14:21 +0900, KaiGai Kohei wrote:
Some users will be able to take advantage of the facilities without
implementing full MLS. Yet we want the full facilities for Government.
Many people currently run multiple customers in different schemas,
though this would let them just run a single set of tables so is much
better for running many small customers.SELinux community also provides a MLS enabled policy, but it is not
a default one now. SE-PostgreSQL has all the its access controls
decision externally, so it is out of our coltrols.
I have a couple of concerns:
1. if we make a direct link with SELinux then the code will be *much*
less used and tested. It will be a constant battle to maintain
SEPostgres in a bug-free state. I want to decouple the link so this code
goes into normal Postgres. Other comments below are made with that
thought in mind.
2. I see another use case here. For example, a customer runs a
Software-as-a-service company where the same service is offered to 500
customers. The same database schema is there for each customer, yet they
must never see each other's data. Today, that is implemented as 500
schemas, plus 1 schema with common data in it. ISTM we would be able to
implement this better using SEPostgreSQL, with/without using SELinux.
The need for common data is why in some cases we would want access
controls placed only on certain tables.
Fulfilling use case (2) will also meet my concerns in (1).
So I would prefer it if the solution was designed closely with SELinux,
but usable and useful in other cases also. The link to SELinux could be
done via a contrib plugin. A plugin is then optional. But the main
plugin we provide can be built directly with SELinux.
The security context on each row could be an optional column present
only if HEAP_HASSECURITYCONTEXT is set (0x0010 see htup.h), just like
OIDs. Use a specific datatype rather than TEXT. That datatype could be
an identifier to pg_security. Security people have big databases too, so
we need to compress the security context more and take out parse time of
string handling. Don't think we should use Oids, they're too big. Might
be easier to use a 2byte field and restrict access to 32,000 contexts,
which is easily enough. TEXT also makes me nervous, just in case there
is some collation/encoding weirdness that allows contexts to be
subverted. Fixed integers are hard to compromise in that respect.An issue is who can decide the existance or needs of security system
attribute. If the table owner can disable it, we cannot say it as
a mandatory access control feature, so the security attribute has to
be always appeared when the security feature is enabled.Here is an answer for the expected question.
When we refer the "security_context" system column of tuples without
HEAP_HAS_SECURITY, it returns an alternative label called as "unlabeled_t",
because it has no labels.
Not really an issue. Just use a parameter. security_controls = mandatory
or change the meaning of the existing one. Similar to default_with_oids,
just that we have a setting where it isn't optional.
The reason why we adopt TEXT type is SELinux requires userspace
object manager makes queries via text represented security context,
and it also can be used for other security feature to show client
its security attribute in human readable format.
AFAICS, neither of those things means the datatype has to be TEXT.
For your information, in-kernel SELinux can handle 2^32 - 1 of security
context internally in theoretical maximum, so using Oid as a security
identifier is a fair decision to avoid an implementation to handle overflow
cases.
OK, so we need 4 bytes. I can live with that - at least its not ~10
bytes/row. Does it need to be an Oid, or just the size of an Oid?
The section on LOAD doesn't sound very convincing. Loading a module
could immediately subvert security. We could probably tighten up on that
for general use as well. ISTM we need something like a new catalog table
for loadable modules, so we can give them specific security contexts and
potentially store some kind of verification information about them.
Having a single "can load modules" isn't enough with Postgres, since it
would effectively prevent us from loading *any* modules in a secure
database. Which kinda removes much of the benefit of using Postgres.SE-PostgreSQL applies access controls for individual loadable modules.
When a function implemented within an external modules tries to be loaded,
it checks security context between the database and the file of loadable
modules. (No need to say, in-kernel SELinux assigns its security context
for files in common format, so we can compare them each other.)Perhaps, the description I wrote can easily make misunderstanding.
If you can read it says widespread load modules permission, I'll revise
its representation.http://wiki.postgresql.org/wiki/SEPostgreSQL#Loading_shared_library_module
How does Discretionary Access control work with regard to server logs?
You said there was no superuser access, but I don't see any controls for
the logs. Do we need log_max_security_context?It writes out server logs to filesystem, so its access controls should
be applied in-kernel SELinux. SE-PostgreSQL does not care system call
invocation, because it should be a task in kernel features.
It works as a reference monitor for SQL queries.
Yes, the file will be protected. My thought was that we might wish to
control the levels of message placed in the file. Otherwise you would
require top level access to view the log. It doesn't seem likely that
they would want to give Top Secret level access to DBAs. Nor should any
level of DBAs be able to inspect who is running which SQL by simple
manipulation of parameters such as log_min_duration_statement.
--
Simon Riggs www.2ndQuadrant.com
PostgreSQL Training, Services and Support
Simon Riggs wrote:
On Fri, 2008-11-07 at 16:52 -0500, Bruce Momjian wrote:
Simon Riggs wrote:
So if somebody with context x tries to delete value1 from TableB, they
will be refused because of a row they cannot see. In this case the
correct action is to update the tuple in TableB so it now has a
security_context = y. The user with x cannot see it and can be persuaded
he deleted it, while the user with y can still see it.It seems odd for a low-privilege user to be able to elevate the
privilege of a tuple above their own privilege level. I also don't
believe that the privilege level is a total order, which might make
this something of a sticky wicket. But those are just my thoughts as
a non-guru.The low-privilege user isn't elevating the label. If the tuple was
visible by multiple labels it was already elevated. All I am suggesting
is the system remove the one it can see, leaving the other ones intact.
This makes the row appear to be deleted by the lower privileged user,
whereas in fact it was merely updated. There need not be any ordering to
the labels for this scheme to work.Simon, would you read the chapter on "covert channels"? You might
understand it better than I do and it might give you some ideas:http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.33.5950
It's probably easier just to say "here is the specification we;re
working to implement".
This document gives us some of hints to be considered when we
apply mandatory access control facilities on database systems.
However, it is not a specification of SE-PostgreSQL.
The series of documents assumes traditional multi-level-security
system, so it does not care about flexible policy, type-enforcement
rules and collaborating with operating system.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
On Sat, 2008-11-08 at 18:58 +0900, KaiGai Kohei wrote:
This document gives us some of hints to be considered when we
apply mandatory access control facilities on database systems.However, it is not a specification of SE-PostgreSQL.
The series of documents assumes traditional multi-level-security
system, so it does not care about flexible policy, type-enforcement
rules and collaborating with operating system.
I'm sorry, but I don't understand your answer.
The wiki seemed to indicate, to me, that the FK situation was a problem,
so I was trying to provide a solution. Personally, I could live with it
either way. But the important thing is: will this aspect prevent
SEPostgreSQL from achieving Common Criteria certification, or not?
If it will pass, then I'm happy, even if a different, better solution
exists. If it will fail, then we must act. I'm not qualified to say what
will happen, but it would be good to see a very clear answer on this. If
it was already resolved, then please accept my apologies for raising the
issue again. Please could you update the Wiki docs to explain the agreed
resolution, its reasons and references? The design choices we make will
be questioned again in the future, so it will be good to have them
clear. Thanks.
--
Simon Riggs www.2ndQuadrant.com
PostgreSQL Training, Services and Support
Simon Riggs wrote:
On Sat, 2008-11-08 at 14:21 +0900, KaiGai Kohei wrote:
Some users will be able to take advantage of the facilities without
implementing full MLS. Yet we want the full facilities for Government.
Many people currently run multiple customers in different schemas,
though this would let them just run a single set of tables so is much
better for running many small customers.SELinux community also provides a MLS enabled policy, but it is not
a default one now. SE-PostgreSQL has all the its access controls
decision externally, so it is out of our coltrols.I have a couple of concerns:
1. if we make a direct link with SELinux then the code will be *much*
less used and tested. It will be a constant battle to maintain
SEPostgres in a bug-free state. I want to decouple the link so this code
goes into normal Postgres. Other comments below are made with that
thought in mind.
I don't deny that SELinux has not been our majority yet.
However, I also think other configuratin options have similar issues
less or more. We cannot test all the combinations of the options, so
it should not be a reason.
2. I see another use case here. For example, a customer runs a
Software-as-a-service company where the same service is offered to 500
customers. The same database schema is there for each customer, yet they
must never see each other's data. Today, that is implemented as 500
schemas, plus 1 schema with common data in it. ISTM we would be able to
implement this better using SEPostgreSQL, with/without using SELinux.
The need for common data is why in some cases we would want access
controls placed only on certain tables.Fulfilling use case (2) will also meet my concerns in (1).
We can assign a proper label for common tables, which allows everyone
to access it. I guess it can be implement wih MCS policy so well.
Any customer has its individual category (c0 to c499) and their data
is also labeled as same category, but the common table is kept
uncategorized.
So I would prefer it if the solution was designed closely with SELinux,
but usable and useful in other cases also. The link to SELinux could be
done via a contrib plugin. A plugin is then optional. But the main
plugin we provide can be built directly with SELinux.
The reason why SE-PostgreSQL feature is implemented on the PGACE security
framework is to provide end-users options.
We can switch preferable security feature or turn it off at this level.
If necessary, we can implement another option on the PGACE. The rowacl is
proof of the concept. It seems to me you consider a pluggable interface
to operating system enables to apply other security server, but, they can
have different security model, different security attribute and so on.
I think it is an appropriate decision to switch security features at the
hook level which does not provide any security model, more than integration
of different security design.
The security context on each row could be an optional column present
only if HEAP_HASSECURITYCONTEXT is set (0x0010 see htup.h), just like
OIDs. Use a specific datatype rather than TEXT. That datatype could be
an identifier to pg_security. Security people have big databases too, so
we need to compress the security context more and take out parse time of
string handling. Don't think we should use Oids, they're too big. Might
be easier to use a 2byte field and restrict access to 32,000 contexts,
which is easily enough. TEXT also makes me nervous, just in case there
is some collation/encoding weirdness that allows contexts to be
subverted. Fixed integers are hard to compromise in that respect.An issue is who can decide the existance or needs of security system
attribute. If the table owner can disable it, we cannot say it as
a mandatory access control feature, so the security attribute has to
be always appeared when the security feature is enabled.Here is an answer for the expected question.
When we refer the "security_context" system column of tuples without
HEAP_HAS_SECURITY, it returns an alternative label called as "unlabeled_t",
because it has no labels.Not really an issue. Just use a parameter. security_controls = mandatory
or change the meaning of the existing one. Similar to default_with_oids,
just that we have a setting where it isn't optional.
This choice should be contained in the security model which can be choosen
at the PGACE hook level. At least, I cannot imagine SELinux without mandatory
feature. However, I don't deny other security model which allows mandatory or
discretionary.
The reason why we adopt TEXT type is SELinux requires userspace
object manager makes queries via text represented security context,
and it also can be used for other security feature to show client
its security attribute in human readable format.AFAICS, neither of those things means the datatype has to be TEXT.
We cannot represent a security context in TIMESTAMP or FLOAT datatype. :-)
From the viewpoint of user interfaces, I belive TEXT is an appropriate
datatype. It enables to provide an interface to manage security context
as they handle it on operating system.
For your information, in-kernel SELinux can handle 2^32 - 1 of security
context internally in theoretical maximum, so using Oid as a security
identifier is a fair decision to avoid an implementation to handle overflow
cases.OK, so we need 4 bytes. I can live with that - at least its not ~10
bytes/row. Does it need to be an Oid, or just the size of an Oid?
It utilize the fortune that Oid has 32bit length.
It enables us to indicate a tuple within pg_security without any
additional enhancement.
How does Discretionary Access control work with regard to server logs?
You said there was no superuser access, but I don't see any controls for
the logs. Do we need log_max_security_context?It writes out server logs to filesystem, so its access controls should
be applied in-kernel SELinux. SE-PostgreSQL does not care system call
invocation, because it should be a task in kernel features.
It works as a reference monitor for SQL queries.Yes, the file will be protected. My thought was that we might wish to
control the levels of message placed in the file. Otherwise you would
require top level access to view the log. It doesn't seem likely that
they would want to give Top Secret level access to DBAs. Nor should any
level of DBAs be able to inspect who is running which SQL by simple
manipulation of parameters such as log_min_duration_statement.
In this case, I recommend you to utilize TE rules, not MLS rules.
The default security policy provides postgresql_log_t type which prevent
to manupulate it from others.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
Simon Riggs wrote:
On Sat, 2008-11-08 at 18:58 +0900, KaiGai Kohei wrote:
This document gives us some of hints to be considered when we
apply mandatory access control facilities on database systems.However, it is not a specification of SE-PostgreSQL.
The series of documents assumes traditional multi-level-security
system, so it does not care about flexible policy, type-enforcement
rules and collaborating with operating system.I'm sorry, but I don't understand your answer.
What I wanted to say is that the security design of SELinux is combination
of TE(type enforcement), RBAC(role based access controls) and MLS(multi
level security) so we cannot apply specification of the document as-is.
In addition, its security policy is not hard-wired. These differences
gives us some more technical hurdles.
The wiki seemed to indicate, to me, that the FK situation was a problem,
so I was trying to provide a solution. Personally, I could live with it
either way. But the important thing is: will this aspect prevent
SEPostgreSQL from achieving Common Criteria certification, or not?
Please note that I've learned the common criteria for a few years but
not a authority, and the answer may depends on certification agency.
In my understanding, it depends on assurance level of the certification
and what functional components are required by the its environment to
be used and threats to be considered here.
If we don't consider who can be a sponsor of the certification, it has
enough functionalities to pass the certification expect for extreme
requirements which well over enterprise class systems.
The covert channel analysis is contained at the FDP_IFF section in the
Common Criteria part 2, and it defines several classes of requirements
in information flow controls.
It defines six components and FDP_IFF.3, 4, 5 mentions the handling of
covert channels, but the 3 and 4 does not require there is no covert
channels.
FYI, some of certified database products also don't mention them.
For example, the certified Oracle Label Security 10g is evaluated as
EAL4+ class, but it mentions only FDP_IFF.2, not 3, 4 and 5.
The FDP_IFF.2 is label based mandatory access controls as SE-PostgreSQL
provides.
Please could you update the Wiki docs to explain the agreed
resolution, its reasons and references? The design choices we make will
be questioned again in the future, so it will be good to have them
clear. Thanks.
OK, I'll add it to the wiki document.
Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>
I updated the patch set of SE-PostgreSQL (revision 1206)
[1/6] http://sepgsql.googlecode.com/files/sepostgresql-sepgsql-8.4devel-3-r1206.patch
[2/6] http://sepgsql.googlecode.com/files/sepostgresql-pg_dump-8.4devel-3-r1206.patch
[3/6] http://sepgsql.googlecode.com/files/sepostgresql-policy-8.4devel-3-r1206.patch
[4/6] http://sepgsql.googlecode.com/files/sepostgresql-docs-8.4devel-3-r1206.patch
[5/6] http://sepgsql.googlecode.com/files/sepostgresql-tests-8.4devel-3-r1206.patch
[6/6] http://sepgsql.googlecode.com/files/sepostgresql-row_acl-8.4devel-3-r1206.patch
Draft of the SE-PostgreSQL documentation is here:
http://wiki.postgresql.org/wiki/SEPostgreSQL
List of updates:
- Patches are rebased to the latest CVS HEAD.
- Style of patches are changes by "diff -c".
- bugfix: {use} permission on user defined function made possibility
to leak information without {select} permission.
- The wikipage is updated as I promised.
Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>
On Fri, 2008-11-07 at 16:52 -0500, Bruce Momjian wrote:
Simon, would you read the chapter on "covert channels"? You might
understand it better than I do and it might give you some ideas:http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.33.5950
OK, read that now.
Looks to me the covert channel debate will remain open whichever we do.
I agree with you that careful design avoids the problem, for the most
part. Even without that, it appears we have enough to achieve
certification.
The only remaining problem for me now is the size of the security
context column added to each row. I can accept a fixed length 4 byte
value, but anything longer just seems that it will render this unusable.
Normal apps should be able to benefit from row level security, as well
as high-security apps. The additional row overhead is enough to prevent
that, as well as put off many very large high security apps - which is
catastrophic because many of them are very large these days.
--
Simon Riggs www.2ndQuadrant.com
PostgreSQL Training, Services and Support