forked from mirrors/linux
		
	netlabel: Add support for removing a CALIPSO DOI.
Remove a specified DOI through the NLBL_CALIPSO_C_REMOVE command. It requires the attribute: NLBL_CALIPSO_A_DOI. Signed-off-by: Huw Davies <huw@codeweavers.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
This commit is contained in:
		
							parent
							
								
									dc7de73f19
								
							
						
					
					
						commit
						d7cce01504
					
				
					 4 changed files with 150 additions and 0 deletions
				
			
		| 
						 | 
					@ -237,6 +237,7 @@ struct netlbl_calipso_ops {
 | 
				
			||||||
	int (*doi_add)(struct calipso_doi *doi_def,
 | 
						int (*doi_add)(struct calipso_doi *doi_def,
 | 
				
			||||||
		       struct netlbl_audit *audit_info);
 | 
							       struct netlbl_audit *audit_info);
 | 
				
			||||||
	void (*doi_free)(struct calipso_doi *doi_def);
 | 
						void (*doi_free)(struct calipso_doi *doi_def);
 | 
				
			||||||
 | 
						int (*doi_remove)(u32 doi, struct netlbl_audit *audit_info);
 | 
				
			||||||
	struct calipso_doi *(*doi_getdef)(u32 doi);
 | 
						struct calipso_doi *(*doi_getdef)(u32 doi);
 | 
				
			||||||
	void (*doi_putdef)(struct calipso_doi *doi_def);
 | 
						void (*doi_putdef)(struct calipso_doi *doi_def);
 | 
				
			||||||
	int (*doi_walk)(u32 *skip_cnt,
 | 
						int (*doi_walk)(u32 *skip_cnt,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,6 +162,53 @@ static void calipso_doi_free_rcu(struct rcu_head *entry)
 | 
				
			||||||
	calipso_doi_free(doi_def);
 | 
						calipso_doi_free(doi_def);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * calipso_doi_remove - Remove an existing DOI from the CALIPSO protocol engine
 | 
				
			||||||
 | 
					 * @doi: the DOI value
 | 
				
			||||||
 | 
					 * @audit_secid: the LSM secid to use in the audit message
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Description:
 | 
				
			||||||
 | 
					 * Removes a DOI definition from the CALIPSO engine.  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.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret_val;
 | 
				
			||||||
 | 
						struct calipso_doi *doi_def;
 | 
				
			||||||
 | 
						struct audit_buffer *audit_buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spin_lock(&calipso_doi_list_lock);
 | 
				
			||||||
 | 
						doi_def = calipso_doi_search(doi);
 | 
				
			||||||
 | 
						if (!doi_def) {
 | 
				
			||||||
 | 
							spin_unlock(&calipso_doi_list_lock);
 | 
				
			||||||
 | 
							ret_val = -ENOENT;
 | 
				
			||||||
 | 
							goto doi_remove_return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (!atomic_dec_and_test(&doi_def->refcount)) {
 | 
				
			||||||
 | 
							spin_unlock(&calipso_doi_list_lock);
 | 
				
			||||||
 | 
							ret_val = -EBUSY;
 | 
				
			||||||
 | 
							goto doi_remove_return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						list_del_rcu(&doi_def->list);
 | 
				
			||||||
 | 
						spin_unlock(&calipso_doi_list_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						call_rcu(&doi_def->rcu, calipso_doi_free_rcu);
 | 
				
			||||||
 | 
						ret_val = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					doi_remove_return:
 | 
				
			||||||
 | 
						audit_buf = netlbl_audit_start(AUDIT_MAC_CALIPSO_DEL, audit_info);
 | 
				
			||||||
 | 
						if (audit_buf) {
 | 
				
			||||||
 | 
							audit_log_format(audit_buf,
 | 
				
			||||||
 | 
									 " calipso_doi=%u res=%u",
 | 
				
			||||||
 | 
									 doi, ret_val == 0 ? 1 : 0);
 | 
				
			||||||
 | 
							audit_log_end(audit_buf);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * calipso_doi_getdef - Returns a reference to a valid DOI definition
 | 
					 * calipso_doi_getdef - Returns a reference to a valid DOI definition
 | 
				
			||||||
 * @doi: the DOI value
 | 
					 * @doi: the DOI value
 | 
				
			||||||
| 
						 | 
					@ -253,6 +300,7 @@ static int calipso_doi_walk(u32 *skip_cnt,
 | 
				
			||||||
static const struct netlbl_calipso_ops ops = {
 | 
					static const struct netlbl_calipso_ops ops = {
 | 
				
			||||||
	.doi_add          = calipso_doi_add,
 | 
						.doi_add          = calipso_doi_add,
 | 
				
			||||||
	.doi_free         = calipso_doi_free,
 | 
						.doi_free         = calipso_doi_free,
 | 
				
			||||||
 | 
						.doi_remove       = calipso_doi_remove,
 | 
				
			||||||
	.doi_getdef       = calipso_doi_getdef,
 | 
						.doi_getdef       = calipso_doi_getdef,
 | 
				
			||||||
	.doi_putdef       = calipso_doi_putdef,
 | 
						.doi_putdef       = calipso_doi_putdef,
 | 
				
			||||||
	.doi_walk         = calipso_doi_walk,
 | 
						.doi_walk         = calipso_doi_walk,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,6 +53,12 @@ struct netlbl_calipso_doiwalk_arg {
 | 
				
			||||||
	u32 seq;
 | 
						u32 seq;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Argument struct for netlbl_domhsh_walk() */
 | 
				
			||||||
 | 
					struct netlbl_domhsh_walk_arg {
 | 
				
			||||||
 | 
						struct netlbl_audit *audit_info;
 | 
				
			||||||
 | 
						u32 doi;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* NetLabel Generic NETLINK CALIPSO family */
 | 
					/* NetLabel Generic NETLINK CALIPSO family */
 | 
				
			||||||
static struct genl_family netlbl_calipso_gnl_family = {
 | 
					static struct genl_family netlbl_calipso_gnl_family = {
 | 
				
			||||||
	.id = GENL_ID_GENERATE,
 | 
						.id = GENL_ID_GENERATE,
 | 
				
			||||||
| 
						 | 
					@ -257,6 +263,64 @@ static int netlbl_calipso_listall(struct sk_buff *skb,
 | 
				
			||||||
	return skb->len;
 | 
						return skb->len;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * netlbl_calipso_remove_cb - netlbl_calipso_remove() callback for REMOVE
 | 
				
			||||||
 | 
					 * @entry: LSM domain mapping entry
 | 
				
			||||||
 | 
					 * @arg: the netlbl_domhsh_walk_arg structure
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Description:
 | 
				
			||||||
 | 
					 * This function is intended for use by netlbl_calipso_remove() as the callback
 | 
				
			||||||
 | 
					 * for the netlbl_domhsh_walk() function; it removes LSM domain map entries
 | 
				
			||||||
 | 
					 * which are associated with the CALIPSO DOI specified in @arg.  Returns zero on
 | 
				
			||||||
 | 
					 * success, negative values on failure.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int netlbl_calipso_remove_cb(struct netlbl_dom_map *entry, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct netlbl_domhsh_walk_arg *cb_arg = arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (entry->def.type == NETLBL_NLTYPE_CALIPSO &&
 | 
				
			||||||
 | 
						    entry->def.calipso->doi == cb_arg->doi)
 | 
				
			||||||
 | 
							return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * netlbl_calipso_remove - Handle a REMOVE message
 | 
				
			||||||
 | 
					 * @skb: the NETLINK buffer
 | 
				
			||||||
 | 
					 * @info: the Generic NETLINK info block
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Description:
 | 
				
			||||||
 | 
					 * Process a user generated REMOVE message and respond accordingly.  Returns
 | 
				
			||||||
 | 
					 * zero on success, negative values on failure.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int netlbl_calipso_remove(struct sk_buff *skb, struct genl_info *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret_val = -EINVAL;
 | 
				
			||||||
 | 
						struct netlbl_domhsh_walk_arg cb_arg;
 | 
				
			||||||
 | 
						struct netlbl_audit audit_info;
 | 
				
			||||||
 | 
						u32 skip_bkt = 0;
 | 
				
			||||||
 | 
						u32 skip_chain = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!info->attrs[NLBL_CALIPSO_A_DOI])
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						netlbl_netlink_auditinfo(skb, &audit_info);
 | 
				
			||||||
 | 
						cb_arg.doi = nla_get_u32(info->attrs[NLBL_CALIPSO_A_DOI]);
 | 
				
			||||||
 | 
						cb_arg.audit_info = &audit_info;
 | 
				
			||||||
 | 
						ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
 | 
				
			||||||
 | 
									     netlbl_calipso_remove_cb, &cb_arg);
 | 
				
			||||||
 | 
						if (ret_val == 0 || ret_val == -ENOENT) {
 | 
				
			||||||
 | 
							ret_val = calipso_doi_remove(cb_arg.doi, &audit_info);
 | 
				
			||||||
 | 
							if (ret_val == 0)
 | 
				
			||||||
 | 
								atomic_dec(&netlabel_mgmt_protocount);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* NetLabel Generic NETLINK Command Definitions
 | 
					/* NetLabel Generic NETLINK Command Definitions
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -269,6 +333,13 @@ static const struct genl_ops netlbl_calipso_ops[] = {
 | 
				
			||||||
	.dumpit = NULL,
 | 
						.dumpit = NULL,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
						.cmd = NLBL_CALIPSO_C_REMOVE,
 | 
				
			||||||
 | 
						.flags = GENL_ADMIN_PERM,
 | 
				
			||||||
 | 
						.policy = calipso_genl_policy,
 | 
				
			||||||
 | 
						.doit = netlbl_calipso_remove,
 | 
				
			||||||
 | 
						.dumpit = NULL,
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
	.cmd = NLBL_CALIPSO_C_LIST,
 | 
						.cmd = NLBL_CALIPSO_C_LIST,
 | 
				
			||||||
	.flags = 0,
 | 
						.flags = 0,
 | 
				
			||||||
	.policy = calipso_genl_policy,
 | 
						.policy = calipso_genl_policy,
 | 
				
			||||||
| 
						 | 
					@ -362,6 +433,27 @@ void calipso_doi_free(struct calipso_doi *doi_def)
 | 
				
			||||||
		ops->doi_free(doi_def);
 | 
							ops->doi_free(doi_def);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * calipso_doi_remove - Remove an existing DOI from the CALIPSO protocol engine
 | 
				
			||||||
 | 
					 * @doi: the DOI value
 | 
				
			||||||
 | 
					 * @audit_secid: the LSM secid to use in the audit message
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Description:
 | 
				
			||||||
 | 
					 * Removes a DOI definition from the CALIPSO engine.  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 calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret_val = -ENOMSG;
 | 
				
			||||||
 | 
						const struct netlbl_calipso_ops *ops = netlbl_calipso_ops_get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ops)
 | 
				
			||||||
 | 
							ret_val = ops->doi_remove(doi, audit_info);
 | 
				
			||||||
 | 
						return ret_val;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * calipso_doi_getdef - Returns a reference to a valid DOI definition
 | 
					 * calipso_doi_getdef - Returns a reference to a valid DOI definition
 | 
				
			||||||
 * @doi: the DOI value
 | 
					 * @doi: the DOI value
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,6 +46,14 @@
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *   If using CALIPSO_MAP_PASS no additional attributes are required.
 | 
					 *   If using CALIPSO_MAP_PASS no additional attributes are required.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 | 
					 * o REMOVE:
 | 
				
			||||||
 | 
					 *   Sent by an application to remove a specific DOI mapping table from the
 | 
				
			||||||
 | 
					 *   CALIPSO system.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *   Required attributes:
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *     NLBL_CALIPSO_A_DOI
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 * o LIST:
 | 
					 * o LIST:
 | 
				
			||||||
 *   Sent by an application to list the details of a DOI definition.  On
 | 
					 *   Sent by an application to list the details of a DOI definition.  On
 | 
				
			||||||
 *   success the kernel should send a response using the following format.
 | 
					 *   success the kernel should send a response using the following format.
 | 
				
			||||||
| 
						 | 
					@ -114,6 +122,7 @@ static inline int netlbl_calipso_genl_init(void)
 | 
				
			||||||
int calipso_doi_add(struct calipso_doi *doi_def,
 | 
					int calipso_doi_add(struct calipso_doi *doi_def,
 | 
				
			||||||
		    struct netlbl_audit *audit_info);
 | 
							    struct netlbl_audit *audit_info);
 | 
				
			||||||
void calipso_doi_free(struct calipso_doi *doi_def);
 | 
					void calipso_doi_free(struct calipso_doi *doi_def);
 | 
				
			||||||
 | 
					int calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info);
 | 
				
			||||||
struct calipso_doi *calipso_doi_getdef(u32 doi);
 | 
					struct calipso_doi *calipso_doi_getdef(u32 doi);
 | 
				
			||||||
void calipso_doi_putdef(struct calipso_doi *doi_def);
 | 
					void calipso_doi_putdef(struct calipso_doi *doi_def);
 | 
				
			||||||
int calipso_doi_walk(u32 *skip_cnt,
 | 
					int calipso_doi_walk(u32 *skip_cnt,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue