Re: [HACKERS] [RFC] Security label support

2010-05-27 Thread Stephen Frost
KaiGai,

* KaiGai Kohei (kai...@ak.jp.nec.com) wrote:
 As we talked at the developer meeting on Ottawa, it needs to provide
 a capability to assign a short text identifier on database objects
 to support label based ESP (such as SELinux).
 So, I'd like to propose a few approaches to support security label
 as a draft of discussion.
[...]
 [2] Using OID as a key of text representation in separated catalog
 --
 
 This idea is similar to pg_description/pg_shdescription.
 A new system catalog pg_seclabel and pg_shseclabel stores text form
 of labels for pair of the relation-Id, object-Oid and object-Subid.
 It does not damage to the schema of existing system catalog,

Right, this is the approach that was agreed to during various
discussions and is, I believe, what Robert is currently working on.

 It adds two new system catalogs; pg_seclabel (local) and pg_shseclabel 
 (shared).

Do we really need a shared catalog initially?  Right now, we're just
talking about labels for tables and columns.  Let's not overcomplicate
this.  We can always add it later.

 We also add a dependency between the labeled object and the security
 label itself. It also enables to clean up orphan labels automatically,
 without any new invention.

I agree that we need to address this.  I am kind of curious how this is
handled for comments?  It appears to be, but I don't see an entry in
pg_depend when a comment is added to an object, yet the entry in
pg_description disappears when a table is dropped.  Shrug

 However, it also has a limitation from the viewpoint of long-term.
 From the definition, OID of database objects are unique. So, we cannot
 share text form of labels even if massive number of database objects
 have an identical security label; it can lead waste of storage consumption
 because of the duplicated security labels. So, this idea shall be switched
 to the [3] when we support row-level security with ESP.
 But I think the idea [2] is reasonable in short-term development.

Row level security might not even use this catalog directly but perhaps
another one.  That's a discussion for a much later time though.

 * SQL Statement
 ---
 
 It also need to provide SQL statement to manage security label of the database
 object. I plan the following statement to change the security label.
 
   ALTER xxx name SECURITY LABEL TO 'label';

Rather than adding more cruft around ALTER, I believe the plan is to add
a new top-level command (eg: 'SECURITY LABEL ON'), just like the COMMENT
ON syntax.

 When the ALTER command is executed, ESP module validate the given label,
 in addition to permission checks to relabel it.

 If no ESP module is available, the ALTER always raises a feature-not-supported
 error.

Right.  We do need to identify what the hook needs to look like.  I
would think just passing a pg_seclabel (or whatever) structure which
would represent the new row in the table (possibly replacing an existing
row, if one exists, but the hook can figure that out).  The hook can
then figure out the user and any other information it needs to know
based on that and either allow or not allow the change.

 In my original SE-PostgreSQL design, it provided an option to specify
 an explicit security label in CREATE xxx statement, but I discarded
 the idea, because the implementation of CREATE statement has much
 variations for each object class (so the patch will be invasive),
 and it is a fungible functionality using ALTER.

As with other things, this could be done in a transaction rather than
cluttering up CREATE, etc, statements.  Supporting a default label for
objects might be something which could be added later.

 * Pg_dump/Pg_restore support
 

We do need to include some kind of pg_dump/pg_restore support for this,
of course.

Thanks,

Stephen


signature.asc
Description: Digital signature


Re: [HACKERS] [RFC] Security label support

2010-05-27 Thread Tom Lane
Stephen Frost sfr...@snowman.net writes:
 We also add a dependency between the labeled object and the security
 label itself. It also enables to clean up orphan labels automatically,
 without any new invention.

 I agree that we need to address this.  I am kind of curious how this is
 handled for comments?  It appears to be, but I don't see an entry in
 pg_depend when a comment is added to an object, yet the entry in
 pg_description disappears when a table is dropped.  Shrug

IIRC, dropping comments is hard-wired into the object drop mechanism ---
this seemed more efficient than having to add a pg_depend entry for each
one.  You could argue that either way of course depending on how many
comments you expect there to be in the system.

I'm not real sure that you want a dependency for a security label anyway
--- wouldn't that mean each label could only be used for one object?

regards, tom lane

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [RFC] Security label support

2010-05-27 Thread Stephen Frost
* Tom Lane (t...@sss.pgh.pa.us) wrote:
 Stephen Frost sfr...@snowman.net writes:
  I agree that we need to address this.  I am kind of curious how this is
  handled for comments?  It appears to be, but I don't see an entry in
  pg_depend when a comment is added to an object, yet the entry in
  pg_description disappears when a table is dropped.  Shrug
 
 IIRC, dropping comments is hard-wired into the object drop mechanism ---
 this seemed more efficient than having to add a pg_depend entry for each
 one.  You could argue that either way of course depending on how many
 comments you expect there to be in the system.

