Various sepgsql corrections.
KaiGai Kohei
This commit is contained in:
parent
426227850b
commit
c7689ee733
@ -14,6 +14,7 @@
|
||||
#include "access/tupdesc.h"
|
||||
#include "catalog/catalog.h"
|
||||
#include "catalog/heap.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/pg_attribute.h"
|
||||
#include "catalog/pg_class.h"
|
||||
#include "catalog/pg_inherits_fn.h"
|
||||
@ -151,6 +152,7 @@ check_relation_privileges(Oid relOid,
|
||||
char relkind = get_rel_relkind(relOid);
|
||||
char *scontext = sepgsql_get_client_label();
|
||||
char *tcontext;
|
||||
char *audit_name;
|
||||
Bitmapset *columns;
|
||||
int index;
|
||||
bool result = true;
|
||||
@ -183,6 +185,7 @@ check_relation_privileges(Oid relOid,
|
||||
* Check permissions on the relation
|
||||
*/
|
||||
tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
|
||||
audit_name = getObjectDescriptionOids(RelationRelationId, relOid);
|
||||
switch (relkind)
|
||||
{
|
||||
case RELKIND_RELATION:
|
||||
@ -190,10 +193,8 @@ check_relation_privileges(Oid relOid,
|
||||
tcontext,
|
||||
SEPG_CLASS_DB_TABLE,
|
||||
required,
|
||||
get_rel_name(relOid),
|
||||
audit_name,
|
||||
abort);
|
||||
if (!result)
|
||||
return false;
|
||||
break;
|
||||
|
||||
case RELKIND_SEQUENCE:
|
||||
@ -204,23 +205,31 @@ check_relation_privileges(Oid relOid,
|
||||
tcontext,
|
||||
SEPG_CLASS_DB_SEQUENCE,
|
||||
SEPG_DB_SEQUENCE__GET_VALUE,
|
||||
get_rel_name(relOid),
|
||||
audit_name,
|
||||
abort);
|
||||
return result;
|
||||
break;
|
||||
|
||||
case RELKIND_VIEW:
|
||||
result = sepgsql_check_perms(scontext,
|
||||
tcontext,
|
||||
SEPG_CLASS_DB_VIEW,
|
||||
SEPG_DB_VIEW__EXPAND,
|
||||
get_rel_name(relOid),
|
||||
audit_name,
|
||||
abort);
|
||||
return result;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* nothing to be checked */
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
pfree(tcontext);
|
||||
pfree(audit_name);
|
||||
|
||||
/*
|
||||
* Only columns owned by relations shall be checked
|
||||
*/
|
||||
if (relkind != RELKIND_RELATION)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Check permissions on the columns
|
||||
@ -233,7 +242,7 @@ check_relation_privileges(Oid relOid,
|
||||
{
|
||||
AttrNumber attnum;
|
||||
uint32 column_perms = 0;
|
||||
char audit_name[NAMEDATALEN * 2 + 10];
|
||||
ObjectAddress object;
|
||||
|
||||
if (bms_is_member(index, selected))
|
||||
column_perms |= SEPG_DB_COLUMN__SELECT;
|
||||
@ -250,8 +259,11 @@ check_relation_privileges(Oid relOid,
|
||||
/* obtain column's permission */
|
||||
attnum = index + FirstLowInvalidHeapAttributeNumber;
|
||||
tcontext = sepgsql_get_label(RelationRelationId, relOid, attnum);
|
||||
snprintf(audit_name, sizeof(audit_name), "%s.%s",
|
||||
get_rel_name(relOid), get_attname(relOid, attnum));
|
||||
|
||||
object.classId = RelationRelationId;
|
||||
object.objectId = relOid;
|
||||
object.objectSubId = attnum;
|
||||
audit_name = getObjectDescription(&object);
|
||||
|
||||
result = sepgsql_check_perms(scontext,
|
||||
tcontext,
|
||||
@ -259,6 +271,9 @@ check_relation_privileges(Oid relOid,
|
||||
column_perms,
|
||||
audit_name,
|
||||
abort);
|
||||
pfree(tcontext);
|
||||
pfree(audit_name);
|
||||
|
||||
if (!result)
|
||||
return result;
|
||||
}
|
||||
|
@ -42,15 +42,15 @@ SELECT objtype, objname, label FROM pg_seclabels
|
||||
table | t3 | system_u:object_r:sepgsql_fixed_table_t:s0
|
||||
table | t4 | system_u:object_r:sepgsql_secret_table_t:s0
|
||||
table | t5 | system_u:object_r:sepgsql_table_t:s0
|
||||
column | t5.g | system_u:object_r:sepgsql_secret_table_t:s0
|
||||
column | t5.f | system_u:object_r:sepgsql_ro_table_t:s0
|
||||
column | t5.e | system_u:object_r:sepgsql_table_t:s0
|
||||
column | t5.f | system_u:object_r:sepgsql_ro_table_t:s0
|
||||
column | t5.g | system_u:object_r:sepgsql_secret_table_t:s0
|
||||
(8 rows)
|
||||
|
||||
-- Hardwired Rules
|
||||
UPDATE pg_attribute SET attisdropped = true
|
||||
WHERE attrelid = 't5'::regclass AND attname = 'f'; -- failed
|
||||
ERROR: selinux: hardwired security policy violation
|
||||
ERROR: SELinux: hardwired security policy violation
|
||||
--
|
||||
-- Simple DML statements
|
||||
--
|
||||
|
@ -56,8 +56,8 @@ SELECT sepgsql_getcon(); -- confirm client privilege
|
||||
SECURITY LABEL ON TABLE t1
|
||||
IS 'system_u:object_r:sepgsql_ro_table_t:s0'; -- ok
|
||||
SECURITY LABEL ON TABLE t2
|
||||
IS 'invalid seuciryt context'; -- be failed
|
||||
ERROR: invalid security label: "invalid seuciryt context"
|
||||
IS 'invalid security context'; -- be failed
|
||||
ERROR: SELinux: invalid security label: "invalid security context"
|
||||
SECURITY LABEL ON COLUMN t2
|
||||
IS 'system_u:object_r:sepgsql_ro_table_t:s0'; -- be failed
|
||||
ERROR: improper relation name (too many dotted names):
|
||||
|
@ -2,4 +2,4 @@
|
||||
-- Regression Test for Misc Permission Checks
|
||||
--
|
||||
LOAD '$libdir/sepgsql'; -- failed
|
||||
ERROR: SELinux: LOAD is not allowed anyway.
|
||||
ERROR: SELinux: LOAD is not permitted
|
||||
|
@ -91,7 +91,7 @@ sepgsql_client_auth(Port *port, int status)
|
||||
if (getpeercon_raw(port->sock, &context) < 0)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("SELinux: unable to get peer label")));
|
||||
errmsg("SELinux: unable to get peer label: %m")));
|
||||
|
||||
sepgsql_set_client_label(context);
|
||||
|
||||
@ -414,7 +414,7 @@ _PG_init(void)
|
||||
if (getcon_raw(&context) < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("SELinux: failed to get server security label")));
|
||||
errmsg("SELinux: failed to get server security label: %m")));
|
||||
sepgsql_set_client_label(context);
|
||||
|
||||
/* Security label provider hook */
|
||||
|
@ -81,7 +81,7 @@ sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
|
||||
if (security_get_initial_context_raw("unlabeled", &unlabeled) < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("SELinux: failed to get initial security label")));
|
||||
errmsg("SELinux: failed to get initial security label: %m")));
|
||||
PG_TRY();
|
||||
{
|
||||
label = pstrdup(unlabeled);
|
||||
@ -184,7 +184,7 @@ sepgsql_mcstrans_in(PG_FUNCTION_ARGS)
|
||||
&raw_label) < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("SELinux: could not translate security label")));
|
||||
errmsg("SELinux: could not translate security label: %m")));
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
@ -224,7 +224,7 @@ sepgsql_mcstrans_out(PG_FUNCTION_ARGS)
|
||||
&qual_label) < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("SELinux: could not translate security label")));
|
||||
errmsg("SELinux: could not translate security label: %m")));
|
||||
|
||||
PG_TRY();
|
||||
{
|
||||
@ -241,6 +241,51 @@ sepgsql_mcstrans_out(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_TEXT_P(cstring_to_text(result));
|
||||
}
|
||||
|
||||
/*
|
||||
* quote_object_names
|
||||
*
|
||||
* It tries to quote the supplied identifiers
|
||||
*/
|
||||
static char *
|
||||
quote_object_name(const char *src1, const char *src2,
|
||||
const char *src3, const char *src4)
|
||||
{
|
||||
StringInfoData result;
|
||||
const char *temp;
|
||||
|
||||
initStringInfo(&result);
|
||||
|
||||
if (src1)
|
||||
{
|
||||
temp = quote_identifier(src1);
|
||||
appendStringInfo(&result, "%s", temp);
|
||||
if (src1 != temp)
|
||||
pfree((void *)temp);
|
||||
}
|
||||
if (src2)
|
||||
{
|
||||
temp = quote_identifier(src2);
|
||||
appendStringInfo(&result, ".%s", temp);
|
||||
if (src2 != temp)
|
||||
pfree((void *)temp);
|
||||
}
|
||||
if (src3)
|
||||
{
|
||||
temp = quote_identifier(src3);
|
||||
appendStringInfo(&result, ".%s", temp);
|
||||
if (src3 != temp)
|
||||
pfree((void *)temp);
|
||||
}
|
||||
if (src4)
|
||||
{
|
||||
temp = quote_identifier(src4);
|
||||
appendStringInfo(&result, ".%s", temp);
|
||||
if (src4 != temp)
|
||||
pfree((void *)temp);
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
|
||||
/*
|
||||
* exec_object_restorecon
|
||||
*
|
||||
@ -273,7 +318,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
|
||||
Form_pg_class relForm;
|
||||
Form_pg_attribute attForm;
|
||||
Form_pg_proc proForm;
|
||||
char objname[NAMEDATALEN * 4 + 10];
|
||||
char *objname;
|
||||
int objtype = 1234;
|
||||
ObjectAddress object;
|
||||
security_context_t context;
|
||||
@ -288,8 +333,10 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
|
||||
nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
|
||||
|
||||
objtype = SELABEL_DB_SCHEMA;
|
||||
snprintf(objname, sizeof(objname), "%s.%s",
|
||||
database_name, NameStr(nspForm->nspname));
|
||||
|
||||
objname = quote_object_name(database_name,
|
||||
NameStr(nspForm->nspname),
|
||||
NULL, NULL);
|
||||
|
||||
object.classId = NamespaceRelationId;
|
||||
object.objectId = HeapTupleGetOid(tuple);
|
||||
@ -309,9 +356,10 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
|
||||
continue; /* no need to assign security label */
|
||||
|
||||
namespace_name = get_namespace_name(relForm->relnamespace);
|
||||
snprintf(objname, sizeof(objname), "%s.%s.%s",
|
||||
database_name, namespace_name,
|
||||
NameStr(relForm->relname));
|
||||
objname = quote_object_name(database_name,
|
||||
namespace_name,
|
||||
NameStr(relForm->relname),
|
||||
NULL);
|
||||
pfree(namespace_name);
|
||||
|
||||
object.classId = RelationRelationId;
|
||||
@ -330,11 +378,12 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
|
||||
namespace_id = get_rel_namespace(attForm->attrelid);
|
||||
namespace_name = get_namespace_name(namespace_id);
|
||||
relation_name = get_rel_name(attForm->attrelid);
|
||||
snprintf(objname, sizeof(objname), "%s.%s.%s.%s",
|
||||
database_name, namespace_name,
|
||||
relation_name, NameStr(attForm->attname));
|
||||
pfree(relation_name);
|
||||
objname = quote_object_name(database_name,
|
||||
namespace_name,
|
||||
relation_name,
|
||||
NameStr(attForm->attname));
|
||||
pfree(namespace_name);
|
||||
pfree(relation_name);
|
||||
|
||||
object.classId = RelationRelationId;
|
||||
object.objectId = attForm->attrelid;
|
||||
@ -347,9 +396,10 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
|
||||
objtype = SELABEL_DB_PROCEDURE;
|
||||
|
||||
namespace_name = get_namespace_name(proForm->pronamespace);
|
||||
snprintf(objname, sizeof(objname), "%s.%s.%s",
|
||||
database_name, namespace_name,
|
||||
NameStr(proForm->proname));
|
||||
objname = quote_object_name(database_name,
|
||||
namespace_name,
|
||||
NameStr(proForm->proname),
|
||||
NULL);
|
||||
pfree(namespace_name);
|
||||
|
||||
object.classId = ProcedureRelationId;
|
||||
@ -359,6 +409,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
|
||||
|
||||
default:
|
||||
elog(ERROR, "unexpected catalog id: %u", catalogId);
|
||||
objname = NULL; /* for compiler quiet */
|
||||
break;
|
||||
}
|
||||
|
||||
@ -389,7 +440,9 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("SELinux: could not determine initial security label for %s (type=%d)", objname, objtype)));
|
||||
errmsg("SELinux: could not determine initial security label for %s (type=%d): %m", objname, objtype)));
|
||||
|
||||
pfree(objname);
|
||||
}
|
||||
systable_endscan(sscan);
|
||||
|
||||
@ -449,7 +502,7 @@ sepgsql_restorecon(PG_FUNCTION_ARGS)
|
||||
if (!sehnd)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("SELinux: failed to initialize labeling handle")));
|
||||
errmsg("SELinux: failed to initialize labeling handle: %m")));
|
||||
PG_TRY();
|
||||
{
|
||||
/*
|
||||
|
0
contrib/sepgsql/launcher
Normal file → Executable file
0
contrib/sepgsql/launcher
Normal file → Executable file
@ -13,6 +13,7 @@
|
||||
#include "access/genam.h"
|
||||
#include "access/heapam.h"
|
||||
#include "access/sysattr.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
@ -99,7 +100,7 @@ sepgsql_proc_relabel(Oid functionId, const char *seclabel)
|
||||
char *tcontext;
|
||||
char *audit_name;
|
||||
|
||||
audit_name = get_func_name(functionId);
|
||||
audit_name = getObjectDescriptionOids(ProcedureRelationId, functionId);
|
||||
|
||||
/*
|
||||
* check db_procedure:{setattr relabelfrom} permission
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "access/heapam.h"
|
||||
#include "access/sysattr.h"
|
||||
#include "catalog/indexing.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/pg_attribute.h"
|
||||
#include "catalog/pg_class.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
@ -79,15 +80,18 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
|
||||
{
|
||||
char *scontext = sepgsql_get_client_label();
|
||||
char *tcontext;
|
||||
char audit_name[NAMEDATALEN * 2 + 10];
|
||||
char *audit_name;
|
||||
ObjectAddress object;
|
||||
|
||||
if (get_rel_relkind(relOid) != RELKIND_RELATION)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||
errmsg("cannot set security label on non-regular columns")));
|
||||
|
||||
snprintf(audit_name, sizeof(audit_name), "%s.%s",
|
||||
get_rel_name(relOid), get_attname(relOid, attnum));
|
||||
object.classId = RelationRelationId;
|
||||
object.objectId = relOid;
|
||||
object.objectSubId = attnum;
|
||||
audit_name = getObjectDescription(&object);
|
||||
|
||||
/*
|
||||
* check db_column:{setattr relabelfrom} permission
|
||||
@ -100,7 +104,6 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
|
||||
SEPG_DB_COLUMN__RELABELFROM,
|
||||
audit_name,
|
||||
true);
|
||||
pfree(tcontext);
|
||||
|
||||
/*
|
||||
* check db_column:{relabelto} permission
|
||||
@ -111,6 +114,9 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
|
||||
SEPG_DB_PROCEDURE__RELABELTO,
|
||||
audit_name,
|
||||
true);
|
||||
|
||||
pfree(tcontext);
|
||||
pfree(audit_name);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -239,7 +245,7 @@ sepgsql_relation_relabel(Oid relOid, const char *seclabel)
|
||||
errmsg("cannot set security labels on relations except "
|
||||
"for tables, sequences or views")));
|
||||
|
||||
audit_name = get_rel_name(relOid);
|
||||
audit_name = getObjectDescriptionOids(RelationRelationId, relOid);
|
||||
|
||||
/*
|
||||
* check db_xxx:{setattr relabelfrom} permission
|
||||
@ -253,7 +259,6 @@ sepgsql_relation_relabel(Oid relOid, const char *seclabel)
|
||||
SEPG_DB_TABLE__RELABELFROM,
|
||||
audit_name,
|
||||
true);
|
||||
pfree(tcontext);
|
||||
|
||||
/*
|
||||
* check db_xxx:{relabelto} permission
|
||||
@ -264,4 +269,7 @@ sepgsql_relation_relabel(Oid relOid, const char *seclabel)
|
||||
SEPG_DB_TABLE__RELABELTO,
|
||||
audit_name,
|
||||
true);
|
||||
|
||||
pfree(tcontext);
|
||||
pfree(audit_name);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
#include "commands/seclabel.h"
|
||||
#include "utils/lsyscache.h"
|
||||
@ -68,7 +69,7 @@ sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
|
||||
char *tcontext;
|
||||
char *audit_name;
|
||||
|
||||
audit_name = get_namespace_name(namespaceId);
|
||||
audit_name = getObjectDescriptionOids(NamespaceRelationId, namespaceId);
|
||||
|
||||
/*
|
||||
* check db_schema:{setattr relabelfrom} permission
|
||||
|
@ -396,7 +396,7 @@ sepgsql_audit_log(bool denied,
|
||||
appendStringInfo(&buf, " scontext=%s tcontext=%s tclass=%s",
|
||||
scontext, tcontext, class_name);
|
||||
if (audit_name)
|
||||
appendStringInfo(&buf, " name=%s", audit_name);
|
||||
appendStringInfo(&buf, " name=\"%s\"", audit_name);
|
||||
|
||||
ereport(LOG, (errmsg("SELinux: %s", buf.data)));
|
||||
}
|
||||
@ -459,7 +459,7 @@ sepgsql_compute_avd(const char *scontext,
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("SELinux could not compute av_decision: "
|
||||
"scontext=%s tcontext=%s tclass=%s",
|
||||
"scontext=%s tcontext=%s tclass=%s: %m",
|
||||
scontext, tcontext, tclass_name)));
|
||||
|
||||
/*
|
||||
@ -545,7 +545,7 @@ sepgsql_compute_create(const char *scontext,
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||
errmsg("SELinux could not compute a new context: "
|
||||
"scontext=%s tcontext=%s tclass=%s",
|
||||
"scontext=%s tcontext=%s tclass=%s: %m",
|
||||
scontext, tcontext, tclass_name)));
|
||||
|
||||
/*
|
||||
|
@ -46,7 +46,7 @@ SELECT objtype, objname, label FROM pg_seclabels
|
||||
SECURITY LABEL ON TABLE t1
|
||||
IS 'system_u:object_r:sepgsql_ro_table_t:s0'; -- ok
|
||||
SECURITY LABEL ON TABLE t2
|
||||
IS 'invalid seuciryt context'; -- be failed
|
||||
IS 'invalid security context'; -- be failed
|
||||
SECURITY LABEL ON COLUMN t2
|
||||
IS 'system_u:object_r:sepgsql_ro_table_t:s0'; -- be failed
|
||||
SECURITY LABEL ON COLUMN t2.b
|
||||
|
Loading…
Reference in New Issue
Block a user