/* ------------------------------------------------------------------------- * * sepgsql_avc_check_valid * * This function checks whether the cached entries are still valid. If * the security policy has been reloaded (or any other events that requires * resetting userspace caches has occurred) since the last reference to * the access vector cache, we must flush the cache. * * Access control decisions must be atomic, but multiple system calls may * be required to make a decision; thus, when referencing the access vector * cache, we must loop until we complete without an intervening cache flush * event. In practice, looping even once should be very rare. Callers should * do something like this: * * sepgsql_avc_check_valid(); * do { * : * <reference to uavc> * : * } while (!sepgsql_avc_check_valid()) * * ------------------------------------------------------------------------- */ static bool sepgsql_avc_check_valid(void) { if (selinux_status_updated() > 0) { sepgsql_avc_reset(); return false; } return true; }
rpmRC rpmtsSELabelInit(rpmts ts, int open_status) { #if WITH_SELINUX const char * path = selinux_file_context_path(); if (ts == NULL || path == NULL) { return RPMRC_FAIL; } if (open_status) { selinux_status_close(); if (selinux_status_open(0) < 0) { return RPMRC_FAIL; } } else if (!selinux_status_updated() && ts->selabelHandle) { return RPMRC_OK; } struct selinux_opt opts[] = { { .type = SELABEL_OPT_PATH, .value = path} };
void dpkg_selabel_load(void) { #ifdef WITH_LIBSELINUX static int selinux_enabled = -1; if (selinux_enabled < 0) { int rc; /* Set selinux_enabled if it is not already set (singleton). */ selinux_enabled = (in_force(FORCE_SECURITY_MAC) && is_selinux_enabled() > 0); if (!selinux_enabled) return; /* Open the SELinux status notification channel, with fallback * enabled for older kernels. */ rc = selinux_status_open(1); if (rc < 0) ohshit(_("cannot open security status notification channel")); /* XXX: We could use selinux_set_callback() to redirect the * errors from the other SELinux calls, but that does not seem * worth it right now. */ } else if (selinux_enabled && selinux_status_updated()) { /* The SELinux policy got updated in the kernel, usually after * upgrading the package shipping it, we need to reload. */ selabel_close(sehandle); } else { /* SELinux is either disabled or it does not need a reload. */ return; } sehandle = selabel_open(SELABEL_CTX_FILE, NULL, 0); if (sehandle == NULL && security_getenforce() == 1) ohshite(_("cannot get security labeling handle")); #endif }
int svcmgr_handler(struct binder_state *bs, struct binder_transaction_data *txn, struct binder_io *msg, struct binder_io *reply) { struct svcinfo *si; uint16_t *s; size_t len; uint32_t handle; uint32_t strict_policy; int allow_isolated; //ALOGI("target=%p code=%d pid=%d uid=%d\n", // (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid); if (txn->target.ptr != BINDER_SERVICE_MANAGER) return -1; if (txn->code == PING_TRANSACTION) return 0; // Equivalent to Parcel::enforceInterface(), reading the RPC // header with the strict mode policy mask and the interface name. // Note that we ignore the strict_policy and don't propagate it // further (since we do no outbound RPCs anyway). strict_policy = bio_get_uint32(msg); s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } if ((len != (sizeof(svcmgr_id) / 2)) || memcmp(svcmgr_id, s, sizeof(svcmgr_id))) { fprintf(stderr,"invalid id %s\n", str8(s, len)); return -1; } if (sehandle && selinux_status_updated() > 0) { struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle(); if (tmp_sehandle) { selabel_close(sehandle); sehandle = tmp_sehandle; } } switch(txn->code) { case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid); if (!handle) break; bio_put_ref(reply, handle); return 0; case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL) { return -1; } handle = bio_get_ref(msg); allow_isolated = bio_get_uint32(msg) ? 1 : 0; if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, txn->sender_pid)) return -1; break; case SVC_MGR_LIST_SERVICES: { uint32_t n = bio_get_uint32(msg); if (!svc_can_list(txn->sender_pid, txn->sender_euid)) { ALOGE("list_service() uid=%d - PERMISSION DENIED\n", txn->sender_euid); return -1; } si = svclist; while ((n-- > 0) && si) si = si->next; if (si) { bio_put_string16(reply, si->name); return 0; } return -1; } default: ALOGE("unknown code %d\n", txn->code); return -1; } bio_put_uint32(reply, 0); return 0; }