ok.  We would need to add similar mechanics for labels (removing the
entries when the table is dropped).  Strikes me as slightly odd that we
have an infrastructure in place to handle exactly that but we're not
using it. :)

 I'm not real sure that you want a dependency for a security label anyway
 --- wouldn't that mean each label could only be used for one object?

Err, your question comes across to me like if you added comments to
pg_depend, you'd only be able to use a given comment X for one object?.
Doesn't make alot of sense. :)  Perhaps I misunderstood, but my
assumption would be that, as with comments, there would be an additional
identifier in pg_seclabel (eg: oid) to then use in pg_depend to track that
a given *entry* in pg_seclabel depends on a table.  You wouldn't (erm,
and couldn't) put the actual text of the label into pg_depend.

The structure for pg_seclabel we were talking about would be very
similar to pg_description, eg:

CREATE TABLE pg_seclabel (
  objoid oid not null,
  classoid oid not null,
  objsubid integer not null,
  label text 
);

We could move label into another table (eg: pg_labels) and then give an
OID to each label and then store the label's OID in pg_seclabel.  That
would then have the problem you describe, but we could just have a
'mapping OID' from the table to the label and then have *that* depend on
the table (erm, and the label).  I'm not sure I see the need for that
right now.  We may want that when we add row-level security support, so
perhaps we should consider doing that now, but I don't expect RLS
anytime real soon.

A thought that did occur to me is that we could forgo actually
identifying in pg_depend the *specific* entry in pg_description or
pg_seclabel that depends on the table and, perhaps, just have an
entry that says something with this classid depends on it, so delete
anything in that table which has a matching objoid and classoid of
what's being removed.

Thanks,

Stephen


signature.asc
Description: Digital signature


Re: [HACKERS] [RFC] Security label support

2010-05-27 Thread Tom Lane
Stephen Frost sfr...@snowman.net writes:
 * Tom Lane (t...@sss.pgh.pa.us) wrote:
 I'm not real sure that you want a dependency for a security label anyway
 --- wouldn't that mean each label could only be used for one object?

 Err, your question comes across to me like if you added comments to
 pg_depend, you'd only be able to use a given comment X for one object?.
 Doesn't make alot of sense. :)

Well, one of us is confused.  I thought the idea was that the same
security label would apply to many different objects.  If each object
has its own label, you're going to need an awfully large label cache
for performance to be sane.

 The structure for pg_seclabel we were talking about would be very
 similar to pg_description, eg:

 CREATE TABLE pg_seclabel (
   objoid oid not null,
   classoid oid not null,
   objsubid integer not null,
   label text 
 );

 We could move label into another table (eg: pg_labels) and then give an
 OID to each label and then store the label's OID in pg_seclabel.

OK, but the notion that you would try to remove orphan pg_labels
entries seems entirely wrongheaded to me.  The labels would be
long-lived objects.

regards, tom lane

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [RFC] Security label support

2010-05-27 Thread Robert Haas
On Thu, May 27, 2010 at 4:01 PM, Tom Lane t...@sss.pgh.pa.us wrote:
 Stephen Frost sfr...@snowman.net writes:
 * Tom Lane (t...@sss.pgh.pa.us) wrote:
 I'm not real sure that you want a dependency for a security label anyway
 --- wouldn't that mean each label could only be used for one object?

 Err, your question comes across to me like if you added comments to
 pg_depend, you'd only be able to use a given comment X for one object?.
 Doesn't make alot of sense. :)

 Well, one of us is confused.  I thought the idea was that the same
 security label would apply to many different objects.  If each object
 has its own label, you're going to need an awfully large label cache
 for performance to be sane.

I think this only makes sense when and if we implement row-level
security.  The labels for SELinux are, say, 64 byte strings.  That's
really not that big, if these are only being applied to objects like
tables, and even columns.   More to the point, ISTM a cache would be
fairly useless anyway, because you have to pass the labels themselves
to the OS to get an access control decision, which is also based on
the type of object that you're doing something to and the operation
you're doing to it.  It probably make sense to cache the results of
the access-control lookup within a query - for example, if all the
labels of a table you're accessing have the same label, just ask once
for all of them, instead of individually for each one - but I can't
see how you could usefully do much more than that.

Now, if we were talking about row-level security, well, that's a whole
different situation.  Now the space to store the individual labels
might become burdensome.  But that's a problem for another day,
hopefully a day when I'm out of town.

 The structure for pg_seclabel we were talking about would be very
 similar to pg_description, eg:

 CREATE TABLE pg_seclabel (
   objoid oid not null,
   classoid oid not null,
   objsubid integer not null,
   label text
 );

 We could move label into another table (eg: pg_labels) and then give an
 OID to each label and then store the label's OID in pg_seclabel.

 OK, but the notion that you would try to remove orphan pg_labels
 entries seems entirely wrongheaded to me.  The labels would be
 long-lived objects.

Now I'm confused.  Previously you complained about not having a
garbage collection mechanism for labels - now you seem to be saying
that we should never garbage collect.

-- 
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise Postgres Company

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [RFC] Security label support

2010-05-27 Thread Stephen Frost
* Tom Lane (t...@sss.pgh.pa.us) wrote:
 Stephen Frost sfr...@snowman.net writes:
  Err, your question comes across to me like if you added comments to
  pg_depend, you'd only be able to use a given comment X for one object?.
  Doesn't make alot of sense. :)
 
 Well, one of us is confused.  I thought the idea was that the same
 security label would apply to many different objects.  If each object
 has its own label, you're going to need an awfully large label cache
 for performance to be sane.

It's certainly true that many objects could, and probably would in most
situations, have the same label.  I feel like that could be true of
comments as well.  We were just thinking about keeping it simple in the
first go-round.  Going back to what I think was KaiGai's earlier
question about which way to go:

#1: only have pg_description-like pg_seclabel
(objoid oid, classoid oid, objsubid integer, label text)

#2: have long-lived labels in pg_seclabels with (secoid oid, label text)
have label_oid in various system catalogs (pg_class, etc)

#3: have long-lived labels in pg_seclabels with (secoid oid, label text)
have mapping from each object to OID of label associated with it
(objoid oid, classoid oid, objsubid integer, secoid oid)

My inclination would generally be towards #2, to be honest, but I
thought we wanted to avoid changing pg_namespace, pg_class and
pg_attribute for this.

 OK, but the notion that you would try to remove orphan pg_labels
 entries seems entirely wrongheaded to me.  The labels would be
 long-lived objects.

OK, then we should really go with either #2 or #3 from above, and make
sure that we add appropriate grammar to allow adding and removing of
security labels.  Do we then throw an error if someone tries to put a
label on an object that we don't already know of?  We certainly need to
complain if someone tries to remove a label that is used by an object
somewhere.  Typically, I'd expect the set of labels to be pretty well
defined, but there will still be some amount of churn, and we'll need a
way for people to determine what objects are still using certain labels.
Not unlike how we deal with roles today already though.

Thanks,

Stephen


signature.asc
Description: Digital signature


Re: [HACKERS] [RFC] Security label support

2010-05-27 Thread KaiGai Kohei
(2010/05/28 4:12), Stephen Frost wrote:
 KaiGai,
 
 * KaiGai Kohei (kai...@ak.jp.nec.com) wrote:
 As we talked at the developer meeting on Ottawa, it needs to provide
 a capability to assign a short text identifier on database objects
 to support label based ESP (such as SELinux).
 So, I'd like to propose a few approaches to support security label
 as a draft of discussion.
 [...]
 [2] Using OID as a key of text representation in separated catalog
 --

 This idea is similar to pg_description/pg_shdescription.
 A new system catalog pg_seclabel and pg_shseclabel stores text form
 of labels for pair of the relation-Id, object-Oid and object-Subid.
 It does not damage to the schema of existing system catalog,
 
 Right, this is the approach that was agreed to during various
 discussions and is, I believe, what Robert is currently working on.
 
Good.

I've been allowed to work it with high priority.
If your hands are not free, should I work on it?

 It adds two new system catalogs; pg_seclabel (local) and pg_shseclabel 
 (shared).
 
 Do we really need a shared catalog initially?  Right now, we're just
 talking about labels for tables and columns.  Let's not overcomplicate
 this.  We can always add it later.
 
Perhaps, I can agree to add it later. I believe the pg_seclabel and 
pg_shseclabel
shall have identical schema, so we can easily add it.

 We also add a dependency between the labeled object and the security
 label itself. It also enables to clean up orphan labels automatically,
 without any new invention.
 
 I agree that we need to address this.  I am kind of curious how this is
 handled for comments?  It appears to be, but I don't see an entry in
 pg_depend when a comment is added to an object, yet the entry in
 pg_description disappears when a table is dropped.Shrug
 

