From: Robert Haas Date: Thu, 3 Feb 2011 04:39:43 +0000 (-0500) Subject: Various sepgsql corrections. X-Git-Tag: REL9_1_ALPHA4~286 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=c7689ee73346d198177dee538501bb1148c8cebb;p=postgresql.git Various sepgsql corrections. KaiGai Kohei --- diff --git a/contrib/sepgsql/dml.c b/contrib/sepgsql/dml.c index 684b5ee8e61..358a2643ca4 100644 --- a/contrib/sepgsql/dml.c +++ b/contrib/sepgsql/dml.c @@ -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; } diff --git a/contrib/sepgsql/expected/dml.out b/contrib/sepgsql/expected/dml.out index 5625ebcd9ee..c1bbbba0093 100644 --- a/contrib/sepgsql/expected/dml.out +++ b/contrib/sepgsql/expected/dml.out @@ -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 -- diff --git a/contrib/sepgsql/expected/label.out b/contrib/sepgsql/expected/label.out index 0f0615cb306..daf8d08eb2a 100644 --- a/contrib/sepgsql/expected/label.out +++ b/contrib/sepgsql/expected/label.out @@ -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): diff --git a/contrib/sepgsql/expected/misc.out b/contrib/sepgsql/expected/misc.out index 5242333bf49..329852c5749 100644 --- a/contrib/sepgsql/expected/misc.out +++ b/contrib/sepgsql/expected/misc.out @@ -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 diff --git a/contrib/sepgsql/hooks.c b/contrib/sepgsql/hooks.c index bc7ce51cf15..83a505ec18d 100644 --- a/contrib/sepgsql/hooks.c +++ b/contrib/sepgsql/hooks.c @@ -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 */ diff --git a/contrib/sepgsql/label.c b/contrib/sepgsql/label.c index ad568f8aa6b..828512a961a 100644 --- a/contrib/sepgsql/label.c +++ b/contrib/sepgsql/label.c @@ -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(); { /* diff --git a/contrib/sepgsql/launcher b/contrib/sepgsql/launcher old mode 100644 new mode 100755 diff --git a/contrib/sepgsql/proc.c b/contrib/sepgsql/proc.c index f1a7b9b7505..5a0c4947f72 100644 --- a/contrib/sepgsql/proc.c +++ b/contrib/sepgsql/proc.c @@ -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 diff --git a/contrib/sepgsql/relation.c b/contrib/sepgsql/relation.c index ceaa6b02357..ed5e3adc0e8 100644 --- a/contrib/sepgsql/relation.c +++ b/contrib/sepgsql/relation.c @@ -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); } diff --git a/contrib/sepgsql/schema.c b/contrib/sepgsql/schema.c index df33a027353..8538d18ac9e 100644 --- a/contrib/sepgsql/schema.c +++ b/contrib/sepgsql/schema.c @@ -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 diff --git a/contrib/sepgsql/selinux.c b/contrib/sepgsql/selinux.c index a67bd567112..03ba25cef08 100644 --- a/contrib/sepgsql/selinux.c +++ b/contrib/sepgsql/selinux.c @@ -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))); /* diff --git a/contrib/sepgsql/sql/label.sql b/contrib/sepgsql/sql/label.sql index 31624948782..1100fcb35a6 100644 --- a/contrib/sepgsql/sql/label.sql +++ b/contrib/sepgsql/sql/label.sql @@ -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