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

📄 policydb.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Implementation of the policy database. * * Author : Stephen Smalley, <sds@epoch.ncsc.mil> *//* Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> * * 	Added conditional policy language extensions * * Copyright (C) 2003 - 2004 Tresys Technology, LLC *	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. */#include <linux/kernel.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/errno.h>#include "security.h"#include "policydb.h"#include "conditional.h"#include "mls.h"#define _DEBUG_HASHES#ifdef DEBUG_HASHESstatic char *symtab_name[SYM_NUM] = {	"common prefixes",	"classes",	"roles",	"types",	"users",	mls_symtab_names	"bools"};#endifint policydb_loaded_version;static unsigned int symtab_sizes[SYM_NUM] = {	2,	32,	16,	512,	128,	mls_symtab_sizes	16};struct policydb_compat_info {	int version;	int sym_num;	int ocon_num;};/* These need to be updated if SYM_NUM or OCON_NUM changes */static struct policydb_compat_info policydb_compat[] = {	{		.version        = POLICYDB_VERSION_BASE,		.sym_num        = SYM_NUM - 1,		.ocon_num       = OCON_NUM - 1,	},	{		.version        = POLICYDB_VERSION_BOOL,		.sym_num        = SYM_NUM,		.ocon_num       = OCON_NUM - 1,	},	{		.version        = POLICYDB_VERSION_IPV6,		.sym_num        = SYM_NUM,		.ocon_num       = OCON_NUM,	},	{		.version        = POLICYDB_VERSION_NLCLASS,		.sym_num        = SYM_NUM,		.ocon_num       = OCON_NUM,	},};static struct policydb_compat_info *policydb_lookup_compat(int version){	int i;	struct policydb_compat_info *info = NULL;	for (i = 0; i < sizeof(policydb_compat)/sizeof(*info); i++) {		if (policydb_compat[i].version == version) {			info = &policydb_compat[i];			break;		}	}	return info;}/* * Initialize the role table. */int roles_init(struct policydb *p){	char *key = NULL;	int rc;	struct role_datum *role;	role = kmalloc(sizeof(*role), GFP_KERNEL);	if (!role) {		rc = -ENOMEM;		goto out;	}	memset(role, 0, sizeof(*role));	role->value = ++p->p_roles.nprim;	if (role->value != OBJECT_R_VAL) {		rc = -EINVAL;		goto out_free_role;	}	key = kmalloc(strlen(OBJECT_R)+1,GFP_KERNEL);	if (!key) {		rc = -ENOMEM;		goto out_free_role;	}	strcpy(key, OBJECT_R);	rc = hashtab_insert(p->p_roles.table, key, role);	if (rc)		goto out_free_key;out:	return rc;out_free_key:	kfree(key);out_free_role:	kfree(role);	goto out;}/* * Initialize a policy database structure. */int policydb_init(struct policydb *p){	int i, rc;	memset(p, 0, sizeof(*p));	for (i = 0; i < SYM_NUM; i++) {		rc = symtab_init(&p->symtab[i], symtab_sizes[i]);		if (rc)			goto out_free_symtab;	}	rc = avtab_init(&p->te_avtab);	if (rc)		goto out_free_symtab;	rc = roles_init(p);	if (rc)		goto out_free_avtab;	rc = cond_policydb_init(p);	if (rc)		goto out_free_avtab;out:	return rc;out_free_avtab:	avtab_destroy(&p->te_avtab);out_free_symtab:	for (i = 0; i < SYM_NUM; i++)		hashtab_destroy(p->symtab[i].table);	goto out;}/* * The following *_index functions are used to * define the val_to_name and val_to_struct arrays * in a policy database structure.  The val_to_name * arrays are used when converting security context * structures into string representations.  The * val_to_struct arrays are used when the attributes * of a class, role, or user are needed. */static int common_index(void *key, void *datum, void *datap){	struct policydb *p;	struct common_datum *comdatum;	comdatum = datum;	p = datap;	if (!comdatum->value || comdatum->value > p->p_commons.nprim)		return -EINVAL;	p->p_common_val_to_name[comdatum->value - 1] = key;	return 0;}static int class_index(void *key, void *datum, void *datap){	struct policydb *p;	struct class_datum *cladatum;	cladatum = datum;	p = datap;	if (!cladatum->value || cladatum->value > p->p_classes.nprim)		return -EINVAL;	p->p_class_val_to_name[cladatum->value - 1] = key;	p->class_val_to_struct[cladatum->value - 1] = cladatum;	return 0;}static int role_index(void *key, void *datum, void *datap){	struct policydb *p;	struct role_datum *role;	role = datum;	p = datap;	if (!role->value || role->value > p->p_roles.nprim)		return -EINVAL;	p->p_role_val_to_name[role->value - 1] = key;	p->role_val_to_struct[role->value - 1] = role;	return 0;}static int type_index(void *key, void *datum, void *datap){	struct policydb *p;	struct type_datum *typdatum;	typdatum = datum;	p = datap;	if (typdatum->primary) {		if (!typdatum->value || typdatum->value > p->p_types.nprim)			return -EINVAL;		p->p_type_val_to_name[typdatum->value - 1] = key;	}	return 0;}static int user_index(void *key, void *datum, void *datap){	struct policydb *p;	struct user_datum *usrdatum;	usrdatum = datum;	p = datap;	if (!usrdatum->value || usrdatum->value > p->p_users.nprim)		return -EINVAL;	p->p_user_val_to_name[usrdatum->value - 1] = key;	p->user_val_to_struct[usrdatum->value - 1] = usrdatum;	return 0;}static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) ={	common_index,	class_index,	role_index,	type_index,	user_index,	mls_index_f	cond_index_bool};/* * Define the common val_to_name array and the class * val_to_name and val_to_struct arrays in a policy * database structure. * * Caller must clean up upon failure. */int policydb_index_classes(struct policydb *p){	int rc;	p->p_common_val_to_name =		kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL);	if (!p->p_common_val_to_name) {		rc = -ENOMEM;		goto out;	}	rc = hashtab_map(p->p_commons.table, common_index, p);	if (rc)		goto out;	p->class_val_to_struct =		kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL);	if (!p->class_val_to_struct) {		rc = -ENOMEM;		goto out;	}	p->p_class_val_to_name =		kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL);	if (!p->p_class_val_to_name) {		rc = -ENOMEM;		goto out;	}	rc = hashtab_map(p->p_classes.table, class_index, p);out:	return rc;}#ifdef DEBUG_HASHESstatic void symtab_hash_eval(struct symtab *s){	int i;	for (i = 0; i < SYM_NUM; i++) {		struct hashtab *h = s[i].table;		struct hashtab_info info;		hashtab_stat(h, &info);		printk(KERN_INFO "%s:  %d entries and %d/%d buckets used, "		       "longest chain length %d\n", symtab_name[i], h->nel,		       info.slots_used, h->size, info.max_chain_len);	}}#endif/* * Define the other val_to_name and val_to_struct arrays * in a policy database structure. * * Caller must clean up on failure. */int policydb_index_others(struct policydb *p){	int i, rc = 0;	printk(KERN_INFO "security:  %d users, %d roles, %d types, %d bools",	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);	mls_policydb_index_others(p);	printk("\n");	printk(KERN_INFO "security:  %d classes, %d rules\n",	       p->p_classes.nprim, p->te_avtab.nel);#ifdef DEBUG_HASHES	avtab_hash_eval(&p->te_avtab, "rules");	symtab_hash_eval(p->symtab);#endif	p->role_val_to_struct =		kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)),		        GFP_KERNEL);	if (!p->role_val_to_struct) {		rc = -ENOMEM;		goto out;	}	p->user_val_to_struct =		kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)),		        GFP_KERNEL);	if (!p->user_val_to_struct) {		rc = -ENOMEM;		goto out;	}	if (cond_init_bool_indexes(p)) {		rc = -ENOMEM;		goto out;	}	for (i = SYM_ROLES; i < SYM_NUM; i++) {		p->sym_val_to_name[i] =			kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL);		if (!p->sym_val_to_name[i]) {			rc = -ENOMEM;			goto out;		}		rc = hashtab_map(p->symtab[i].table, index_f[i], p);		if (rc)			goto out;	}out:	return rc;}/* * The following *_destroy functions are used to * free any memory allocated for each kind of * symbol data in the policy database. */static int perm_destroy(void *key, void *datum, void *p){	kfree(key);	kfree(datum);	return 0;}static int common_destroy(void *key, void *datum, void *p){	struct common_datum *comdatum;	kfree(key);	comdatum = datum;	hashtab_map(comdatum->permissions.table, perm_destroy, NULL);	hashtab_destroy(comdatum->permissions.table);	kfree(datum);	return 0;}static int class_destroy(void *key, void *datum, void *p){	struct class_datum *cladatum;	struct constraint_node *constraint, *ctemp;	struct constraint_expr *e, *etmp;	kfree(key);	cladatum = datum;	hashtab_map(cladatum->permissions.table, perm_destroy, NULL);	hashtab_destroy(cladatum->permissions.table);	constraint = cladatum->constraints;	while (constraint) {		e = constraint->expr;		while (e) {			ebitmap_destroy(&e->names);			etmp = e;			e = e->next;			kfree(etmp);		}		ctemp = constraint;		constraint = constraint->next;		kfree(ctemp);	}	kfree(cladatum->comkey);	kfree(datum);	return 0;}static int role_destroy(void *key, void *datum, void *p){	struct role_datum *role;	kfree(key);	role = datum;	ebitmap_destroy(&role->dominates);	ebitmap_destroy(&role->types);	kfree(datum);	return 0;}static int type_destroy(void *key, void *datum, void *p){	kfree(key);	kfree(datum);	return 0;}static int user_destroy(void *key, void *datum, void *p){	struct user_datum *usrdatum;	kfree(key);	usrdatum = datum;	ebitmap_destroy(&usrdatum->roles);	mls_user_destroy(usrdatum);	kfree(datum);	return 0;}static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) ={	common_destroy,	class_destroy,	role_destroy,	type_destroy,	user_destroy,	mls_destroy_f	cond_destroy_bool};void ocontext_destroy(struct ocontext *c, int i){	context_destroy(&c->context[0]);	context_destroy(&c->context[1]);	if (i == OCON_ISID || i == OCON_FS ||	    i == OCON_NETIF || i == OCON_FSUSE)		kfree(c->u.name);	kfree(c);}/* * Free any memory allocated by a policy database structure. */void policydb_destroy(struct policydb *p){	struct ocontext *c, *ctmp;	struct genfs *g, *gtmp;	int i;	for (i = 0; i < SYM_NUM; i++) {		hashtab_map(p->symtab[i].table, destroy_f[i], NULL);		hashtab_destroy(p->symtab[i].table);	}	for (i = 0; i < SYM_NUM; i++) {		if (p->sym_val_to_name[i])			kfree(p->sym_val_to_name[i]);	}	if (p->class_val_to_struct)		kfree(p->class_val_to_struct);	if (p->role_val_to_struct)		kfree(p->role_val_to_struct);	if (p->user_val_to_struct)		kfree(p->user_val_to_struct);	avtab_destroy(&p->te_avtab);	for (i = 0; i < OCON_NUM; i++) {		c = p->ocontexts[i];		while (c) {			ctmp = c;

⌨️ 快捷键说明

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