Sorry, I missed the special handling of pg_description.
However, what we should do here is same as pg_description without
any new invention.

 However, it also has a limitation from the viewpoint of long-term.
  From the definition, OID of database objects are unique. So, we cannot
 share text form of labels even if massive number of database objects
 have an identical security label; it can lead waste of storage consumption
 because of the duplicated security labels. So, this idea shall be switched
 to the [3] when we support row-level security with ESP.
 But I think the idea [2] is reasonable in short-term development.
 
 Row level security might not even use this catalog directly but perhaps
 another one.  That's a discussion for a much later time though.
 

Yep, we can design it later.

 * SQL Statement
 ---

 It also need to provide SQL statement to manage security label of the 
 database
 object. I plan the following statement to change the security label.

ALTER xxxname  SECURITY LABEL TO 'label';
 
 Rather than adding more cruft around ALTER, I believe the plan is to add
 a new top-level command (eg: 'SECURITY LABEL ON'), just like the COMMENT
 ON syntax.
 

It seems to me the syntax like COMMENT ON gives us an incorrect impression.
The role of ALTER is (basically) to alter an existing property of the object,
such as owner, name, schema and so on. Meanwhile, COMMENT ON is used for
both assignment of new description and update of existing description.

The security label is a part of the properties of object to be assigned on
the creation time, such as owner-id. (Even if ESP module is not loaded on
the creation time, it assumes someone is labeled on the unlabeled object.)

The ALTER SECURITY LABEL TO shall be implemented as an individual code path,
like ALTER xxx RENAME TO or ALTER xxx SCHEMA TO, so the patch shall not be
invasive to existing ALTER implementation.

I don't think a new top level 'SECURITY LABEL ON' is not a good naming,
although its internal catalog layout is similar to pg_description.

 When the ALTER command is executed, ESP module validate the given label,
 in addition to permission checks to relabel it.
 
 If no ESP module is available, the ALTER always raises a 
 feature-not-supported
 error.
 
 Right.  We do need to identify what the hook needs to look like.  I
 would think just passing a pg_seclabel (or whatever) structure which
 would represent the new row in the table (possibly replacing an existing
 row, if one exists, but the hook can figure that out).  The hook can
 then figure out the user and any other information it needs to know
 based on that and either allow or not allow the change.
 

I think ESP should not need to handle whether the target object is already
labeled, or not. It can be push down into a common function.
For example, we can easily provide seclabel_insert_or_update() that allows
to insert a new label into pg_seclabel (if not exist) or update an old label
of pg_seclabel (if exist).

I plan the following design typically. In this case, the ESP hook validates
the given new label and check its permission to 

Re: [HACKERS] [RFC] Security label support

2010-05-27 Thread KaiGai Kohei
(2010/05/28 5:11), Robert Haas wrote:
 On Thu, May 27, 2010 at 4:01 PM, Tom Lanet...@sss.pgh.pa.us  wrote:
 Stephen Frostsfr...@snowman.net  writes:
 * Tom Lane (t...@sss.pgh.pa.us) wrote:
 I'm not real sure that you want a dependency for a security label anyway
 --- wouldn't that mean each label could only be used for one object?

 Err, your question comes across to me like if you added comments to
 pg_depend, you'd only be able to use a given comment X for one object?.
 Doesn't make alot of sense. :)

 Well, one of us is confused.  I thought the idea was that the same
 security label would apply to many different objects.  If each object
 has its own label, you're going to need an awfully large label cache
 for performance to be sane.
 
 I think this only makes sense when and if we implement row-level
 security.  The labels for SELinux are, say, 64 byte strings.  That's
 really not that big, if these are only being applied to objects like
 tables, and even columns.

Yes, as I noted on the idea [3], RLS with label requires a facility to
share a limited number of security labels, instead of flat text for
each user tuples. But it will need more code than the idea [2].

  More to the point, ISTM a cache would be
 fairly useless anyway, because you have to pass the labels themselves
 to the OS to get an access control decision, which is also based on
 the type of object that you're doing something to and the operation
 you're doing to it.  It probably make sense to cache the results of
 the access-control lookup within a query - for example, if all the
 labels of a table you're accessing have the same label, just ask once
 for all of them, instead of individually for each one - but I can't
 see how you could usefully do much more than that.
 
Right, as long as security policy is identical, it returns an identical
access control decision for the given pair of security label.
I plan to support access control decision cache, but it should be
implemented within ESP module, because it is SELinux specific.

