Skip to content

Commit f4c4335

Browse files
committed
Add context info to OAT_POST_CREATE security hook
... and have sepgsql use it to determine whether to check permissions during certain operations. Indexes that are being created as a result of REINDEX, for instance, do not need to have their permissions checked; they were already checked when the index was created. Author: KaiGai Kohei, slightly revised by me
1 parent 4c9d090 commit f4c4335

File tree

16 files changed

+336
-116
lines changed

16 files changed

+336
-116
lines changed

contrib/sepgsql/expected/ddl.out

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_
3434
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column ctid"
3535
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column x"
3636
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column y"
37+
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
38+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
3739
ALTER TABLE regtest_table ADD COLUMN z int;
3840
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column z"
3941
CREATE TABLE regtest_table_2 (a int) WITH OIDS;
@@ -93,6 +95,55 @@ LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfine
9395
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func_2(integer)"
9496
RESET SESSION AUTHORIZATION;
9597
--
98+
-- ALTER and CREATE/DROP extra attribute permissions
99+
--
100+
CREATE TABLE regtest_table_4 (x int primary key, y int, z int);
101+
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
102+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
103+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column tableoid"
104+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column cmax"
105+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column xmax"
106+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column cmin"
107+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column xmin"
108+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column ctid"
109+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column x"
110+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column y"
111+
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column z"
112+
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
113+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
114+
CREATE INDEX regtest_index_tbl4_y ON regtest_table_4(y);
115+
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
116+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
117+
CREATE INDEX regtest_index_tbl4_z ON regtest_table_4(z);
118+
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
119+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
120+
ALTER TABLE regtest_table_4 ALTER COLUMN y TYPE float;
121+
DROP INDEX regtest_index_tbl4_y;
122+
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
123+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
124+
ALTER TABLE regtest_table_4
125+
ADD CONSTRAINT regtest_tbl4_con EXCLUDE USING btree (z WITH =);
126+
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
127+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
128+
DROP TABLE regtest_table_4 CASCADE;
129+
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
130+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
131+
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
132+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
133+
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
134+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
135+
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
136+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
137+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column tableoid"
138+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column cmax"
139+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column xmax"
140+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column cmin"
141+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column xmin"
142+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column ctid"
143+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column x"
144+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column y"
145+
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column z"
146+
--
96147
-- DROP Permission checks (with clean-up)
97148
--
98149
DROP FUNCTION regtest_func(text,int[]);
@@ -115,6 +166,8 @@ DROP TABLE regtest_table;
115166
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
116167
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_table_x_seq"
117168
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
169+
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
170+
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
118171
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
119172
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column tableoid"
120173
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column cmax"

contrib/sepgsql/hooks.c

Lines changed: 41 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ void _PG_init(void);
3838
static object_access_hook_type next_object_access_hook = NULL;
3939
static ExecutorCheckPerms_hook_type next_exec_check_perms_hook = NULL;
4040
static ProcessUtility_hook_type next_ProcessUtility_hook = NULL;
41-
static ExecutorStart_hook_type next_ExecutorStart_hook = NULL;
4241

