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

📄 policydb.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Implementation of the policy database. * * Author : Stephen Smalley, <sds@epoch.ncsc.mil> *//* * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com> * *	Support for enhanced MLS infrastructure. * * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> * * 	Added conditional policy language extensions * * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * 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/sched.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",	"bools",	"levels",	"categories",};#endifint selinux_mls_enabled = 0;static unsigned int symtab_sizes[SYM_NUM] = {	2,	32,	16,	512,	128,	16,	16,	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 - 3,		.ocon_num       = OCON_NUM - 1,	},	{		.version        = POLICYDB_VERSION_BOOL,		.sym_num        = SYM_NUM - 2,		.ocon_num       = OCON_NUM - 1,	},	{		.version        = POLICYDB_VERSION_IPV6,		.sym_num        = SYM_NUM - 2,		.ocon_num       = OCON_NUM,	},	{		.version        = POLICYDB_VERSION_NLCLASS,		.sym_num        = SYM_NUM - 2,		.ocon_num       = OCON_NUM,	},	{		.version        = POLICYDB_VERSION_MLS,		.sym_num        = SYM_NUM,		.ocon_num       = OCON_NUM,	},	{		.version        = POLICYDB_VERSION_AVTAB,		.sym_num        = SYM_NUM,		.ocon_num       = OCON_NUM,	},	{		.version        = POLICYDB_VERSION_RANGETRANS,		.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 < ARRAY_SIZE(policydb_compat); i++) {		if (policydb_compat[i].version == version) {			info = &policydb_compat[i];			break;		}	}	return info;}/* * Initialize the role table. */static int roles_init(struct policydb *p){	char *key = NULL;	int rc;	struct role_datum *role;	role = kzalloc(sizeof(*role), GFP_KERNEL);	if (!role) {		rc = -ENOMEM;		goto out;	}	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. */static 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_symtab;	rc = cond_policydb_init(p);	if (rc)		goto out_free_symtab;out:	return rc;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 sens_index(void *key, void *datum, void *datap){	struct policydb *p;	struct level_datum *levdatum;	levdatum = datum;	p = datap;	if (!levdatum->isalias) {		if (!levdatum->level->sens ||		    levdatum->level->sens > p->p_levels.nprim)			return -EINVAL;		p->p_sens_val_to_name[levdatum->level->sens - 1] = key;	}	return 0;}static int cat_index(void *key, void *datum, void *datap){	struct policydb *p;	struct cat_datum *catdatum;	catdatum = datum;	p = datap;	if (!catdatum->isalias) {		if (!catdatum->value || catdatum->value > p->p_cats.nprim)			return -EINVAL;		p->p_cat_val_to_name[catdatum->value - 1] = key;	}	return 0;}static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) ={	common_index,	class_index,	role_index,	type_index,	user_index,	cond_index_bool,	sens_index,	cat_index,};/* * 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. */static 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_DEBUG "%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. */static int policydb_index_others(struct policydb *p){	int i, rc = 0;	printk(KERN_DEBUG "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);	if (selinux_mls_enabled)		printk(", %d sens, %d cats", p->p_levels.nprim,		       p->p_cats.nprim);	printk("\n");	printk(KERN_DEBUG "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 cls_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);	}	constraint = cladatum->validatetrans;	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);	ebitmap_destroy(&usrdatum->range.level[0].cat);	ebitmap_destroy(&usrdatum->range.level[1].cat);	ebitmap_destroy(&usrdatum->dfltlevel.cat);	kfree(datum);	return 0;}static int sens_destroy(void *key, void *datum, void *p){	struct level_datum *levdatum;	kfree(key);	levdatum = datum;	ebitmap_destroy(&levdatum->level->cat);	kfree(levdatum->level);	kfree(datum);	return 0;}static int cat_destroy(void *key, void *datum, void *p){	kfree(key);	kfree(datum);	return 0;}static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) ={	common_destroy,	cls_destroy,	role_destroy,	type_destroy,	user_destroy,	cond_destroy_bool,	sens_destroy,	cat_destroy,};static 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;	struct role_allow *ra, *lra = NULL;	struct role_trans *tr, *ltr = NULL;	struct range_trans *rt, *lrt = NULL;	for (i = 0; i < SYM_NUM; i++) {		cond_resched();		hashtab_map(p->symtab[i].table, destroy_f[i], NULL);		hashtab_destroy(p->symtab[i].table);	}	for (i = 0; i < SYM_NUM; i++)		kfree(p->sym_val_to_name[i]);	kfree(p->class_val_to_struct);	kfree(p->role_val_to_struct);	kfree(p->user_val_to_struct);	avtab_destroy(&p->te_avtab);	for (i = 0; i < OCON_NUM; i++) {		cond_resched();		c = p->ocontexts[i];		while (c) {			ctmp = c;			c = c->next;			ocontext_destroy(ctmp,i);		}		p->ocontexts[i] = NULL;	}	g = p->genfs;	while (g) {		cond_resched();		kfree(g->fstype);		c = g->head;		while (c) {			ctmp = c;			c = c->next;			ocontext_destroy(ctmp,OCON_FSUSE);		}		gtmp = g;		g = g->next;		kfree(gtmp);	}	p->genfs = NULL;	cond_policydb_destroy(p);	for (tr = p->role_tr; tr; tr = tr->next) {		cond_resched();		kfree(ltr);		ltr = tr;	}	kfree(ltr);	for (ra = p->role_allow; ra; ra = ra -> next) {		cond_resched();		kfree(lra);

⌨️ 快捷键说明

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