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

📄 acm_chinesewall_hooks.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* 3. now re-calculate the state for the new policy based on     *    running domains; this can fail if new policy is conflicting     *    with running domains     */    if ( chwall_init_state(chwall_buf, ssids,                           conflict_sets, running_types,                           conflict_aggregate_set,                           errors))    {        printk("%s: New policy conflicts with running domains. Policy load aborted.\n",               __func__);        goto error_free;        /* new policy conflicts with running domains */    }    /* if this was only a test run, exit with ACM_OK */    if ( test_only )    {        rc = ACM_OK;        goto error_free;    }    /* 4. free old policy buffers, replace with new ones */    chwall_bin_pol.max_types = chwall_buf->chwall_max_types;    chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs;    chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets;    xfree(chwall_bin_pol.ssidrefs);    xfree(chwall_bin_pol.conflict_aggregate_set);    xfree(chwall_bin_pol.running_types);    xfree(chwall_bin_pol.conflict_sets);    chwall_bin_pol.ssidrefs = ssids;    chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set;    chwall_bin_pol.running_types = running_types;    chwall_bin_pol.conflict_sets = conflict_sets;    return ACM_OK; error_free:    if ( !test_only )        printk("%s: ERROR setting policy.\n", __func__);    xfree(ssids);    xfree(conflict_sets);    xfree(running_types);    xfree(conflict_aggregate_set);    return rc;}/* * This function MUST be called before the chwall_ste_policy function! */static int chwall_test_policy(u8 *buf, u32 buf_size, int is_bootpolicy,                              struct acm_sized_buffer *errors){    struct acm_chwall_policy_buffer *chwall_buf =        (struct acm_chwall_policy_buffer *) buf;    if ( buf_size < sizeof(struct acm_chwall_policy_buffer) )        return -EINVAL;    /* rewrite the policy due to endianess */    chwall_buf->policy_code = be32_to_cpu(chwall_buf->policy_code);    chwall_buf->policy_version = be32_to_cpu(chwall_buf->policy_version);    chwall_buf->chwall_max_types =        be32_to_cpu(chwall_buf->chwall_max_types);    chwall_buf->chwall_max_ssidrefs =        be32_to_cpu(chwall_buf->chwall_max_ssidrefs);    chwall_buf->chwall_max_conflictsets =        be32_to_cpu(chwall_buf->chwall_max_conflictsets);    chwall_buf->chwall_ssid_offset =        be32_to_cpu(chwall_buf->chwall_ssid_offset);    chwall_buf->chwall_conflict_sets_offset =        be32_to_cpu(chwall_buf->chwall_conflict_sets_offset);    chwall_buf->chwall_running_types_offset =        be32_to_cpu(chwall_buf->chwall_running_types_offset);    chwall_buf->chwall_conflict_aggregate_offset =        be32_to_cpu(chwall_buf->chwall_conflict_aggregate_offset);    /* policy type and version checks */    if ( (chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) ||         (chwall_buf->policy_version != ACM_CHWALL_VERSION) )        return -EINVAL;    /* during boot dom0_chwall_ssidref is set */    if ( is_bootpolicy &&         (dom0_chwall_ssidref >= chwall_buf->chwall_max_ssidrefs) )        return -EINVAL;    return _chwall_update_policy(buf, buf_size, 1, errors);}static int chwall_set_policy(u8 *buf, u32 buf_size){    return _chwall_update_policy(buf, buf_size, 0, NULL);}static int chwall_dump_stats(u8 * buf, u16 len){    /* no stats for Chinese Wall Policy */    return 0;}static int chwall_dump_ssid_types(ssidref_t ssidref, u8 * buf, u16 len){    int i;    /* fill in buffer */    if ( chwall_bin_pol.max_types > len )        return -EFAULT;    if ( ssidref >= chwall_bin_pol.max_ssidrefs )        return -EFAULT;    /* read types for chwall ssidref */    for ( i = 0; i < chwall_bin_pol.max_types; i++ )    {        if ( chwall_bin_pol.             ssidrefs[ssidref * chwall_bin_pol.max_types + i] )            buf[i] = 1;        else            buf[i] = 0;    }    return chwall_bin_pol.max_types;}/*************************** * Authorization functions ***************************//* -------- DOMAIN OPERATION HOOKS -----------*/static int _chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref){    ssidref_t chwall_ssidref;    int i, j;    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);    if ( chwall_ssidref >= chwall_bin_pol.max_ssidrefs )    {        printk("%s: ERROR chwall_ssidref > max(%x).\n",               __func__, chwall_bin_pol.max_ssidrefs - 1);        return ACM_ACCESS_DENIED;    }    /* A: chinese wall check for conflicts */    for ( i = 0; i < chwall_bin_pol.max_types; i++ )        if ( chwall_bin_pol.conflict_aggregate_set[i] &&             chwall_bin_pol.ssidrefs[chwall_ssidref *                                     chwall_bin_pol.max_types + i] )        {            printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i);            return ACM_ACCESS_DENIED;        }    /* B: chinese wall conflict set adjustment (so that other     *    other domains simultaneously created are evaluated against     *    this new set)     */    for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )    {        int common = 0;        /* check if conflict_set_i and ssidref have common types */        for ( j = 0; j < chwall_bin_pol.max_types; j++ )            if ( chwall_bin_pol.                 conflict_sets[i * chwall_bin_pol.max_types + j]                 && chwall_bin_pol.ssidrefs[chwall_ssidref *                                            chwall_bin_pol.max_types + j] )            {                common = 1;                break;            }        if ( common == 0 )            continue;           /* try next conflict set */        /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */        for ( j = 0; j < chwall_bin_pol.max_types; j++ )            if ( chwall_bin_pol.                 conflict_sets[i * chwall_bin_pol.max_types + j]                 && !chwall_bin_pol.ssidrefs[chwall_ssidref *                                             chwall_bin_pol.max_types + j])                 chwall_bin_pol.conflict_aggregate_set[j]++;    }    return ACM_ACCESS_PERMITTED;}static void _chwall_post_domain_create(domid_t domid, ssidref_t ssidref){    int i;    ssidref_t chwall_ssidref;    chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref);    /* adjust types ref-count for running domains */    for ( i = 0; i < chwall_bin_pol.max_types; i++ )        chwall_bin_pol.running_types[i] +=            chwall_bin_pol.ssidrefs[chwall_ssidref *                                   chwall_bin_pol.max_types + i];}/* * To be called when creating a domain. If this call is unsuccessful, * no state changes have occurred (adjustments of counters etc.). If it * was successful, state was changed and can be undone using * chwall_domain_destroy. */static int chwall_domain_create(void *subject_ssid, ssidref_t ssidref,                                domid_t domid){    int rc;    read_lock(&acm_bin_pol_rwlock);    rc = _chwall_pre_domain_create(subject_ssid, ssidref);    if ( rc == ACM_ACCESS_PERMITTED )        _chwall_post_domain_create(domid, ssidref);    read_unlock(&acm_bin_pol_rwlock);    return rc;}/* * This function undoes everything a successful call to * chwall_domain_create has done. */static void chwall_domain_destroy(void *object_ssid, struct domain *d){    int i, j;    struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY,                                                 (struct acm_ssid_domain *)                                                 object_ssid);    ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref;    read_lock(&acm_bin_pol_rwlock);    /* adjust running types set */    for ( i = 0; i < chwall_bin_pol.max_types; i++ )        chwall_bin_pol.running_types[i] -=            chwall_bin_pol.ssidrefs[chwall_ssidref *                                   chwall_bin_pol.max_types + i];    /* roll-back: re-adjust conflicting types aggregate */    for ( i = 0; i < chwall_bin_pol.max_conflictsets; i++ )    {        int common = 0;        /* check if conflict_set_i and ssidref have common types */        for ( j = 0; j < chwall_bin_pol.max_types; j++ )            if ( chwall_bin_pol.conflict_sets[i * chwall_bin_pol.max_types + j]                 && chwall_bin_pol.ssidrefs[chwall_ssidref *                                            chwall_bin_pol.max_types + j])            {                common = 1;                break;            }        if ( common == 0 )        {            /* try next conflict set, this one does not include               any type of chwall_ssidref */            continue;        }        /* now add types of the conflict set to conflict_aggregate_set           (except types in chwall_ssidref) */        for ( j = 0; j < chwall_bin_pol.max_types; j++ )            if ( chwall_bin_pol.                 conflict_sets[i * chwall_bin_pol.max_types + j]                 && !chwall_bin_pol.ssidrefs[chwall_ssidref *                                             chwall_bin_pol.max_types + j])                chwall_bin_pol.conflict_aggregate_set[j]--;    }    read_unlock(&acm_bin_pol_rwlock);    return;}static int chwall_is_default_policy(void){    static const domaintype_t def_policy[2] = { 0x0, 0x0 };    return ( ( chwall_bin_pol.max_types    == 1 ) &&             ( chwall_bin_pol.max_ssidrefs == 2 ) &&             ( memcmp(chwall_bin_pol.ssidrefs,                      def_policy,                      sizeof(def_policy)) == 0 ) );}static int chwall_is_in_conflictset(ssidref_t ssidref1){    /* is ssidref1 in conflict with any running domains ? */    int rc = 0;    int i, j;    ssidref_t ssid_chwall;    read_lock(&acm_bin_pol_rwlock);    ssid_chwall = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref1);    if ( ssid_chwall >= 0 && ssid_chwall < chwall_bin_pol.max_ssidrefs ) {        for ( i = 0; i < chwall_bin_pol.max_conflictsets && rc == 0; i++ ) {            for ( j = 0; j < chwall_bin_pol.max_types; j++ ) {                if ( chwall_bin_pol.conflict_aggregate_set                                 [i * chwall_bin_pol.max_types + j] &&                     chwall_bin_pol.ssidrefs                                 [ssid_chwall * chwall_bin_pol.max_types + j])                {                    rc = 1;                    break;                }            }        }    } else {        rc = 1;    }    read_unlock(&acm_bin_pol_rwlock);    return rc;}struct acm_operations acm_chinesewall_ops = {    /* policy management services */    .init_domain_ssid = chwall_init_domain_ssid,    .free_domain_ssid = chwall_free_domain_ssid,    .dump_binary_policy = chwall_dump_policy,    .test_binary_policy = chwall_test_policy,    .set_binary_policy = chwall_set_policy,    .dump_statistics = chwall_dump_stats,    .dump_ssid_types = chwall_dump_ssid_types,    /* domain management control hooks */    .domain_create = chwall_domain_create,    .domain_destroy = chwall_domain_destroy,    /* event channel control hooks */    .pre_eventchannel_unbound = NULL,    .fail_eventchannel_unbound = NULL,    .pre_eventchannel_interdomain = NULL,    .fail_eventchannel_interdomain = NULL,    /* grant table control hooks */    .pre_grant_map_ref = NULL,    .fail_grant_map_ref = NULL,    .pre_grant_setup = NULL,    .fail_grant_setup = NULL,    /* generic domain-requested decision hooks */    .sharing = NULL,    .authorization = NULL,    .conflictset = chwall_is_in_conflictset,    .is_default_policy = chwall_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 + -