BTW, SELinux also provide an interface to inform userspace applications
an invalidation message when security policy is reloaded, using netlink
socket. We entirely need a background worker process to monitor the socket,
but it should be in the future development.

 Now, if we were talking about row-level security, well, that's a whole
 different situation.  Now the space to store the individual labels
 might become burdensome.  But that's a problem for another day,
 hopefully a day when I'm out of town.
 
Yes, let's tackle it in another day.

 The structure for pg_seclabel we were talking about would be very
 similar to pg_description, eg:

 CREATE TABLE pg_seclabel (
objoid oid not null,
classoid oid not null,
objsubid integer not null,
label text
 );

 We could move label into another table (eg: pg_labels) and then give an
 OID to each label and then store the label's OID in pg_seclabel.

 OK, but the notion that you would try to remove orphan pg_labels
 entries seems entirely wrongheaded to me.  The labels would be
 long-lived objects.
 
 Now I'm confused.  Previously you complained about not having a
 garbage collection mechanism for labels - now you seem to be saying
 that we should never garbage collect.
 
I'm also confused. What is the orphan label in the current pg_description
like design?
It has 1:1 map with a certain database object, so whenever we drop
the database object, its label entry shall be also dropped.
As long as database is not corrupt, no orphan labels will appear.

Thanks,
-- 
KaiGai Kohei kai...@ak.jp.nec.com

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] [RFC] Security label support

2010-05-27 Thread KaiGai Kohei
(2010/05/28 5:25), Stephen Frost wrote:
 * Tom Lane (t...@sss.pgh.pa.us) wrote:
 Stephen Frostsfr...@snowman.net  writes:
 Err, your question comes across to me like if you added comments to
 pg_depend, you'd only be able to use a given comment X for one object?.
 Doesn't make alot of sense. :)

 Well, one of us is confused.  I thought the idea was that the same
 security label would apply to many different objects.  If each object
 has its own label, you're going to need an awfully large label cache
 for performance to be sane.
 
 It's certainly true that many objects could, and probably would in most
 situations, have the same label.  I feel like that could be true of
 comments as well.  We were just thinking about keeping it simple in the
 first go-round.  Going back to what I think was KaiGai's earlier
 question about which way to go:
 
 #1: only have pg_description-like pg_seclabel
  (objoid oid, classoid oid, objsubid integer, label text)
 
 #2: have long-lived labels in pg_seclabels with (secoid oid, label text)
  have label_oid in various system catalogs (pg_class, etc)
 
 #3: have long-lived labels in pg_seclabels with (secoid oid, label text)
  have mapping from each object to OID of label associated with it
   (objoid oid, classoid oid, objsubid integer, secoid oid)
 
 My inclination would generally be towards #2, to be honest, but I
 thought we wanted to avoid changing pg_namespace, pg_class and
 pg_attribute for this.
 
Are you talking about a future development, aren't you?

I comment it for just a future development, not current efforts.

I plan the security-Id which points to an entry of pg_seclabel shall
be stored within padding area of HeapTupleHeader like what we are doing
to store object-Id.
The object-Id is stored only when HEAP_HASOID is set on t_infomask.
It does not damage to the existing schema of system catalog, and
allows to turn on/off the table's capability to store the security-Id.
Maybe, if we set up SELinux support, we need to run a special program
to initialize the database cluster just after initdb. It will turn on
the capability to store security-Id of the pg_class and so on.
Of course, we can apply same way between system catalogs and users'
tables.

 OK, but the notion that you would try to remove orphan pg_labels
 entries seems entirely wrongheaded to me.  The labels would be
 long-lived objects.
 
 OK, then we should really go with either #2 or #3 from above, and make
 sure that we add appropriate grammar to allow adding and removing of
 security labels.  Do we then throw an error if someone tries to put a
 label on an object that we don't already know of?  We certainly need to
 complain if someone tries to remove a label that is used by an object
 somewhere.  Typically, I'd expect the set of labels to be pretty well
 defined, but there will still be some amount of churn, and we'll need a
 way for people to determine what objects are still using certain labels.
 Not unlike how we deal with roles today already though.
 
As Bruce suggested before, pg_seclabel should have relid field which
ensures the relation which references the security label entry.
It allows us to reclaim orphan security label with minimum locks.

In SE-PostgreSQL of Fedora, I provide a method to reclaim orphan labels:

  LOCK target table IN SHARE MODE;

  DELETE FROM pg_seclabel WHERE relid = OID of target table AND
  secid NOT IN (SELECT tuple_to_secid(target table) FROM ONLY target 
table);

During the reclaims, the target table is locked for writable accesses,
but we don't need to lock out whole of the database to detect orphan labels.

Thanks,
-- 
KaiGai Kohei kai...@ak.jp.nec.com

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers