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

📄 cipso_ipv4.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {		switch (doi_def->tags[iter]) {		case CIPSO_V4_TAG_RBITMAP:			break;		case CIPSO_V4_TAG_RANGE:			if (doi_def->type != CIPSO_V4_MAP_PASS)				return -EINVAL;			break;		case CIPSO_V4_TAG_INVALID:			if (iter == 0)				return -EINVAL;			break;		case CIPSO_V4_TAG_ENUM:			if (doi_def->type != CIPSO_V4_MAP_PASS)				return -EINVAL;			break;		default:			return -EINVAL;		}	}	doi_def->valid = 1;	INIT_RCU_HEAD(&doi_def->rcu);	INIT_LIST_HEAD(&doi_def->dom_list);	spin_lock(&cipso_v4_doi_list_lock);	if (cipso_v4_doi_search(doi_def->doi) != NULL)		goto doi_add_failure;	list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);	spin_unlock(&cipso_v4_doi_list_lock);	return 0;doi_add_failure:	spin_unlock(&cipso_v4_doi_list_lock);	return -EEXIST;}/** * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine * @doi: the DOI value * @audit_secid: the LSM secid to use in the audit message * @callback: the DOI cleanup/free callback * * Description: * Removes a DOI definition from the CIPSO engine, @callback is called to * free any memory.  The NetLabel routines will be called to release their own * LSM domain mappings as well as our own domain list.  Returns zero on * success and negative values on failure. * */int cipso_v4_doi_remove(u32 doi,			struct netlbl_audit *audit_info,			void (*callback) (struct rcu_head * head)){	struct cipso_v4_doi *doi_def;	struct cipso_v4_domhsh_entry *dom_iter;	spin_lock(&cipso_v4_doi_list_lock);	doi_def = cipso_v4_doi_search(doi);	if (doi_def != NULL) {		doi_def->valid = 0;		list_del_rcu(&doi_def->list);		spin_unlock(&cipso_v4_doi_list_lock);		rcu_read_lock();		list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list)			if (dom_iter->valid)				netlbl_domhsh_remove(dom_iter->domain,						     audit_info);		rcu_read_unlock();		cipso_v4_cache_invalidate();		call_rcu(&doi_def->rcu, callback);		return 0;	}	spin_unlock(&cipso_v4_doi_list_lock);	return -ENOENT;}/** * cipso_v4_doi_getdef - Returns a pointer to a valid DOI definition * @doi: the DOI value * * Description: * Searches for a valid DOI definition and if one is found it is returned to * the caller.  Otherwise NULL is returned.  The caller must ensure that * rcu_read_lock() is held while accessing the returned definition. * */struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi){	return cipso_v4_doi_search(doi);}/** * cipso_v4_doi_walk - Iterate through the DOI definitions * @skip_cnt: skip past this number of DOI definitions, updated * @callback: callback for each DOI definition * @cb_arg: argument for the callback function * * Description: * Iterate over the DOI definition list, skipping the first @skip_cnt entries. * For each entry call @callback, if @callback returns a negative value stop * 'walking' through the list and return.  Updates the value in @skip_cnt upon * return.  Returns zero on success, negative values on failure. * */int cipso_v4_doi_walk(u32 *skip_cnt,		     int (*callback) (struct cipso_v4_doi *doi_def, void *arg),		     void *cb_arg){	int ret_val = -ENOENT;	u32 doi_cnt = 0;	struct cipso_v4_doi *iter_doi;	rcu_read_lock();	list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list)		if (iter_doi->valid) {			if (doi_cnt++ < *skip_cnt)				continue;			ret_val = callback(iter_doi, cb_arg);			if (ret_val < 0) {				doi_cnt--;				goto doi_walk_return;			}		}doi_walk_return:	rcu_read_unlock();	*skip_cnt = doi_cnt;	return ret_val;}/** * cipso_v4_doi_domhsh_add - Adds a domain entry to a DOI definition * @doi_def: the DOI definition * @domain: the domain to add * * Description: * Adds the @domain to the DOI specified by @doi_def, this function * should only be called by external functions (i.e. NetLabel).  This function * does allocate memory.  Returns zero on success, negative values on failure. * */int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain){	struct cipso_v4_domhsh_entry *iter;	struct cipso_v4_domhsh_entry *new_dom;	new_dom = kzalloc(sizeof(*new_dom), GFP_KERNEL);	if (new_dom == NULL)		return -ENOMEM;	if (domain) {		new_dom->domain = kstrdup(domain, GFP_KERNEL);		if (new_dom->domain == NULL) {			kfree(new_dom);			return -ENOMEM;		}	}	new_dom->valid = 1;	INIT_RCU_HEAD(&new_dom->rcu);	spin_lock(&cipso_v4_doi_list_lock);	list_for_each_entry(iter, &doi_def->dom_list, list)		if (iter->valid &&		    ((domain != NULL && iter->domain != NULL &&		      strcmp(iter->domain, domain) == 0) ||		     (domain == NULL && iter->domain == NULL))) {			spin_unlock(&cipso_v4_doi_list_lock);			kfree(new_dom->domain);			kfree(new_dom);			return -EEXIST;		}	list_add_tail_rcu(&new_dom->list, &doi_def->dom_list);	spin_unlock(&cipso_v4_doi_list_lock);	return 0;}/** * cipso_v4_doi_domhsh_remove - Removes a domain entry from a DOI definition * @doi_def: the DOI definition * @domain: the domain to remove * * Description: * Removes the @domain from the DOI specified by @doi_def, this function * should only be called by external functions (i.e. NetLabel).   Returns zero * on success and negative values on error. * */int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,			       const char *domain){	struct cipso_v4_domhsh_entry *iter;	spin_lock(&cipso_v4_doi_list_lock);	list_for_each_entry(iter, &doi_def->dom_list, list)		if (iter->valid &&		    ((domain != NULL && iter->domain != NULL &&		      strcmp(iter->domain, domain) == 0) ||		     (domain == NULL && iter->domain == NULL))) {			iter->valid = 0;			list_del_rcu(&iter->list);			spin_unlock(&cipso_v4_doi_list_lock);			call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free);			return 0;		}	spin_unlock(&cipso_v4_doi_list_lock);	return -ENOENT;}/* * Label Mapping Functions *//** * cipso_v4_map_lvl_valid - Checks to see if the given level is understood * @doi_def: the DOI definition * @level: the level to check * * Description: * Checks the given level against the given DOI definition and returns a * negative value if the level does not have a valid mapping and a zero value * if the level is defined by the DOI. * */static int cipso_v4_map_lvl_valid(const struct cipso_v4_doi *doi_def, u8 level){	switch (doi_def->type) {	case CIPSO_V4_MAP_PASS:		return 0;	case CIPSO_V4_MAP_STD:		if (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL)			return 0;		break;	}	return -EFAULT;}/** * cipso_v4_map_lvl_hton - Perform a level mapping from the host to the network * @doi_def: the DOI definition * @host_lvl: the host MLS level * @net_lvl: the network/CIPSO MLS level * * Description: * Perform a label mapping to translate a local MLS level to the correct * CIPSO level using the given DOI definition.  Returns zero on success, * negative values otherwise. * */static int cipso_v4_map_lvl_hton(const struct cipso_v4_doi *doi_def,				 u32 host_lvl,				 u32 *net_lvl){	switch (doi_def->type) {	case CIPSO_V4_MAP_PASS:		*net_lvl = host_lvl;		return 0;	case CIPSO_V4_MAP_STD:		if (host_lvl < doi_def->map.std->lvl.local_size &&		    doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) {			*net_lvl = doi_def->map.std->lvl.local[host_lvl];			return 0;		}		return -EPERM;	}	return -EINVAL;}/** * cipso_v4_map_lvl_ntoh - Perform a level mapping from the network to the host * @doi_def: the DOI definition * @net_lvl: the network/CIPSO MLS level * @host_lvl: the host MLS level * * Description: * Perform a label mapping to translate a CIPSO level to the correct local MLS * level using the given DOI definition.  Returns zero on success, negative * values otherwise. * */static int cipso_v4_map_lvl_ntoh(const struct cipso_v4_doi *doi_def,				 u32 net_lvl,				 u32 *host_lvl){	struct cipso_v4_std_map_tbl *map_tbl;	switch (doi_def->type) {	case CIPSO_V4_MAP_PASS:		*host_lvl = net_lvl;		return 0;	case CIPSO_V4_MAP_STD:		map_tbl = doi_def->map.std;		if (net_lvl < map_tbl->lvl.cipso_size &&		    map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) {			*host_lvl = doi_def->map.std->lvl.cipso[net_lvl];			return 0;		}		return -EPERM;	}	return -EINVAL;}/** * cipso_v4_map_cat_rbm_valid - Checks to see if the category bitmap is valid * @doi_def: the DOI definition * @bitmap: category bitmap * @bitmap_len: bitmap length in bytes * * Description: * Checks the given category bitmap against the given DOI definition and * returns a negative value if any of the categories in the bitmap do not have * a valid mapping and a zero value if all of the categories are valid. * */static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,				      const unsigned char *bitmap,				      u32 bitmap_len){	int cat = -1;	u32 bitmap_len_bits = bitmap_len * 8;	u32 cipso_cat_size;	u32 *cipso_array;	switch (doi_def->type) {	case CIPSO_V4_MAP_PASS:		return 0;	case CIPSO_V4_MAP_STD:		cipso_cat_size = doi_def->map.std->cat.cipso_size;		cipso_array = doi_def->map.std->cat.cipso;		for (;;) {			cat = cipso_v4_bitmap_walk(bitmap,						   bitmap_len_bits,						   cat + 1,						   1);			if (cat < 0)				break;			if (cat >= cipso_cat_size ||			    cipso_array[cat] >= CIPSO_V4_INV_CAT)				return -EFAULT;		}		if (cat == -1)			return 0;		break;	}	return -EFAULT;}/** * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network * @doi_def: the DOI definition * @secattr: the security attributes * @net_cat: the zero'd out category bitmap in network/CIPSO format * @net_cat_len: the length of the CIPSO bitmap in bytes * * Description: * Perform a label mapping to translate a local MLS category bitmap to the * correct CIPSO bitmap using the given DOI definition.  Returns the minimum * size in bytes of the network bitmap on success, negative values otherwise. * */static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,				     const struct netlbl_lsm_secattr *secattr,				     unsigned char *net_cat,				     u32 net_cat_len){	int host_spot = -1;	u32 net_spot = CIPSO_V4_INV_CAT;	u32 net_spot_max = 0;	u32 net_clen_bits = net_cat_len * 8;	u32 host_cat_size = 0;	u32 *host_cat_array = NULL;	if (doi_def->type == CIPSO_V4_MAP_STD) {		host_cat_size = doi_def->map.std->cat.local_size;		host_cat_array = doi_def->map.std->cat.local;	}	for (;;) {		host_spot = netlbl_secattr_catmap_walk(secattr->mls_cat,						       host_spot + 1);		if (host_spot < 0)			break;		switch (doi_def->type) {		case CIPSO_V4_MAP_PASS:			net_spot = host_spot;			break;		case CIPSO_V4_MAP_STD:			if (host_spot >= host_cat_size)				return -EPERM;			net_spot = host_cat_array[host_spot];			if (net_spot >= CIPSO_V4_INV_CAT)				return -EPERM;			break;		}		if (net_spot >= net_clen_bits)			return -ENOSPC;		cipso_v4_bitmap_setbit(net_cat, net_spot, 1);		if (net_spot > net_spot_max)			net_spot_max = net_spot;	}	if (++net_spot_max % 8)		return net_spot_max / 8 + 1;	return net_spot_max / 8;}/** * cipso_v4_map_cat_rbm_ntoh - Perform a category mapping from network to host * @doi_def: the DOI definition * @net_cat: the category bitmap in network/CIPSO format * @net_cat_len: the length of the CIPSO bitmap in bytes * @secattr: the security attributes * * Description: * Perform a label mapping to translate a CIPSO bitmap to the correct local * MLS category bitmap using the given DOI definition.  Returns zero on * success, negative values on failure. * */static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,				     const unsigned char *net_cat,				     u32 net_cat_len,				     struct netlbl_lsm_secattr *secattr){	int ret_val;	int net_spot = -1;	u32 host_spot = CIPSO_V4_INV_CAT;	u32 net_clen_bits = net_cat_len * 8;	u32 net_cat_size = 0;	u32 *net_cat_array = NULL;	if (doi_def->type == CIPSO_V4_MAP_STD) {		net_cat_size = doi_def->map.std->cat.cipso_size;		net_cat_array = doi_def->map.std->cat.cipso;	}	for (;;) {		net_spot = cipso_v4_bitmap_walk(net_cat,						net_clen_bits,						net_spot + 1,						1);		if (net_spot < 0) {			if (net_spot == -2)				return -EFAULT;			return 0;		}		switch (doi_def->type) {		case CIPSO_V4_MAP_PASS:			host_spot = net_spot;			break;		case CIPSO_V4_MAP_STD:			if (net_spot >= net_cat_size)				return -EPERM;			host_spot = net_cat_array[net_spot];			if (host_spot >= CIPSO_V4_INV_CAT)				return -EPERM;			break;		}		ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,						       host_spot,						       GFP_ATOMIC);		if (ret_val != 0)			return ret_val;	}	return -EINVAL;}/** * cipso_v4_map_cat_enum_valid - Checks to see if the categories are valid

⌨️ 快捷键说明

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