⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 acm_simple_type_enforcement_hooks.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
    ste_buf->policy_code = be32_to_cpu(ste_buf->policy_code);    ste_buf->policy_version = be32_to_cpu(ste_buf->policy_version);    ste_buf->ste_max_types = be32_to_cpu(ste_buf->ste_max_types);    ste_buf->ste_max_ssidrefs = be32_to_cpu(ste_buf->ste_max_ssidrefs);    ste_buf->ste_ssid_offset = be32_to_cpu(ste_buf->ste_ssid_offset);    /* policy type and version checks */    if ( (ste_buf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ||         (ste_buf->policy_version != ACM_STE_VERSION) )        return -EINVAL;    /* during boot dom0_chwall_ssidref is set */    if ( is_bootpolicy && (dom0_ste_ssidref >= ste_buf->ste_max_ssidrefs) )        return -EINVAL;    return _ste_update_policy(buf, buf_size, 1, errors);}static intste_set_policy(u8 *buf, u32 buf_size){    return _ste_update_policy(buf, buf_size, 0, NULL);}static int ste_dump_stats(u8 *buf, u16 buf_len){    struct acm_ste_stats_buffer stats;    /* now send the hook counts to user space */    stats.ec_eval_count =                    cpu_to_be32(atomic_read(&ste_bin_pol.ec_eval_count));    stats.gt_eval_count =                    cpu_to_be32(atomic_read(&ste_bin_pol.gt_eval_count));    stats.ec_denied_count =                    cpu_to_be32(atomic_read(&ste_bin_pol.ec_denied_count));    stats.gt_denied_count =                    cpu_to_be32(atomic_read(&ste_bin_pol.gt_denied_count));    stats.ec_cachehit_count =                    cpu_to_be32(atomic_read(&ste_bin_pol.ec_cachehit_count));    stats.gt_cachehit_count =                    cpu_to_be32(atomic_read(&ste_bin_pol.gt_cachehit_count));    if ( buf_len < sizeof(struct acm_ste_stats_buffer) )        return -ENOMEM;    memcpy(buf, &stats, sizeof(struct acm_ste_stats_buffer));    return sizeof(struct acm_ste_stats_buffer);}static intste_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len){    int i;    /* fill in buffer */    if ( ste_bin_pol.max_types > len )        return -EFAULT;    if ( ssidref >= ste_bin_pol.max_ssidrefs )        return -EFAULT;    /* read types for chwall ssidref */    for( i = 0; i< ste_bin_pol.max_types; i++ )    {        if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i])            buf[i] = 1;        else            buf[i] = 0;    }    return ste_bin_pol.max_types;}/* we need to go through this before calling the hooks, * returns 1 == cache hit */static int inlinecheck_cache(struct domain *dom, domid_t rdom){    struct ste_ssid *ste_ssid;    int i;    printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom);    if (dom->ssid == NULL)        return 0;    ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,                          (struct acm_ssid_domain *)(dom->ssid));    for( i = 0; i < ACM_TE_CACHE_SIZE; i++ )    {        if ( (ste_ssid->ste_cache[i].valid == ACM_STE_valid) &&             (ste_ssid->ste_cache[i].id == rdom) )        {            printkd("cache hit (entry %x, id= %x!\n",                    i,                    ste_ssid->ste_cache[i].id);            return 1;        }    }    return 0;}/* we only get here if there is NO entry yet; no duplication check! */static void inlinecache_result(struct domain *subj, struct domain *obj) {    struct ste_ssid *ste_ssid;    int i;    printkd("caching from doms: %x --> %x.\n",            subj->domain_id, obj->domain_id);    if ( subj->ssid == NULL )        return;    ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY,                          (struct acm_ssid_domain *)(subj)->ssid);    for( i = 0; i < ACM_TE_CACHE_SIZE; i++ )        if ( ste_ssid->ste_cache[i].valid == ACM_STE_free )            break;    if ( i < ACM_TE_CACHE_SIZE )    {        ste_ssid->ste_cache[i].valid = ACM_STE_valid;        ste_ssid->ste_cache[i].id = obj->domain_id;    } else        printk ("Cache of dom %x is full!\n", subj->domain_id);}/* deletes entries for domain 'id' from all caches (re-use) */static void inlineclean_id_from_cache(domid_t id) {    struct ste_ssid *ste_ssid;    int i;    struct acm_ssid_domain *rawssid;    printkd("deleting cache for dom %x.\n", id);    read_lock(&ssid_list_rwlock);    /* look through caches of all domains */    for_each_acmssid ( rawssid )    {        ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, rawssid);        if ( !ste_ssid )        {            printk("%s: deleting ID from cache ERROR (no ste_ssid)!\n",                   __func__);            goto out;        }        for ( i = 0; i < ACM_TE_CACHE_SIZE; i++ )            if ( (ste_ssid->ste_cache[i].valid == ACM_STE_valid) &&                 (ste_ssid->ste_cache[i].id == id) )                ste_ssid->ste_cache[i].valid = ACM_STE_free;    } out:    read_unlock(&ssid_list_rwlock);}/*************************** * Authorization functions **************************/static int ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref){          /* check for ssidref in range for policy */    ssidref_t ste_ssidref;    traceprintk("%s.\n", __func__);    read_lock(&acm_bin_pol_rwlock);    ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref);    if ( ste_ssidref >= ste_bin_pol.max_ssidrefs )    {        printk("%s: ERROR ste_ssidref > max(%x).\n",                __func__, ste_bin_pol.max_ssidrefs-1);        read_unlock(&acm_bin_pol_rwlock);        return ACM_ACCESS_DENIED;    }    read_unlock(&acm_bin_pol_rwlock);    return ACM_ACCESS_PERMITTED;}static intste_domain_create(void *subject_ssid, ssidref_t ssidref, domid_t  domid){    return ste_pre_domain_create(subject_ssid, ssidref);}static void ste_domain_destroy(void *subject_ssid, struct domain *d){    /* clean all cache entries for destroyed domain (might be re-used) */    clean_id_from_cache(d->domain_id);}/* -------- EVENTCHANNEL OPERATIONS -----------*/static intste_pre_eventchannel_unbound(domid_t id1, domid_t id2) {    struct domain *subj, *obj;    int ret;    traceprintk("%s: dom%x-->dom%x.\n", __func__,                (id1 == DOMID_SELF) ? current->domain->domain_id : id1,                (id2 == DOMID_SELF) ? current->domain->domain_id : id2);    if ( id1 == DOMID_SELF )        id1 = current->domain->domain_id;    if ( id2 == DOMID_SELF )        id2 = current->domain->domain_id;    subj = rcu_lock_domain_by_id(id1);    obj  = rcu_lock_domain_by_id(id2);    if ( (subj == NULL) || (obj == NULL) )    {        ret = ACM_ACCESS_DENIED;        goto out;    }    /* cache check late */    if ( check_cache(subj, obj->domain_id) )    {        atomic_inc(&ste_bin_pol.ec_cachehit_count);        ret = ACM_ACCESS_PERMITTED;        goto out;    }    atomic_inc(&ste_bin_pol.ec_eval_count);    if ( share_common_type(subj, obj) )    {        cache_result(subj, obj);        ret = ACM_ACCESS_PERMITTED;    }    else    {        atomic_inc(&ste_bin_pol.ec_denied_count);        ret = ACM_ACCESS_DENIED;    }  out:    if ( obj != NULL )        rcu_unlock_domain(obj);    if ( subj != NULL )        rcu_unlock_domain(subj);    return ret;}static intste_pre_eventchannel_interdomain(domid_t id){    struct domain *subj=NULL, *obj=NULL;    int ret;    traceprintk("%s: dom%x-->dom%x.\n", __func__,                current->domain->domain_id,                (id == DOMID_SELF) ? current->domain->domain_id : id);    /* following is a bit longer but ensures that we     * "put" only domains that we where "find"-ing      */    if ( id == DOMID_SELF )        id = current->domain->domain_id;    subj = current->domain;    obj  = rcu_lock_domain_by_id(id);    if ( obj == NULL )    {        ret = ACM_ACCESS_DENIED;        goto out;    }    /* cache check late, but evtchn is not on performance critical path */    if ( check_cache(subj, obj->domain_id) )    {        atomic_inc(&ste_bin_pol.ec_cachehit_count);        ret = ACM_ACCESS_PERMITTED;        goto out;    }    atomic_inc(&ste_bin_pol.ec_eval_count);    if ( share_common_type(subj, obj) )    {        cache_result(subj, obj);        ret = ACM_ACCESS_PERMITTED;    }    else    {        atomic_inc(&ste_bin_pol.ec_denied_count);        ret = ACM_ACCESS_DENIED;    } out:    if ( obj != NULL )        rcu_unlock_domain(obj);    return ret;}/* -------- SHARED MEMORY OPERATIONS -----------*/static intste_pre_grant_map_ref (domid_t id){    struct domain *obj, *subj;    int ret;    traceprintk("%s: dom%x-->dom%x.\n", __func__,                current->domain->domain_id, id);    if ( check_cache(current->domain, id) )    {        atomic_inc(&ste_bin_pol.gt_cachehit_count);        return ACM_ACCESS_PERMITTED;    }    atomic_inc(&ste_bin_pol.gt_eval_count);    subj = current->domain;    obj = rcu_lock_domain_by_id(id);    if ( share_common_type(subj, obj) )    {        cache_result(subj, obj);        ret = ACM_ACCESS_PERMITTED;    }    else    {        atomic_inc(&ste_bin_pol.gt_denied_count);        printkd("%s: ACCESS DENIED!\n", __func__);        ret = ACM_ACCESS_DENIED;    }    if ( obj != NULL )        rcu_unlock_domain(obj);    return ret;}/* since setting up grant tables involves some implicit information   flow from the creating domain to the domain that is setup, we    check types in addition to the general authorization */static intste_pre_grant_setup (domid_t id){    struct domain *obj, *subj;    int ret;    traceprintk("%s: dom%x-->dom%x.\n", __func__,                current->domain->domain_id, id);    if ( check_cache(current->domain, id) )    {        atomic_inc(&ste_bin_pol.gt_cachehit_count);        return ACM_ACCESS_PERMITTED;    }    atomic_inc(&ste_bin_pol.gt_eval_count);    subj = current->domain;    obj = rcu_lock_domain_by_id(id);    /* a) check authorization (eventually use specific capabilities) */    if ( obj && !IS_PRIV_FOR(current->domain, obj) )    {        printk("%s: Grant table management authorization denied ERROR!\n",               __func__);        rcu_unlock_domain(obj);        return ACM_ACCESS_DENIED;    }    /* b) check types */    if ( share_common_type(subj, obj) )    {        cache_result(subj, obj);        ret = ACM_ACCESS_PERMITTED;    }    else    {        atomic_inc(&ste_bin_pol.gt_denied_count);        ret = ACM_ACCESS_DENIED;    }    if ( obj != NULL )        rcu_unlock_domain(obj);    return ret;}/* -------- DOMAIN-Requested Decision hooks -----------*/static intste_sharing(ssidref_t ssidref1, ssidref_t ssidref2){    int hct = have_common_type(        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1),        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2));    return (hct ? ACM_ACCESS_PERMITTED : ACM_ACCESS_DENIED);}static intste_authorization(ssidref_t ssidref1, ssidref_t ssidref2){    int iss = is_superset(        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1),        GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2));    return (iss ? ACM_ACCESS_PERMITTED : ACM_ACCESS_DENIED);}static intste_is_default_policy(void){    const static domaintype_t def_policy[4] = { 0x0, 0x1, 0x1, 0x1};    return ((ste_bin_pol.max_types    == 2) &&            (ste_bin_pol.max_ssidrefs == 2) &&            (memcmp(ste_bin_pol.ssidrefs,                    def_policy,                    sizeof(def_policy)) == 0));}/* now define the hook structure similarly to LSM */struct acm_operations acm_simple_type_enforcement_ops = {    /* policy management services */    .init_domain_ssid       = ste_init_domain_ssid,    .free_domain_ssid       = ste_free_domain_ssid,    .dump_binary_policy     = ste_dump_policy,    .test_binary_policy     = ste_test_policy,    .set_binary_policy      = ste_set_policy,    .dump_statistics        = ste_dump_stats,    .dump_ssid_types        = ste_dump_ssid_types,    /* domain management control hooks */    .domain_create          = ste_domain_create,    .domain_destroy         = ste_domain_destroy,    /* event channel control hooks */    .pre_eventchannel_unbound = ste_pre_eventchannel_unbound,    .fail_eventchannel_unbound = NULL,    .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain,    .fail_eventchannel_interdomain = NULL,    /* grant table control hooks */    .pre_grant_map_ref      = ste_pre_grant_map_ref,    .fail_grant_map_ref     = NULL,    .pre_grant_setup        = ste_pre_grant_setup,    .fail_grant_setup       = NULL,    /* generic domain-requested decision hooks */    .sharing                = ste_sharing,    .authorization          = ste_authorization,    .conflictset            = NULL,    .is_default_policy      = ste_is_default_policy,};/* * Local variables: * mode: C * c-set-style: "BSD" * c-basic-offset: 4 * tab-width: 4 * indent-tabs-mode: nil * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -