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

📄 hooks.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
 /* *  This file contains the Flask hook function implementations for Xen. * *  Author:  George Coker, <gscoker@alpha.ncsc.mil> * *    This program is free software; you can redistribute it and/or modify *    it under the terms of the GNU General Public License version 2, *      as published by the Free Software Foundation. */#include <xen/init.h>#include <xen/lib.h>#include <xen/sched.h>#include <xen/xmalloc.h>#include <xsm/xsm.h>#include <xen/spinlock.h>#include <xen/cpumask.h>#include <xen/errno.h>#include <xen/guest_access.h>#include <public/xen.h>#include <public/physdev.h>#include <public/platform.h>#include <public/xsm/flask_op.h>#include <avc.h>#include <avc_ss.h>#include <objsec.h>#include <conditional.h>struct xsm_operations *original_ops = NULL;static int domain_has_perm(struct domain *dom1, struct domain *dom2,                                                         u16 class, u32 perms){    struct domain_security_struct *dsec1, *dsec2;    dsec1 = dom1->ssid;    dsec2 = dom2->ssid;    return avc_has_perm(dsec1->sid, dsec2->sid, class, perms, NULL);}static int domain_has_evtchn(struct domain *d, struct evtchn *chn, u32 perms){    struct domain_security_struct *dsec;    struct evtchn_security_struct *esec;    dsec = d->ssid;    esec = chn->ssid;    return avc_has_perm(dsec->sid, esec->sid, SECCLASS_EVENT, perms, NULL);}static int domain_has_xen(struct domain *d, u32 perms){    struct domain_security_struct *dsec;    dsec = d->ssid;    return avc_has_perm(dsec->sid, SECINITSID_XEN, SECCLASS_XEN, perms, NULL);}static int flask_domain_alloc_security(struct domain *d){    struct domain_security_struct *dsec;    dsec = xmalloc(struct domain_security_struct);    if ( !dsec )        return -ENOMEM;    memset(dsec, 0, sizeof(struct domain_security_struct));    dsec->d = d;    if ( d->domain_id == IDLE_DOMAIN_ID )    {        dsec->sid = SECINITSID_XEN;        dsec->create_sid = SECINITSID_DOM0;    }    else    {        dsec->sid = SECINITSID_UNLABELED;        dsec->create_sid = SECSID_NULL;    }    d->ssid = dsec;    return 0;}static void flask_domain_free_security(struct domain *d){    struct domain_security_struct *dsec = d->ssid;    if ( !dsec )        return;    d->ssid = NULL;    xfree(dsec);}static int flask_evtchn_unbound(struct domain *d1, struct evtchn *chn,                                                                     domid_t id2){    u32 newsid;    int rc;    domid_t id;    struct domain *d2;    struct domain_security_struct *dsec, *dsec1, *dsec2;    struct evtchn_security_struct *esec;    dsec = current->domain->ssid;    dsec1 = d1->ssid;    esec = chn->ssid;    if ( id2 == DOMID_SELF )        id = current->domain->domain_id;    else        id = id2;    d2 = get_domain_by_id(id);    if ( d2 == NULL )        return -EPERM;    dsec2 = d2->ssid;    rc = security_transition_sid(dsec1->sid, dsec2->sid, SECCLASS_EVENT,                                                                     &newsid);    if ( rc )        goto out;    rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT,                                            EVENT__CREATE|EVENT__ALLOC, NULL);    if ( rc )        goto out;    rc = avc_has_perm(newsid, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, NULL);    if ( rc )        goto out;    else        esec->sid = newsid;out:    put_domain(d2);    return rc;}static int flask_evtchn_interdomain(struct domain *d1, struct evtchn *chn1,                                         struct domain *d2, struct evtchn *chn2){    u32 newsid1;    u32 newsid2;    int rc;    struct domain_security_struct *dsec1, *dsec2;    struct evtchn_security_struct *esec1, *esec2;    dsec1 = d1->ssid;    dsec2 = d2->ssid;    esec1 = chn1->ssid;    esec2 = chn2->ssid;    rc = security_transition_sid(dsec1->sid, dsec2->sid,                                         SECCLASS_EVENT, &newsid1);    if ( rc )    {        printk("%s: security_transition_sid failed, rc=%d (domain=%d)\n",                                            __FUNCTION__, -rc, d2->domain_id);        return rc;    }    rc = avc_has_perm(dsec1->sid, newsid1, SECCLASS_EVENT, EVENT__CREATE, NULL);    if ( rc )        return rc;    rc = security_transition_sid(dsec2->sid, dsec1->sid,                                         SECCLASS_EVENT, &newsid2);    if ( rc )    {        printk("%s: security_transition_sid failed, rc=%d (domain=%d)\n",                                            __FUNCTION__, -rc, d1->domain_id);        return rc;    }    rc = avc_has_perm(dsec2->sid, newsid2, SECCLASS_EVENT, EVENT__CREATE, NULL);    if ( rc )        return rc;    rc = avc_has_perm(newsid1, dsec2->sid, SECCLASS_EVENT, EVENT__BIND, NULL);    if ( rc )        return rc;    rc = avc_has_perm(newsid2, dsec1->sid, SECCLASS_EVENT, EVENT__BIND, NULL);    if ( rc )        return rc;        esec1->sid = newsid1;    esec2->sid = newsid2;    return rc;}static void flask_evtchn_close_post(struct evtchn *chn){    struct evtchn_security_struct *esec;    esec = chn->ssid;    esec->sid = SECINITSID_UNLABELED;}static int flask_evtchn_send(struct domain *d, struct evtchn *chn){    return domain_has_evtchn(d, chn, EVENT__SEND);}static int flask_evtchn_status(struct domain *d, struct evtchn *chn){    return domain_has_evtchn(d, chn, EVENT__STATUS);}static int flask_evtchn_reset(struct domain *d1, struct domain *d2){    return domain_has_perm(d1, d2, SECCLASS_EVENT, EVENT__RESET);}static int flask_alloc_security_evtchn(struct evtchn *chn){    struct evtchn_security_struct *esec;    esec = xmalloc(struct evtchn_security_struct);    if ( !esec )        return -ENOMEM;    memset(esec, 0, sizeof(struct evtchn_security_struct));    esec->chn = chn;    esec->sid = SECINITSID_UNLABELED;    chn->ssid = esec;    return 0;    }static void flask_free_security_evtchn(struct evtchn *chn){    struct evtchn_security_struct *esec;    if ( !chn )        return;    esec = chn->ssid;    if ( !esec )        return;    chn->ssid = NULL;    xfree(esec);}static int flask_grant_mapref(struct domain *d1, struct domain *d2,                                                                 uint32_t flags){    u32 perms = GRANT__MAP_READ;    if ( flags & GTF_writing )        perms |= GRANT__MAP_WRITE;    return domain_has_perm(d1, d2, SECCLASS_GRANT, perms);}static int flask_grant_unmapref(struct domain *d1, struct domain *d2){    return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__UNMAP);}static int flask_grant_setup(struct domain *d1, struct domain *d2){    return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__SETUP);}static int flask_grant_transfer(struct domain *d1, struct domain *d2){    return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__TRANSFER);}static int flask_grant_copy(struct domain *d1, struct domain *d2){    return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__COPY);}static int flask_grant_query_size(struct domain *d1, struct domain *d2){    return domain_has_perm(d1, d2, SECCLASS_GRANT, GRANT__QUERY);}static int get_page_sid(struct page_info *page, u32 *sid){    int rc = 0;    struct domain *d;    struct domain_security_struct *dsec;    unsigned long mfn;    d = page_get_owner(page);    if ( d == NULL )    {        mfn = page_to_mfn(page);        rc = security_iomem_sid(mfn, sid);        return rc;    }    switch ( d->domain_id )    {        case DOMID_IO:            /*A tracked IO page?*/            *sid = SECINITSID_DOMIO;        break;        case DOMID_XEN:            /*A page from Xen's private heap?*/            *sid = SECINITSID_DOMXEN;        break;        default:            /*Pages are implicitly labeled by domain ownership!*/            dsec = d->ssid;            *sid = dsec->sid;        break;    }    return rc;}static int get_mfn_sid(unsigned long mfn, u32 *sid){    int rc = 0;    struct page_info *page;    if ( mfn_valid(mfn) )    {        /*mfn is valid if this is a page that Xen is tracking!*/        page = mfn_to_page(mfn);                rc = get_page_sid(page, sid);    }    else    {        /*Possibly an untracked IO page?*/        rc = security_iomem_sid(mfn, sid);    }    return rc;    }static int flask_translate_gpfn_list(struct domain *d, unsigned long mfn){    int rc = 0;    u32 sid;    struct domain_security_struct *dsec;    dsec = d->ssid;    rc = get_mfn_sid(mfn, &sid);    if ( rc )        return rc;    return avc_has_perm(dsec->sid, sid, SECCLASS_MMU, MMU__TRANSLATEGP, NULL);}static int flask_memory_adjust_reservation(struct domain *d1, struct domain *d2){    return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__ADJUST);}static int flask_memory_stat_reservation(struct domain *d1, struct domain *d2){    return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__STAT);}static int flask_memory_pin_page(struct domain *d, struct page_info *page){    int rc = 0;    u32 sid;    struct domain_security_struct *dsec;    dsec = d->ssid;    rc = get_page_sid(page, &sid);    if ( rc )        return rc;    return avc_has_perm(dsec->sid, sid, SECCLASS_MMU, MMU__PINPAGE, NULL);}/* Used to defer flushing of memory structures. */struct percpu_mm_info {#define DOP_FLUSH_TLB      (1<<0) /* Flush the local TLB.                    */#define DOP_FLUSH_ALL_TLBS (1<<1) /* Flush TLBs of all VCPUs of current dom. */#define DOP_RELOAD_LDT     (1<<2) /* Reload the LDT shadow mapping.          */    unsigned int   deferred_ops;    /* If non-NULL, specifies a foreign subject domain for some operations. */    struct domain *foreign;};static DEFINE_PER_CPU(struct percpu_mm_info, percpu_mm_info);/* * Returns the current foreign domain; defaults to the currently-executing * domain if a foreign override hasn't been specified. */#define FOREIGNDOM (this_cpu(percpu_mm_info).foreign ?: current->domain)static int flask_console_io(struct domain *d, int cmd){    u32 perm;    switch ( cmd )    {        case CONSOLEIO_read:            perm = XEN__READCONSOLE;        break;        case CONSOLEIO_write:            perm = XEN__WRITECONSOLE;        break;        default:            return -EPERM;    }    return domain_has_xen(d, perm);}static int flask_profile(struct domain *d, int op){    u32 perm;    switch ( op )    {        case XENOPROF_init:        case XENOPROF_enable_virq:        case XENOPROF_disable_virq:        case XENOPROF_get_buffer:            perm = XEN__NONPRIVPROFILE;        break;        case XENOPROF_reset_active_list:        case XENOPROF_reset_passive_list:        case XENOPROF_set_active:        case XENOPROF_set_passive:        case XENOPROF_reserve_counters:        case XENOPROF_counter:        case XENOPROF_setup_events:        case XENOPROF_start:        case XENOPROF_stop:        case XENOPROF_release_counters:        case XENOPROF_shutdown:            perm = XEN__PRIVPROFILE;        break;        default:            return -EPERM;    }    return domain_has_xen(d, perm);}static int flask_kexec(void){    return domain_has_xen(current->domain, XEN__KEXEC);}static int flask_schedop_shutdown(struct domain *d1, struct domain *d2){    return domain_has_perm(d1, d2, SECCLASS_DOMAIN, DOMAIN__SHUTDOWN);}static void flask_security_domaininfo(struct domain *d,                                         struct xen_domctl_getdomaininfo *info){    struct domain_security_struct *dsec;    dsec = d->ssid;    info->ssidref = dsec->sid;}static int flask_setvcpucontext(struct domain *d){    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,                                                         DOMAIN__SETVCPUCONTEXT);}static int flask_pausedomain(struct domain *d){    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__PAUSE);}static int flask_unpausedomain(struct domain *d){    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__UNPAUSE);}static int flask_resumedomain(struct domain *d){    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__RESUME);}static int flask_domain_create(struct domain *d, u32 ssidref){    int rc;    struct domain_security_struct *dsec1;    struct domain_security_struct *dsec2;    dsec1 = current->domain->ssid;    if ( dsec1->create_sid == SECSID_NULL )        dsec1->create_sid = ssidref;    rc = avc_has_perm(dsec1->sid, dsec1->create_sid, SECCLASS_DOMAIN,                                                         DOMAIN__CREATE, NULL);    if ( rc )    {        dsec1->create_sid = SECSID_NULL;        return rc;    }    dsec2 = d->ssid;    dsec2->sid = dsec1->create_sid;    dsec1->create_sid = SECSID_NULL;    dsec2->create_sid = SECSID_NULL;    return rc;}static int flask_max_vcpus(struct domain *d){    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,                                                             DOMAIN__MAX_VCPUS);}static int flask_destroydomain(struct domain *d){    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,                                                             DOMAIN__DESTROY);}static int flask_vcpuaffinity(int cmd, struct domain *d){    u32 perm;    switch ( cmd )    {        case XEN_DOMCTL_setvcpuaffinity:            perm = DOMAIN__SETVCPUAFFINITY;        break;        case XEN_DOMCTL_getvcpuaffinity:            perm = DOMAIN__GETVCPUAFFINITY;        break;        default:            return -EPERM;    }    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm );}static int flask_scheduler(struct domain *d){    int rc = 0;    rc = domain_has_xen(current->domain, XEN__SCHEDULER);    if ( rc )        return rc;    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,                                                             DOMAIN__SCHEDULER);}static int flask_getdomaininfo(struct domain *d){    return domain_has_perm(current->domain, d, SECCLASS_DOMAIN,                                                        DOMAIN__GETDOMAININFO);

⌨️ 快捷键说明

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