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

📄 acm_ops.c

📁 xen虚拟机源代码安装包
💻 C
字号:
/****************************************************************************** * acm_ops.c * * Copyright (C) 2005 IBM Corporation * * Author: * Reiner Sailer <sailer@watson.ibm.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2 of the * License. * * Process acm command requests from guest OS. */#include <xen/config.h>#include <xen/types.h>#include <xen/lib.h>#include <xen/mm.h>#include <public/xsm/acm.h>#include <public/xsm/acm_ops.h>#include <xen/sched.h>#include <xen/event.h>#include <xen/trace.h>#include <xen/console.h>#include <xen/guest_access.h>#include <xsm/acm/acm_hooks.h>#ifndef ACM_SECURITYlong do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg){    return -ENOSYS;}#elseint acm_authorize_acm_ops(struct domain *d){    /* currently, policy management functions are restricted to privileged domains */    return (IS_PRIV(d) ? 0 : -EPERM);}long do_acm_op(XEN_GUEST_HANDLE(xen_acmctl_t) u_acmctl){    long rc = -EFAULT;    struct xen_acmctl curop, *op = &curop;    if (acm_authorize_acm_ops(current->domain))        return -EPERM;    if ( copy_from_guest(op, u_acmctl, 1) )        return -EFAULT;    if (op->interface_version != ACM_INTERFACE_VERSION)        return -EACCES;    switch ( op->cmd )    {    case ACMOP_setpolicy: {        rc = acm_set_policy(op->u.setpolicy.pushcache,                            op->u.setpolicy.pushcache_size);        break;    }    case ACMOP_getpolicy: {        rc = acm_get_policy(op->u.getpolicy.pullcache,                            op->u.getpolicy.pullcache_size);        break;    }    case ACMOP_dumpstats: {        rc = acm_dump_statistics(op->u.dumpstats.pullcache,                                 op->u.dumpstats.pullcache_size);        break;    }    case ACMOP_getssid: {        ssidref_t ssidref;        if (op->u.getssid.get_ssid_by == ACM_GETBY_ssidref)            ssidref = op->u.getssid.id.ssidref;        else if (op->u.getssid.get_ssid_by == ACM_GETBY_domainid)        {            struct domain *subj = rcu_lock_domain_by_id(op->u.getssid.id.domainid);            if (!subj)            {                rc = -ESRCH; /* domain not found */                break;            }            if (subj->ssid == NULL)            {                rcu_unlock_domain(subj);                rc = -ESRCH;                break;            }            ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;            rcu_unlock_domain(subj);        }        else        {            rc = -ESRCH;            break;        }        rc = acm_get_ssid(ssidref, op->u.getssid.ssidbuf,                          op->u.getssid.ssidbuf_size);        break;    }    case ACMOP_getdecision: {        ssidref_t ssidref1, ssidref2;        if (op->u.getdecision.get_decision_by1 == ACM_GETBY_ssidref)            ssidref1 = op->u.getdecision.id1.ssidref;        else if (op->u.getdecision.get_decision_by1 == ACM_GETBY_domainid)        {            struct domain *subj = rcu_lock_domain_by_id(op->u.getdecision.id1.domainid);            if (!subj)            {                rc = -ESRCH; /* domain not found */                break;            }            if (subj->ssid == NULL)            {                rcu_unlock_domain(subj);                rc = -ESRCH;                break;            }            ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;            rcu_unlock_domain(subj);        }        else        {            rc = -ESRCH;            break;        }        if (op->u.getdecision.get_decision_by2 == ACM_GETBY_ssidref)            ssidref2 = op->u.getdecision.id2.ssidref;        else if (op->u.getdecision.get_decision_by2 == ACM_GETBY_domainid)        {            struct domain *subj = rcu_lock_domain_by_id(op->u.getdecision.id2.domainid);            if (!subj)            {                rc = -ESRCH; /* domain not found */                break;;            }            if (subj->ssid == NULL)            {                rcu_unlock_domain(subj);                rc = -ESRCH;                break;            }            ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;            rcu_unlock_domain(subj);        }        else        {            rc = -ESRCH;            break;        }        rc = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook);        if (rc == ACM_ACCESS_PERMITTED)        {            op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;            rc = 0;        }        else if  (rc == ACM_ACCESS_DENIED)        {            op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;            rc = 0;        }        else            rc = -ESRCH;        if ( (rc == 0) && (copy_to_guest(u_acmctl, op, 1) != 0) )            rc = -EFAULT;        break;    }    case ACMOP_chgpolicy: {        rc = acm_change_policy(&op->u.change_policy);        break;    }    case ACMOP_relabeldoms: {        rc = acm_relabel_domains(&op->u.relabel_doms);        break;    }    default:        rc = -ENOSYS;        break;    }    return rc;}#endif/* * 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 + -