int security_compute_av_raw(const char * scon, const char * tcon, security_class_t tclass, access_vector_t requested, struct av_decision *avd) { struct av_decision lavd; int ret; ret = security_compute_av_flags_raw(scon, tcon, tclass, requested, &lavd); if (ret == 0) { avd->allowed = lavd.allowed; avd->decided = lavd.decided; avd->auditallow = lavd.auditallow; avd->auditdeny = lavd.auditdeny; avd->seqno = lavd.seqno; /* NOTE: * We should not return avd->flags via the interface * due to the binary compatibility. */ } return ret; }
int security_compute_av_flags(const char * scon, const char * tcon, security_class_t tclass, access_vector_t requested, struct av_decision *avd) { char * rscon; char * rtcon; int ret; if (selinux_trans_to_raw_context(scon, &rscon)) return -1; if (selinux_trans_to_raw_context(tcon, &rtcon)) { freecon(rscon); return -1; } ret = security_compute_av_flags_raw(rscon, rtcon, tclass, requested, avd); freecon(rscon); freecon(rtcon); return ret; }
/* * sepgsql_compute_avd * * It actually asks SELinux what permissions are allowed on a pair of * the security contexts and object class. It also returns what permissions * should be audited on access violation or allowed. * In most cases, subject's security context (scontext) is a client, and * target security context (tcontext) is a database object. * * The access control decision shall be set on the given av_decision. * The av_decision.allowed has a bitmask of SEPG_<class>__<perms> * to suggest a set of allowed actions in this object class. */ void sepgsql_compute_avd(const char *scontext, const char *tcontext, uint16 tclass, struct av_decision *avd) { const char *tclass_name; security_class_t tclass_ex; struct av_decision avd_ex; int i, deny_unknown = security_deny_unknown(); /* Get external code of the object class*/ Assert(tclass < SEPG_CLASS_MAX); Assert(tclass == selinux_catalog[tclass].class_code); tclass_name = selinux_catalog[tclass].class_name; tclass_ex = string_to_security_class(tclass_name); if (tclass_ex == 0) { /* * If the current security policy does not support permissions * corresponding to database objects, we fill up them with dummy * data. * If security_deny_unknown() returns positive value, undefined * permissions should be denied. Otherwise, allowed */ avd->allowed = (security_deny_unknown() > 0 ? 0 : ~0); avd->auditallow = 0U; avd->auditdeny = ~0U; avd->flags = 0; return; } /* * Ask SELinux what is allowed set of permissions on a pair of the * security contexts and the given object class. */ if (security_compute_av_flags_raw((security_context_t)scontext, (security_context_t)tcontext, tclass_ex, 0, &avd_ex) < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SELinux could not compute av_decision: " "scontext=%s tcontext=%s tclass=%s", scontext, tcontext, tclass_name))); /* * SELinux returns its access control decision as a set of permissions * represented in external code which depends on run-time environment. * So, we need to translate it to the internal representation before * returning results for the caller. */ memset(avd, 0, sizeof(struct av_decision)); for (i=0; selinux_catalog[tclass].av[i].av_name; i++) { access_vector_t av_code_ex; const char *av_name = selinux_catalog[tclass].av[i].av_name; uint32 av_code = selinux_catalog[tclass].av[i].av_code; av_code_ex = string_to_av_perm(tclass_ex, av_name); if (av_code_ex == 0) { /* fill up undefined permissions */ if (!deny_unknown) avd->allowed |= av_code; avd->auditdeny |= av_code; continue; } if (avd_ex.allowed & av_code_ex) avd->allowed |= av_code; if (avd_ex.auditallow & av_code_ex) avd->auditallow |= av_code; if (avd_ex.auditdeny & av_code_ex) avd->auditdeny |= av_code; } return; }