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

📄 sidtab.c

📁 xen虚拟机源代码安装包
💻 C
字号:
/* * Implementation of the SID table type. * * Author : Stephen Smalley, <sds@epoch.ncsc.mil> */ /* Ported to Xen 3.0, George Coker, <gscoker@alpha.ncsc.mil> */ #include <xen/lib.h>#include <xen/xmalloc.h>#include <xen/errno.h>#include <xen/spinlock.h>#include "flask.h"#include "security.h"#include "sidtab.h"#define SIDTAB_HASH(sid) (sid & SIDTAB_HASH_MASK)#define INIT_SIDTAB_LOCK(s) spin_lock_init(&s->lock)#define SIDTAB_LOCK(s, x) spin_lock_irqsave(&s->lock, x)#define SIDTAB_UNLOCK(s, x) spin_unlock_irqrestore(&s->lock, x)int sidtab_init(struct sidtab *s){    int i;    s->htable = (void *)xmalloc_array(struct sidtab_node, SIDTAB_SIZE);    if ( !s->htable )        return -ENOMEM;    for ( i = 0; i < SIDTAB_SIZE; i++ )        s->htable[i] = NULL;    s->nel = 0;    s->next_sid = 1;    s->shutdown = 0;    INIT_SIDTAB_LOCK(s);    return 0;}int sidtab_insert(struct sidtab *s, u32 sid, struct context *context){    int hvalue, rc = 0;    struct sidtab_node *prev, *cur, *newnode;    if ( !s )    {        rc = -ENOMEM;        goto out;    }    hvalue = SIDTAB_HASH(sid);    prev = NULL;    cur = s->htable[hvalue];    while ( cur != NULL && sid > cur->sid )    {        prev = cur;        cur = cur->next;    }    if ( cur && sid == cur->sid )    {        rc = -EEXIST;        goto out;    }    newnode = xmalloc(struct sidtab_node);    if ( newnode == NULL )    {        rc = -ENOMEM;        goto out;    }    newnode->sid = sid;    if ( context_cpy(&newnode->context, context) )    {        xfree(newnode);        rc = -ENOMEM;        goto out;    }    if ( prev )    {        newnode->next = prev->next;        wmb();        prev->next = newnode;    }    else    {        newnode->next = s->htable[hvalue];        wmb();        s->htable[hvalue] = newnode;    }    s->nel++;    if ( sid >= s->next_sid )        s->next_sid = sid + 1;out:    return rc;}struct context *sidtab_search(struct sidtab *s, u32 sid){    int hvalue;    struct sidtab_node *cur;    if ( !s )        return NULL;    hvalue = SIDTAB_HASH(sid);    cur = s->htable[hvalue];    while ( cur != NULL && sid > cur->sid )        cur = cur->next;    if ( cur == NULL || sid != cur->sid )    {        /* Remap invalid SIDs to the unlabeled SID. */        sid = SECINITSID_UNLABELED;        hvalue = SIDTAB_HASH(sid);        cur = s->htable[hvalue];        while ( cur != NULL && sid > cur->sid )            cur = cur->next;        if ( !cur || sid != cur->sid )            return NULL;    }    return &cur->context;}int sidtab_map(struct sidtab *s,         int (*apply) (u32 sid, struct context *context, void *args), void *args){    int i, rc = 0;    struct sidtab_node *cur;    if ( !s )        goto out;    for ( i = 0; i < SIDTAB_SIZE; i++ )    {        cur = s->htable[i];        while ( cur != NULL )        {            rc = apply(cur->sid, &cur->context, args);            if ( rc )                goto out;            cur = cur->next;        }    }out:    return rc;}void sidtab_map_remove_on_error(struct sidtab *s,        int (*apply) (u32 sid, struct context *context, void *args), void *args){    int i, ret;    struct sidtab_node *last, *cur, *temp;    if ( !s )        return;    for ( i = 0; i < SIDTAB_SIZE; i++ )    {        last = NULL;        cur = s->htable[i];        while ( cur != NULL )        {            ret = apply(cur->sid, &cur->context, args);            if ( ret )            {                if ( last )                {                    last->next = cur->next;                }                else                {                    s->htable[i] = cur->next;                }                temp = cur;                cur = cur->next;                context_destroy(&temp->context);                xfree(temp);                s->nel--;            }            else            {                last = cur;                cur = cur->next;            }        }    }    return;}static inline u32 sidtab_search_context(struct sidtab *s,                                                         struct context *context){    int i;    struct sidtab_node *cur;    for ( i = 0; i < SIDTAB_SIZE; i++ )    {        cur = s->htable[i];        while ( cur != NULL )        {            if ( context_cmp(&cur->context, context) )                return cur->sid;            cur = cur->next;        }    }    return 0;}int sidtab_context_to_sid(struct sidtab *s, struct context *context,                                                                u32 *out_sid){    u32 sid;    int ret = 0;    unsigned long flags;    *out_sid = SECSID_NULL;    sid = sidtab_search_context(s, context);    if ( !sid )    {        SIDTAB_LOCK(s, flags);        /* Rescan now that we hold the lock. */        sid = sidtab_search_context(s, context);        if ( sid )            goto unlock_out;        /* No SID exists for the context.  Allocate a new one. */        if ( s->next_sid == UINT_MAX || s->shutdown )        {            ret = -ENOMEM;            goto unlock_out;        }        sid = s->next_sid++;        ret = sidtab_insert(s, sid, context);        if ( ret )            s->next_sid--;unlock_out:        SIDTAB_UNLOCK(s, flags);    }    if ( ret )        return ret;    *out_sid = sid;    return 0;}void sidtab_hash_eval(struct sidtab *h, char *tag){    int i, chain_len, slots_used, max_chain_len;    struct sidtab_node *cur;    slots_used = 0;    max_chain_len = 0;    for ( i = 0; i < SIDTAB_SIZE; i++ )    {        cur = h->htable[i];        if ( cur )        {            slots_used++;            chain_len = 0;            while ( cur )            {                chain_len++;                cur = cur->next;            }            if ( chain_len > max_chain_len )                max_chain_len = chain_len;        }    }    printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, longest "           "chain length %d\n", tag, h->nel, slots_used, SIDTAB_SIZE,           max_chain_len);}void sidtab_destroy(struct sidtab *s){    int i;    struct sidtab_node *cur, *temp;    if ( !s )        return;    for ( i = 0; i < SIDTAB_SIZE; i++ )    {        cur = s->htable[i];        while ( cur != NULL )        {            temp = cur;            cur = cur->next;            context_destroy(&temp->context);            xfree(temp);        }        s->htable[i] = NULL;    }    xfree(s->htable);    s->htable = NULL;    s->nel = 0;    s->next_sid = 1;}void sidtab_set(struct sidtab *dst, struct sidtab *src){    unsigned long flags;    SIDTAB_LOCK(src, flags);    dst->htable = src->htable;    dst->nel = src->nel;    dst->next_sid = src->next_sid;    dst->shutdown = 0;    SIDTAB_UNLOCK(src, flags);}void sidtab_shutdown(struct sidtab *s){    unsigned long flags;    SIDTAB_LOCK(s, flags);    s->shutdown = 1;    SIDTAB_UNLOCK(s, flags);}

⌨️ 快捷键说明

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