Thread: Extend argument of OAT_POST_CREATE

Extend argument of OAT_POST_CREATE

From
Kohei KaiGai
Date:
The attached patch adds argument of OAT_POST_CREATE hook;
to inform extensions type of the context of this object creation. It allows
extensions to know whether the new object is indirectly created apart
from user's operations, or not.

I found out this flag is necessary to add feature to support selinux
checks on ALTER statement (with reasonably simple code) during
my investigation.

A table has various kind of properties; some of them are inlined in
pg_class but others are stored in extra catalogs such as pg_trigger,
pg_constraint and so on.
It might take an extra discussion whether trigger or constraint is
an independent object or an attribute of table. But, anyway, the
default permission checks table's ownership or ACLs when we
create or drop them. I don't think sepgsql should establish its own
object model here.

So, I want sepgsql to check table's "setattr" permission when user
create, drop or alter these objects.

In case of index creation, here are two cases a) user's operation
intend to create index, thus, checks permission of the table being
indexed on b) index is indirectly created as a result of other
operations like change of column's data type.
Due to same reason why we don't check permissions for cleanup
of temporary object, I don't want to apply checks on the later case.

Right now, sepgsql determines the current context using command
tag being saved at ProceddUtility_hook; to avoid permission checks
on table creation due to CLUSTER command for example.
But, it is not easy to apply this approach for the case of index
creation because it can be defined as a part of ALTER TABLE
which may have multiple sub-commands.

So, I want OAT_POST_CREATE hook to inform the current context
of the object creation; whether it is internal / indirect creation, or not.

This patch includes hook enhancement and "setattr" permission checks
on index creation / deletion.

Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>

Attachment

Re: Extend argument of OAT_POST_CREATE

From
Alvaro Herrera
Date:
Kohei KaiGai escribió:
> The attached patch adds argument of OAT_POST_CREATE hook;
> to inform extensions type of the context of this object creation. It allows
> extensions to know whether the new object is indirectly created apart
> from user's operations, or not.

Can we add Assert(!is_internal) to the ProcedureRelationId case in
sepgsql_object_access() too?  I don't see any caller that would set it
true anywhere, but maybe you have a good reason for omitting it.

I'm not clear on what's sepgsql_relation_setattr for; it doesn't seem to
be called anywhere (other than sepgsql_relation_setattr_extra, but
that's static, so why isn't sepgsql_relation_setattr also static?).  But
I notice that it calls sepgsql_index_modify without first checking for
the toast namespace like the other callers do.  Is this okay or an
oversight?

I admit the new RELKIND_INDEX cases in various places make for strange
flow.  Not sure how it can be improved though.

I didn't find anything wrong with the changes to src/backend.  One thing
that I noticed is that when bootstrapping, all relation creation is
considered internal.  I am sure this is okay fo the normal case, but I
wonder if a malicious superuser could get a hold of things that he
shouldn't by starting a bootstrapping backend and run relation creation
there.

Note: I can compile sepgsql but not run the regression tests.

--
Álvaro Herrera                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services



Re: Extend argument of OAT_POST_CREATE

From
Kohei KaiGai
Date:
Thanks for your reviews.

2012/10/10 Alvaro Herrera <alvherre@2ndquadrant.com>:
> Kohei KaiGai escribió:
>> The attached patch adds argument of OAT_POST_CREATE hook;
>> to inform extensions type of the context of this object creation. It allows
>> extensions to know whether the new object is indirectly created apart
>> from user's operations, or not.
>
> Can we add Assert(!is_internal) to the ProcedureRelationId case in
> sepgsql_object_access() too?  I don't see any caller that would set it
> true anywhere, but maybe you have a good reason for omitting it.
>
No, I just missed to add Assert() here.

> I'm not clear on what's sepgsql_relation_setattr for; it doesn't seem to
> be called anywhere (other than sepgsql_relation_setattr_extra, but
> that's static, so why isn't sepgsql_relation_setattr also static?).  But
> I notice that it calls sepgsql_index_modify without first checking for
> the toast namespace like the other callers do.  Is this okay or an
> oversight?
>
I assume sepgsql_relation_setattr is also called on ALTER TABLE
command; to check privilege to modify properties of the target table.
Entrypoint of the object_access_hook is at sepgsql/hooks.c, so this
function was declared without static for (near) future usage.
Regarding to toast relation/index, as default permission mechanism
doing, sepgsql handles toast is a pure-internal semantics, thus, no
security label is assigned and no permission checks are applied.
(Also, please check check_relation_privileges at sepgsql/dml.c.
 It does not allow to reference toast relation using regular SQL
 with hardwired rule, because of the nature of "internal stuff".)

> I admit the new RELKIND_INDEX cases in various places make for strange
> flow.  Not sure how it can be improved though.
>
The idea is not so complicated. This code considers index is an
property of a certain table like as individual field of pg_class.
Relation is the most complex object in PostgreSQL. Its property
is not only ones in pg_class, but some extra catalogs such as
pg_trigger, pg_rewrite and so on.
The default permission checks ownership of the table, instead
of triggers, rules or indexes, when user tries to alter them.
Here is no good reason why sepgsql needs to give its own
definition of relation, so I just followed this manner.

> I didn't find anything wrong with the changes to src/backend.  One thing
> that I noticed is that when bootstrapping, all relation creation is
> considered internal.  I am sure this is okay fo the normal case, but I
> wonder if a malicious superuser could get a hold of things that he
> shouldn't by starting a bootstrapping backend and run relation creation
> there.
>
Yes, you are right. Even though it is harmless right now because we have
no way to load extension prior to initdb, it makes confusion if some built-in
feature used object access hook. The "internal" flag means the given SQL
statement does not intend creation itself of the target object, but bootstrap
command definitely intend to create initial objects.

On the other hand, I don't care about the scenario with malicious superuser
that runs initdb, because it is an assumption of sepgsql to set up initial
database on environment without something malicious.
If we try to prevent to create an initial database by malicious users, it should
be a responsibility of operating system and its policy.

Thanks,
--
KaiGai Kohei <kaigai@kaigai.gr.jp>

Attachment

Re: Extend argument of OAT_POST_CREATE

From
Alvaro Herrera
Date:
Kohei KaiGai escribió:

> 2012/10/10 Alvaro Herrera <alvherre@2ndquadrant.com>:

> > I admit the new RELKIND_INDEX cases in various places make for strange
> > flow.  Not sure how it can be improved though.
> >
> The idea is not so complicated. This code considers index is an
> property of a certain table like as individual field of pg_class.
> Relation is the most complex object in PostgreSQL. Its property
> is not only ones in pg_class, but some extra catalogs such as
> pg_trigger, pg_rewrite and so on.

I have pushed this patch with some slight changes in the way
the RELKIND_INDEX case is handled in various places, to make it
clearer.  I may have broken some cases; please have a look.

Thanks.

--
Álvaro Herrera                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services