4342
/*
4443
* Contextual information on DDL commands
@@ -97,53 +96,55 @@ sepgsql_object_access(ObjectAccessType access,
9796
switch (access)
9897
{
9998
case OAT_POST_CREATE:
100-
switch (classId)
10199
{
102-
case DatabaseRelationId:
103-
sepgsql_database_post_create(objectId,
104-
sepgsql_context_info.createdb_dtemplate);
105-
break;
100+
ObjectAccessPostCreate *pc_arg = arg;
101+
bool is_internal;
106102

107-
case NamespaceRelationId:
108-
sepgsql_schema_post_create(objectId);
109-
break;
103+
is_internal = pc_arg ? pc_arg->is_internal : false;
110104

111-
case RelationRelationId:
112-
if (subId == 0)
113-
{
114-
/*
115-
* All cases we want to apply permission checks on
116-
* creation of a new relation are invocation of the
117-
* heap_create_with_catalog via DefineRelation or
118-
* OpenIntoRel. Elsewhere, we need neither assignment
119-
* of security label nor permission checks.
120-
*/
121-
switch (sepgsql_context_info.cmdtype)
105+
switch (classId)
106+
{
107+
case DatabaseRelationId:
108+
Assert(!is_internal);
109+
sepgsql_database_post_create(objectId,
110+
sepgsql_context_info.createdb_dtemplate);
111+
break;
112+
113+
case NamespaceRelationId:
114+
Assert(!is_internal);
115+
sepgsql_schema_post_create(objectId);
116+
break;
117+
118+
case RelationRelationId:
119+
if (subId == 0)
122120
{
123-
case T_CreateStmt:
124-
case T_ViewStmt:
125-
case T_CreateSeqStmt:
126-
case T_CompositeTypeStmt:
127-
case T_CreateForeignTableStmt:
128-
case T_SelectStmt:
129-
sepgsql_relation_post_create(objectId);
130-
break;
131-
default:
132-
/* via make_new_heap() */
121+
/*
122+
* The cases in which we want to apply permission
123+
* checks on creation of a new relation correspond
124+
* to direct user invocation. For internal uses,
125+
* that is creation of toast tables, index rebuild
126+
* or ALTER TABLE commands, we need neither
127+
* assignment of security labels nor permission
128+
* checks.
129+
*/
130+
if (is_internal)
133131
break;
132+
133+
sepgsql_relation_post_create(objectId);
134134
}
135-
}
136-
else
137-
sepgsql_attribute_post_create(objectId, subId);
138-
break;
135+
else
136+
sepgsql_attribute_post_create(objectId, subId);
137+
break;
139138

140-
case ProcedureRelationId:
141-
sepgsql_proc_post_create(objectId);
142-
break;
139+
case ProcedureRelationId:
140+
Assert(!is_internal);
141+
sepgsql_proc_post_create(objectId);
142+
break;
143143

144-
default:
145-
/* Ignore unsupported object classes */
146-
break;
144+
default:
145+
/* Ignore unsupported object classes */
146+
break;
147+
}
147148
}
148149
break;
149150

@@ -215,46 +216,6 @@ sepgsql_exec_check_perms(List *rangeTabls, bool abort)
215216
return true;
216217
}
217218

218-
/*
219-
* sepgsql_executor_start
220-
*
221-
* It saves contextual information during ExecutorStart to distinguish
222-
* a case with/without permission checks later.
223-
*/
224-
static void
225-
sepgsql_executor_start(QueryDesc *queryDesc, int eflags)
226-
{
227-
sepgsql_context_info_t saved_context_info = sepgsql_context_info;
228-
229-
PG_TRY();
230-
{
231-
if (queryDesc->operation == CMD_SELECT)
232-
sepgsql_context_info.cmdtype = T_SelectStmt;
233-
else if (queryDesc->operation == CMD_INSERT)
234-
sepgsql_context_info.cmdtype = T_InsertStmt;
235-
else if (queryDesc->operation == CMD_DELETE)
236-
sepgsql_context_info.cmdtype = T_DeleteStmt;
237-
else if (queryDesc->operation == CMD_UPDATE)
238-
sepgsql_context_info.cmdtype = T_UpdateStmt;
239-
240-
/*
241-
* XXX - If queryDesc->operation is not above four cases, an error
242-
* shall be raised on the following executor stage soon.
243-
*/
244-
if (next_ExecutorStart_hook)
245-
(*next_ExecutorStart_hook) (queryDesc, eflags);
246-
else
247-
standard_ExecutorStart(queryDesc, eflags);
248-
}
249-
PG_CATCH();
250-
{
251-
sepgsql_context_info = saved_context_info;
252-
PG_RE_THROW();
253-
}
254-
PG_END_TRY();
255-
sepgsql_context_info = saved_context_info;
256-
}
257-
258219
/*
259220
* sepgsql_utility_command
260221
*
@@ -425,10 +386,6 @@ _PG_init(void)
425386
next_ProcessUtility_hook = ProcessUtility_hook;
426387
ProcessUtility_hook = sepgsql_utility_command;
427388

428-
/* ExecutorStart hook */
429-
next_ExecutorStart_hook = ExecutorStart_hook;
430-
ExecutorStart_hook = sepgsql_executor_start;
431-
432389
/* init contextual info */
433390
memset(&sepgsql_context_info, 0, sizeof(sepgsql_context_info));
434391
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy