int mac_selinux_get_create_label_from_exe(const char *exe, char **label) { int r = -EOPNOTSUPP; #ifdef HAVE_SELINUX _cleanup_freecon_ char *mycon = NULL, *fcon = NULL; security_class_t sclass; assert(exe); assert(label); if (!mac_selinux_have()) return -EOPNOTSUPP; r = getcon_raw(&mycon); if (r < 0) return -errno; r = getfilecon_raw(exe, &fcon); if (r < 0) return -errno; sclass = string_to_security_class("process"); r = security_compute_create_raw(mycon, fcon, sclass, label); if (r < 0) return -errno; #endif return r; }
/* * sepgsql_compute_create * * It returns a default security context to be assigned on a new database * object. SELinux compute it based on a combination of client, upper object * which owns the new object and object class. * * For example, when a client (staff_u:staff_r:staff_t:s0) tries to create * a new table within a schema (system_u:object_r:sepgsql_schema_t:s0), * SELinux looks-up its security policy. If it has a special rule on the * combination of these security contexts and object class (db_table), * it returns the security context suggested by the special rule. * Otherwise, it returns the security context of schema, as is. * * We expect the caller already applies sanity/validation checks on the * given security context. * * scontext: security context of the subject (mostly, peer process). * tcontext: security context of the the upper database object. * tclass: class code (SEPG_CLASS_*) of the new object in creation */ char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass) { security_context_t ncontext; security_class_t tclass_ex; const char *tclass_name; char *result; /* Get external code of the object class*/ Assert(tclass < SEPG_CLASS_MAX); tclass_name = selinux_catalog[tclass].class_name; tclass_ex = string_to_security_class(tclass_name); /* * Ask SELinux what is the default context for the given object class * on a pair of security contexts */ if (security_compute_create_raw((security_context_t)scontext, (security_context_t)tcontext, tclass_ex, &ncontext) < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SELinux could not compute a new context: " "scontext=%s tcontext=%s tclass=%s", scontext, tcontext, tclass_name))); /* * libselinux returns malloc()'ed string, so we need to copy it * on the palloc()'ed region. */ PG_TRY(); { result = pstrdup(ncontext); } PG_CATCH(); { freecon(ncontext); PG_RE_THROW(); } PG_END_TRY(); freecon(ncontext); return result; }
int mac_selinux_get_child_mls_label(int socket_fd, const char *exe, const char *exec_label, char **label) { int r = -EOPNOTSUPP; #ifdef HAVE_SELINUX _cleanup_freecon_ char *mycon = NULL, *peercon = NULL, *fcon = NULL; _cleanup_context_free_ context_t pcon = NULL, bcon = NULL; security_class_t sclass; const char *range = NULL; assert(socket_fd >= 0); assert(exe); assert(label); if (!mac_selinux_have()) return -EOPNOTSUPP; r = getcon_raw(&mycon); if (r < 0) return -errno; r = getpeercon_raw(socket_fd, &peercon); if (r < 0) return -errno; if (!exec_label) { /* If there is no context set for next exec let's use context of target executable */ r = getfilecon_raw(exe, &fcon); if (r < 0) return -errno; } bcon = context_new(mycon); if (!bcon) return -ENOMEM; pcon = context_new(peercon); if (!pcon) return -ENOMEM; range = context_range_get(pcon); if (!range) return -errno; r = context_range_set(bcon, range); if (r) return -errno; freecon(mycon); mycon = strdup(context_str(bcon)); if (!mycon) return -ENOMEM; sclass = string_to_security_class("process"); r = security_compute_create_raw(mycon, fcon, sclass, label); if (r < 0) return -errno; #endif return r; }