/* * Looks up a SID for a property/subject pair */ int SELinuxPropertyToSID(Atom property, SELinuxSubjectRec * subj, security_id_t * sid_rtn, int *poly_rtn) { int rc; SELinuxObjectRec *obj; security_id_t tsid, tsid2; /* Get the default context and polyinstantiation bit */ rc = SELinuxAtomToSID(property, 1, &obj); if (rc != Success) return rc; /* Check for an override context next */ if (subj->prp_use_sid) { tsid = subj->prp_use_sid; goto out; } /* Perform a transition */ if (avc_compute_create(subj->sid, obj->sid, SECCLASS_X_PROPERTY, &tsid) < 0) { ErrorF("SELinux: a compute_create call failed!\n"); return BadValue; } /* Polyinstantiate if necessary to obtain the final SID */ if (obj->poly) { tsid2 = tsid; if (avc_compute_member(subj->sid, tsid2, SECCLASS_X_PROPERTY, &tsid) < 0) { ErrorF("SELinux: a compute_member call failed!\n"); return BadValue; } } out: *sid_rtn = tsid; if (poly_rtn) *poly_rtn = obj->poly; return Success; }
/* * Looks up the SID corresponding to the given event type */ int SELinuxEventToSID(unsigned type, security_id_t sid_of_window, SELinuxObjectRec * sid_return) { const char *name = LookupEventName(type); security_id_t sid; security_context_t ctx; type &= 127; sid = SELinuxArrayGet(&arr_events, type); if (!sid) { /* Look in the mappings of event names to contexts */ if (selabel_lookup_raw(label_hnd, &ctx, name, SELABEL_X_EVENT) < 0) { ErrorF("SELinux: an event label lookup failed!\n"); return BadValue; } /* Get a SID for context */ if (avc_context_to_sid_raw(ctx, &sid) < 0) { ErrorF("SELinux: a context_to_SID_raw call failed!\n"); freecon(ctx); return BadAlloc; } freecon(ctx); /* Cache the SID value */ if (!SELinuxArraySet(&arr_events, type, sid)) return BadAlloc; } /* Perform a transition to obtain the final SID */ if (avc_compute_create(sid_of_window, sid, SECCLASS_X_EVENT, &sid_return->sid) < 0) { ErrorF("SELinux: a compute_create call failed!\n"); return BadValue; } return Success; }
uint32_t mselinux_check_alloc(selinux_engine_t *se, const void *cookie, const void *key, size_t keylen) { static security_id_t tsid = NULL; mcache_t *mcache; security_id_t ssid; security_id_t nsid; uint32_t secid; if (!se->config.selinux) return 0; if (!tsid) { security_context_t context; if (getcon_raw(&context) < 0) return 0; if (avc_context_to_sid_raw(context, &tsid) < 0) { freecon(context); return 0; } freecon(context); } /* * It the new allocation tries to replace an existing key, * we copy security id from the older chunk. */ mcache = mcache_get(se, key, keylen); if (mcache) { secid = mcache->mchunk->item.secid; if (secid > 0) { mchunk_t *lchunk = mlabel_lookup_secid(se, secid); if (!lchunk) secid = 0; else lchunk->label.refcount++; } mcache_put(se, mcache); return secid; } ssid = se->server.core->get_engine_specific(cookie); pthread_rwlock_rdlock(&permissions.lock); avc_compute_create(ssid, tsid, permissions.tclass, &nsid); pthread_rwlock_unlock(&permissions.lock); secid = mlabel_get(se, nsid->ctx); if (se->config.debug) fprintf(stderr, "%s: ssid=%s tsid=%s nsid=%s (secid=%u)\n", __FUNCTION__, ssid->ctx, tsid->ctx, nsid->ctx, secid); return secid; }