static int ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset) { PrivateRec **privPtr = &client->devPrivates; security_id_t *pSid; security_context_t ctx = NULL; char *ptr; int rc; REQUEST(SELinuxSetCreateContextReq); REQUEST_FIXED_SIZE(SELinuxSetCreateContextReq, stuff->context_len); if (stuff->context_len > 0) { ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len); if (!ctx) return BadAlloc; } ptr = dixLookupPrivate(privPtr, subjectKey); pSid = (security_id_t *)(ptr + offset); *pSid = NULL; rc = Success; if (stuff->context_len > 0) { if (security_check_context_raw(ctx) < 0 || avc_context_to_sid_raw(ctx, pSid) < 0) rc = BadValue; } free(ctx); return rc; }
/* * Looks up a name in the selection or property mappings */ static int SELinuxAtomToSIDLookup(Atom atom, SELinuxObjectRec * obj, int map, int polymap) { const char *name = NameForAtom(atom); security_context_t ctx; int rc = Success; obj->poly = 1; /* Look in the mappings of names to contexts */ if (selabel_lookup_raw(label_hnd, &ctx, name, map) == 0) { obj->poly = 0; } else if (errno != ENOENT) { ErrorF("SELinux: a property label lookup failed!\n"); return BadValue; } else if (selabel_lookup_raw(label_hnd, &ctx, name, polymap) < 0) { ErrorF("SELinux: a property label lookup failed!\n"); return BadValue; } /* Get a SID for context */ if (avc_context_to_sid_raw(ctx, &obj->sid) < 0) { ErrorF("SELinux: a context_to_SID_raw call failed!\n"); rc = BadAlloc; } freecon(ctx); return rc; }
int SELinuxExtensionToSID(const char *name, security_id_t * sid_rtn) { security_context_t ctx; /* Look in the mappings of extension names to contexts */ if (selabel_lookup_raw(label_hnd, &ctx, name, SELABEL_X_EXT) < 0) { ErrorF("SELinux: a property label lookup failed!\n"); return BadValue; } /* Get a SID for context */ if (avc_context_to_sid_raw(ctx, sid_rtn) < 0) { ErrorF("SELinux: a context_to_SID_raw call failed!\n"); freecon(ctx); return BadAlloc; } freecon(ctx); return Success; }
static int ProcSELinuxSetDeviceContext(ClientPtr client) { security_context_t ctx; security_id_t sid; DeviceIntPtr dev; SELinuxSubjectRec *subj; SELinuxObjectRec *obj; int rc; REQUEST(SELinuxSetContextReq); REQUEST_FIXED_SIZE(SELinuxSetContextReq, stuff->context_len); if (stuff->context_len < 1) return BadLength; ctx = SELinuxCopyContext((char *)(stuff + 1), stuff->context_len); if (!ctx) return BadAlloc; rc = dixLookupDevice(&dev, stuff->id, client, DixManageAccess); if (rc != Success) goto out; if (security_check_context_raw(ctx) < 0 || avc_context_to_sid_raw(ctx, &sid) < 0) { rc = BadValue; goto out; } subj = dixLookupPrivate(&dev->devPrivates, subjectKey); subj->sid = sid; obj = dixLookupPrivate(&dev->devPrivates, objectKey); obj->sid = sid; rc = Success; out: free(ctx); return rc; }
/* * 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; }