Commit 6c2e8ac0 authored by Paul Moore's avatar Paul Moore

netlabel: Update kernel configuration API

Update the NetLabel kernel API to expose the new features added in kernel
releases 2.6.25 and 2.6.28: the static/fallback label functionality and network
address based selectors.
Signed-off-by: default avatarPaul Moore <paul.moore@hp.com>
parent 6a94cb73
...@@ -131,7 +131,8 @@ extern int cipso_v4_rbm_strictvalid; ...@@ -131,7 +131,8 @@ extern int cipso_v4_rbm_strictvalid;
*/ */
#ifdef CONFIG_NETLABEL #ifdef CONFIG_NETLABEL
int cipso_v4_doi_add(struct cipso_v4_doi *doi_def); int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
struct netlbl_audit *audit_info);
void cipso_v4_doi_free(struct cipso_v4_doi *doi_def); void cipso_v4_doi_free(struct cipso_v4_doi *doi_def);
int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info); int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info);
struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi); struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi);
...@@ -140,7 +141,8 @@ int cipso_v4_doi_walk(u32 *skip_cnt, ...@@ -140,7 +141,8 @@ int cipso_v4_doi_walk(u32 *skip_cnt,
int (*callback) (struct cipso_v4_doi *doi_def, void *arg), int (*callback) (struct cipso_v4_doi *doi_def, void *arg),
void *cb_arg); void *cb_arg);
#else #else
static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) static inline int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
struct netlbl_audit *audit_info)
{ {
return -ENOSYS; return -ENOSYS;
} }
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/net.h> #include <linux/net.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/in.h>
#include <linux/in6.h>
#include <net/netlink.h> #include <net/netlink.h>
#include <asm/atomic.h> #include <asm/atomic.h>
...@@ -353,13 +355,37 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr) ...@@ -353,13 +355,37 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr)
/* /*
* LSM configuration operations * LSM configuration operations
*/ */
int netlbl_cfg_map_del(const char *domain, struct netlbl_audit *audit_info); int netlbl_cfg_map_del(const char *domain,
int netlbl_cfg_unlbl_add_map(const char *domain, u16 family,
const void *addr,
const void *mask,
struct netlbl_audit *audit_info);
int netlbl_cfg_unlbl_map_add(const char *domain,
u16 family,
const void *addr,
const void *mask,
struct netlbl_audit *audit_info); struct netlbl_audit *audit_info);
int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, int netlbl_cfg_unlbl_static_add(struct net *net,
const char *dev_name,
const void *addr,
const void *mask,
u16 family,
u32 secid,
struct netlbl_audit *audit_info);
int netlbl_cfg_unlbl_static_del(struct net *net,
const char *dev_name,
const void *addr,
const void *mask,
u16 family,
struct netlbl_audit *audit_info);
int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
struct netlbl_audit *audit_info);
void netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info);
int netlbl_cfg_cipsov4_map_add(u32 doi,
const char *domain, const char *domain,
const struct in_addr *addr,
const struct in_addr *mask,
struct netlbl_audit *audit_info); struct netlbl_audit *audit_info);
/* /*
* LSM security attribute operations * LSM security attribute operations
*/ */
...@@ -401,19 +427,62 @@ void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway); ...@@ -401,19 +427,62 @@ void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway);
void netlbl_cache_invalidate(void); void netlbl_cache_invalidate(void);
int netlbl_cache_add(const struct sk_buff *skb, int netlbl_cache_add(const struct sk_buff *skb,
const struct netlbl_lsm_secattr *secattr); const struct netlbl_lsm_secattr *secattr);
/*
* Protocol engine operations
*/
struct audit_buffer *netlbl_audit_start(int type,
struct netlbl_audit *audit_info);
#else #else
static inline int netlbl_cfg_map_del(const char *domain, static inline int netlbl_cfg_map_del(const char *domain,
u16 family,
const void *addr,
const void *mask,
struct netlbl_audit *audit_info) struct netlbl_audit *audit_info)
{ {
return -ENOSYS; return -ENOSYS;
} }
static inline int netlbl_cfg_unlbl_add_map(const char *domain, static inline int netlbl_cfg_unlbl_map_add(const char *domain,
u16 family,
void *addr,
void *mask,
struct netlbl_audit *audit_info) struct netlbl_audit *audit_info)
{ {
return -ENOSYS; return -ENOSYS;
} }
static inline int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def, static inline int netlbl_cfg_unlbl_static_add(struct net *net,
const char *dev_name,
const void *addr,
const void *mask,
u16 family,
u32 secid,
struct netlbl_audit *audit_info)
{
return -ENOSYS;
}
static inline int netlbl_cfg_unlbl_static_del(struct net *net,
const char *dev_name,
const void *addr,
const void *mask,
u16 family,
struct netlbl_audit *audit_info)
{
return -ENOSYS;
}
static inline int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
struct netlbl_audit *audit_info)
{
return -ENOSYS;
}
static inline void netlbl_cfg_cipsov4_del(u32 doi,
struct netlbl_audit *audit_info)
{
return;
}
static inline int netlbl_cfg_cipsov4_map_add(u32 doi,
const char *domain, const char *domain,
const struct in_addr *addr,
const struct in_addr *mask,
struct netlbl_audit *audit_info) struct netlbl_audit *audit_info)
{ {
return -ENOSYS; return -ENOSYS;
...@@ -495,6 +564,11 @@ static inline int netlbl_cache_add(const struct sk_buff *skb, ...@@ -495,6 +564,11 @@ static inline int netlbl_cache_add(const struct sk_buff *skb,
{ {
return 0; return 0;
} }
static inline struct audit_buffer *netlbl_audit_start(int type,
struct netlbl_audit *audit_info)
{
return NULL;
}
#endif /* CONFIG_NETLABEL */ #endif /* CONFIG_NETLABEL */
#endif /* _NETLABEL_H */ #endif /* _NETLABEL_H */
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/jhash.h> #include <linux/jhash.h>
#include <linux/audit.h>
#include <net/ip.h> #include <net/ip.h>
#include <net/icmp.h> #include <net/icmp.h>
#include <net/tcp.h> #include <net/tcp.h>
...@@ -449,6 +450,7 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi) ...@@ -449,6 +450,7 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
/** /**
* cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine * cipso_v4_doi_add - Add a new DOI to the CIPSO protocol engine
* @doi_def: the DOI structure * @doi_def: the DOI structure
* @audit_info: NetLabel audit information
* *
* Description: * Description:
* The caller defines a new DOI for use by the CIPSO engine and calls this * The caller defines a new DOI for use by the CIPSO engine and calls this
...@@ -458,50 +460,78 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi) ...@@ -458,50 +460,78 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
* zero on success and non-zero on failure. * zero on success and non-zero on failure.
* *
*/ */
int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) int cipso_v4_doi_add(struct cipso_v4_doi *doi_def,
struct netlbl_audit *audit_info)
{ {
int ret_val = -EINVAL;
u32 iter; u32 iter;
u32 doi;
u32 doi_type;
struct audit_buffer *audit_buf;
doi = doi_def->doi;
doi_type = doi_def->type;
if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN) if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
return -EINVAL; goto doi_add_return;
for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) { for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {
switch (doi_def->tags[iter]) { switch (doi_def->tags[iter]) {
case CIPSO_V4_TAG_RBITMAP: case CIPSO_V4_TAG_RBITMAP:
break; break;
case CIPSO_V4_TAG_RANGE: 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: case CIPSO_V4_TAG_ENUM:
if (doi_def->type != CIPSO_V4_MAP_PASS) if (doi_def->type != CIPSO_V4_MAP_PASS)
return -EINVAL; goto doi_add_return;
break; break;
case CIPSO_V4_TAG_LOCAL: case CIPSO_V4_TAG_LOCAL:
if (doi_def->type != CIPSO_V4_MAP_LOCAL) if (doi_def->type != CIPSO_V4_MAP_LOCAL)
return -EINVAL; goto doi_add_return;
break;
case CIPSO_V4_TAG_INVALID:
if (iter == 0)
goto doi_add_return;
break; break;
default: default:
return -EINVAL; goto doi_add_return;
} }
} }
atomic_set(&doi_def->refcount, 1); atomic_set(&doi_def->refcount, 1);
spin_lock(&cipso_v4_doi_list_lock); spin_lock(&cipso_v4_doi_list_lock);
if (cipso_v4_doi_search(doi_def->doi) != NULL) if (cipso_v4_doi_search(doi_def->doi) != NULL) {
goto doi_add_failure; spin_unlock(&cipso_v4_doi_list_lock);
ret_val = -EEXIST;
goto doi_add_return;
}
list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list); list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
spin_unlock(&cipso_v4_doi_list_lock); spin_unlock(&cipso_v4_doi_list_lock);
ret_val = 0;
return 0; doi_add_return:
audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_ADD, audit_info);
if (audit_buf != NULL) {
const char *type_str;
switch (doi_type) {
case CIPSO_V4_MAP_TRANS:
type_str = "trans";
break;
case CIPSO_V4_MAP_PASS:
type_str = "pass";
break;
case CIPSO_V4_MAP_LOCAL:
type_str = "local";
break;
default:
type_str = "(unknown)";
}
audit_log_format(audit_buf,
" cipso_doi=%u cipso_type=%s res=%u",
doi, type_str, ret_val == 0 ? 1 : 0);
audit_log_end(audit_buf);
}
doi_add_failure: return ret_val;
spin_unlock(&cipso_v4_doi_list_lock);
return -EEXIST;
} }
/** /**
...@@ -559,25 +589,39 @@ static void cipso_v4_doi_free_rcu(struct rcu_head *entry) ...@@ -559,25 +589,39 @@ static void cipso_v4_doi_free_rcu(struct rcu_head *entry)
*/ */
int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info) int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info)
{ {
int ret_val;
struct cipso_v4_doi *doi_def; struct cipso_v4_doi *doi_def;
struct audit_buffer *audit_buf;
spin_lock(&cipso_v4_doi_list_lock); spin_lock(&cipso_v4_doi_list_lock);
doi_def = cipso_v4_doi_search(doi); doi_def = cipso_v4_doi_search(doi);
if (doi_def == NULL) { if (doi_def == NULL) {
spin_unlock(&cipso_v4_doi_list_lock); spin_unlock(&cipso_v4_doi_list_lock);
return -ENOENT; ret_val = -ENOENT;
goto doi_remove_return;
} }
if (!atomic_dec_and_test(&doi_def->refcount)) { if (!atomic_dec_and_test(&doi_def->refcount)) {
spin_unlock(&cipso_v4_doi_list_lock); spin_unlock(&cipso_v4_doi_list_lock);
return -EBUSY; ret_val = -EBUSY;
goto doi_remove_return;
} }
list_del_rcu(&doi_def->list); list_del_rcu(&doi_def->list);
spin_unlock(&cipso_v4_doi_list_lock); spin_unlock(&cipso_v4_doi_list_lock);
cipso_v4_cache_invalidate(); cipso_v4_cache_invalidate();
call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu); call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
ret_val = 0;
doi_remove_return:
audit_buf = netlbl_audit_start(AUDIT_MAC_CIPSOV4_DEL, audit_info);
if (audit_buf != NULL) {
audit_log_format(audit_buf,
" cipso_doi=%u res=%u",
doi, ret_val == 0 ? 1 : 0);
audit_log_end(audit_buf);
}
return 0; return ret_val;
} }
/** /**
......
...@@ -130,6 +130,7 @@ static int netlbl_cipsov4_add_common(struct genl_info *info, ...@@ -130,6 +130,7 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
/** /**
* netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition * netlbl_cipsov4_add_std - Adds a CIPSO V4 DOI definition
* @info: the Generic NETLINK info block * @info: the Generic NETLINK info block
* @audit_info: NetLabel audit information
* *
* Description: * Description:
* Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
...@@ -137,7 +138,8 @@ static int netlbl_cipsov4_add_common(struct genl_info *info, ...@@ -137,7 +138,8 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
* non-zero on error. * non-zero on error.
* *
*/ */
static int netlbl_cipsov4_add_std(struct genl_info *info) static int netlbl_cipsov4_add_std(struct genl_info *info,
struct netlbl_audit *audit_info)
{ {
int ret_val = -EINVAL; int ret_val = -EINVAL;
struct cipso_v4_doi *doi_def = NULL; struct cipso_v4_doi *doi_def = NULL;
...@@ -316,7 +318,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -316,7 +318,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
} }
} }
ret_val = cipso_v4_doi_add(doi_def); ret_val = cipso_v4_doi_add(doi_def, audit_info);
if (ret_val != 0) if (ret_val != 0)
goto add_std_failure; goto add_std_failure;
return 0; return 0;
...@@ -330,6 +332,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -330,6 +332,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
/** /**
* netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition * netlbl_cipsov4_add_pass - Adds a CIPSO V4 DOI definition
* @info: the Generic NETLINK info block * @info: the Generic NETLINK info block
* @audit_info: NetLabel audit information
* *
* Description: * Description:
* Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message * Create a new CIPSO_V4_MAP_PASS DOI definition based on the given ADD message
...@@ -337,7 +340,8 @@ static int netlbl_cipsov4_add_std(struct genl_info *info) ...@@ -337,7 +340,8 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
* error. * error.
* *
*/ */
static int netlbl_cipsov4_add_pass(struct genl_info *info) static int netlbl_cipsov4_add_pass(struct genl_info *info,
struct netlbl_audit *audit_info)
{ {
int ret_val; int ret_val;
struct cipso_v4_doi *doi_def = NULL; struct cipso_v4_doi *doi_def = NULL;
...@@ -354,7 +358,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info) ...@@ -354,7 +358,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
if (ret_val != 0) if (ret_val != 0)
goto add_pass_failure; goto add_pass_failure;
ret_val = cipso_v4_doi_add(doi_def); ret_val = cipso_v4_doi_add(doi_def, audit_info);
if (ret_val != 0) if (ret_val != 0)
goto add_pass_failure; goto add_pass_failure;
return 0; return 0;
...@@ -367,6 +371,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info) ...@@ -367,6 +371,7 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
/** /**
* netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition * netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
* @info: the Generic NETLINK info block * @info: the Generic NETLINK info block
* @audit_info: NetLabel audit information
* *
* Description: * Description:
* Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD * Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
...@@ -374,7 +379,8 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info) ...@@ -374,7 +379,8 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
* non-zero on error. * non-zero on error.
* *
*/ */
static int netlbl_cipsov4_add_local(struct genl_info *info) static int netlbl_cipsov4_add_local(struct genl_info *info,
struct netlbl_audit *audit_info)
{ {
int ret_val; int ret_val;
struct cipso_v4_doi *doi_def = NULL; struct cipso_v4_doi *doi_def = NULL;
...@@ -391,7 +397,7 @@ static int netlbl_cipsov4_add_local(struct genl_info *info) ...@@ -391,7 +397,7 @@ static int netlbl_cipsov4_add_local(struct genl_info *info)
if (ret_val != 0) if (ret_val != 0)
goto add_local_failure; goto add_local_failure;
ret_val = cipso_v4_doi_add(doi_def); ret_val = cipso_v4_doi_add(doi_def, audit_info);
if (ret_val != 0) if (ret_val != 0)
goto add_local_failure; goto add_local_failure;
return 0; return 0;
...@@ -415,48 +421,31 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info) ...@@ -415,48 +421,31 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
{ {
int ret_val = -EINVAL; int ret_val = -EINVAL;
u32 type;
u32 doi;
const char *type_str = "(unknown)"; const char *type_str = "(unknown)";
struct audit_buffer *audit_buf;
struct netlbl_audit audit_info; struct netlbl_audit audit_info;
if (!info->attrs[NLBL_CIPSOV4_A_DOI] || if (!info->attrs[NLBL_CIPSOV4_A_DOI] ||
!info->attrs[NLBL_CIPSOV4_A_MTYPE]) !info->attrs[NLBL_CIPSOV4_A_MTYPE])
return -EINVAL; return -EINVAL;
doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
netlbl_netlink_auditinfo(skb, &audit_info); netlbl_netlink_auditinfo(skb, &audit_info);
switch (nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE])) {
type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
switch (type) {
case CIPSO_V4_MAP_TRANS: case CIPSO_V4_MAP_TRANS:
type_str = "trans"; type_str = "trans";
ret_val = netlbl_cipsov4_add_std(info); ret_val = netlbl_cipsov4_add_std(info, &audit_info);
break; break;
case CIPSO_V4_MAP_PASS: case CIPSO_V4_MAP_PASS:
type_str = "pass"; type_str = "pass";
ret_val = netlbl_cipsov4_add_pass(info); ret_val = netlbl_cipsov4_add_pass(info, &audit_info);
break; break;
case CIPSO_V4_MAP_LOCAL: case CIPSO_V4_MAP_LOCAL:
type_str = "local"; type_str = "local";
ret_val = netlbl_cipsov4_add_local(info); ret_val = netlbl_cipsov4_add_local(info, &audit_info);
break; break;
} }
if (ret_val == 0) if (ret_val == 0)
atomic_inc(&netlabel_mgmt_protocount); atomic_inc(&netlabel_mgmt_protocount);
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
&audit_info);
if (audit_buf != NULL) {
audit_log_format(audit_buf,
" cipso_doi=%u cipso_type=%s res=%u",
doi,
type_str,
ret_val == 0 ? 1 : 0);
audit_log_end(audit_buf);
}
return ret_val; return ret_val;
} }
...@@ -725,9 +714,7 @@ static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg) ...@@ -725,9 +714,7 @@ static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
{ {
int ret_val = -EINVAL; int ret_val = -EINVAL;
u32 doi = 0;
struct netlbl_domhsh_walk_arg cb_arg; struct netlbl_domhsh_walk_arg cb_arg;
struct audit_buffer *audit_buf;
struct netlbl_audit audit_info; struct netlbl_audit audit_info;
u32 skip_bkt = 0; u32 skip_bkt = 0;
u32 skip_chain = 0; u32 skip_chain = 0;
...@@ -735,29 +722,17 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info) ...@@ -735,29 +722,17 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
if (!info->attrs[NLBL_CIPSOV4_A_DOI]) if (!info->attrs[NLBL_CIPSOV4_A_DOI])
return -EINVAL; return -EINVAL;
doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
netlbl_netlink_auditinfo(skb, &audit_info); netlbl_netlink_auditinfo(skb, &audit_info);
cb_arg.doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
cb_arg.doi = doi;
cb_arg.audit_info = &audit_info; cb_arg.audit_info = &audit_info;
ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain, ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
netlbl_cipsov4_remove_cb, &cb_arg); netlbl_cipsov4_remove_cb, &cb_arg);
if (ret_val == 0 || ret_val == -ENOENT) { if (ret_val == 0 || ret_val == -ENOENT) {
ret_val = cipso_v4_doi_remove(doi, &audit_info); ret_val = cipso_v4_doi_remove(cb_arg.doi, &audit_info);
if (ret_val == 0) if (ret_val == 0)
atomic_dec(&netlabel_mgmt_protocount); atomic_dec(&netlabel_mgmt_protocount);
} }
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
&audit_info);
if (audit_buf != NULL) {
audit_log_format(audit_buf,
" cipso_doi=%u res=%u",
doi,
ret_val == 0 ? 1 : 0);
audit_log_end(audit_buf);
}
return ret_val; return ret_val;
} }
......
...@@ -482,6 +482,73 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry, ...@@ -482,6 +482,73 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
return ret_val; return ret_val;
} }
/**
* netlbl_domhsh_remove_af4 - Removes an address selector entry
* @domain: the domain
* @addr: IPv4 address
* @mask: IPv4 address mask
* @audit_info: NetLabel audit information
*
* Description:
* Removes an individual address selector from a domain mapping and potentially
* the entire mapping if it is empty. Returns zero on success, negative values
* on failure.
*
*/
int netlbl_domhsh_remove_af4(const char *domain,
const struct in_addr *addr,
const struct in_addr *mask,
struct netlbl_audit *audit_info)
{
struct netlbl_dom_map *entry_map;
struct netlbl_af4list *entry_addr;
struct netlbl_af4list *iter4;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
struct netlbl_af6list *iter6;
#endif /* IPv6 */
struct netlbl_domaddr4_map *entry;
rcu_read_lock();
if (domain)
entry_map = netlbl_domhsh_search(domain);
else
entry_map = netlbl_domhsh_search_def(domain);
if (entry_map == NULL || entry_map->type != NETLBL_NLTYPE_ADDRSELECT)
goto remove_af4_failure;
spin_lock(&netlbl_domhsh_lock);
entry_addr = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
&entry_map->type_def.addrsel->list4);
spin_unlock(&netlbl_domhsh_lock);
if (entry_addr == NULL)
goto remove_af4_failure;
netlbl_af4list_foreach_rcu(iter4, &entry_map->type_def.addrsel->list4)
goto remove_af4_single_addr;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
netlbl_af6list_foreach_rcu(iter6, &entry_map->type_def.addrsel->list6)
goto remove_af4_single_addr;
#endif /* IPv6 */
/* the domain mapping is empty so remove it from the mapping table */
netlbl_domhsh_remove_entry(entry_map, audit_info);
remove_af4_single_addr:
rcu_read_unlock();
/* yick, we can't use call_rcu here because we don't have a rcu head
* pointer but hopefully this should be a rare case so the pause
* shouldn't be a problem */
synchronize_rcu();
entry = netlbl_domhsh_addr4_entry(entry_addr);
cipso_v4_doi_putdef(entry->type_def.cipsov4);
kfree(entry);
return 0;
remove_af4_failure:
rcu_read_unlock();
return -ENOENT;
}
/** /**
* netlbl_domhsh_remove - Removes an entry from the domain hash table * netlbl_domhsh_remove - Removes an entry from the domain hash table
* @domain: the domain to remove * @domain: the domain to remove
......
...@@ -90,6 +90,10 @@ int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, ...@@ -90,6 +90,10 @@ int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
struct netlbl_audit *audit_info); struct netlbl_audit *audit_info);
int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry, int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
struct netlbl_audit *audit_info); struct netlbl_audit *audit_info);
int netlbl_domhsh_remove_af4(const char *domain,
const struct in_addr *addr,
const struct in_addr *mask,
struct netlbl_audit *audit_info);
int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info); int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info);
struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
......
This diff is collapsed.
...@@ -450,13 +450,13 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex) ...@@ -450,13 +450,13 @@ static struct netlbl_unlhsh_iface *netlbl_unlhsh_add_iface(int ifindex)
* success, negative values on failure. * success, negative values on failure.
* *
*/ */
static int netlbl_unlhsh_add(struct net *net, int netlbl_unlhsh_add(struct net *net,
const char *dev_name, const char *dev_name,
const void *addr, const void *addr,
const void *mask, const void *mask,
u32 addr_len, u32 addr_len,
u32 secid, u32 secid,
struct netlbl_audit *audit_info) struct netlbl_audit *audit_info)
{ {
int ret_val; int ret_val;
int ifindex; int ifindex;
...@@ -720,12 +720,12 @@ static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface) ...@@ -720,12 +720,12 @@ static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface)
* Returns zero on success, negative values on failure. * Returns zero on success, negative values on failure.
* *
*/ */
static int netlbl_unlhsh_remove(struct net *net, int netlbl_unlhsh_remove(struct net *net,
const char *dev_name, const char *dev_name,
const void *addr, const void *addr,
const void *mask, const void *mask,
u32 addr_len, u32 addr_len,
struct netlbl_audit *audit_info) struct netlbl_audit *audit_info)
{ {
int ret_val; int ret_val;
struct net_device *dev; struct net_device *dev;
......
...@@ -221,6 +221,21 @@ int netlbl_unlabel_genl_init(void); ...@@ -221,6 +221,21 @@ int netlbl_unlabel_genl_init(void);
/* General Unlabeled init function */ /* General Unlabeled init function */
int netlbl_unlabel_init(u32 size); int netlbl_unlabel_init(u32 size);
/* Static/Fallback label management functions */
int netlbl_unlhsh_add(struct net *net,
const char *dev_name,
const void *addr,
const void *mask,
u32 addr_len,
u32 secid,
struct netlbl_audit *audit_info);
int netlbl_unlhsh_remove(struct net *net,
const char *dev_name,
const void *addr,
const void *mask,
u32 addr_len,
struct netlbl_audit *audit_info);
/* Process Unlabeled incoming network packets */ /* Process Unlabeled incoming network packets */
int netlbl_unlabel_getattr(const struct sk_buff *skb, int netlbl_unlabel_getattr(const struct sk_buff *skb,
u16 family, u16 family,
......
...@@ -350,7 +350,7 @@ static void smk_cipso_doi(void) ...@@ -350,7 +350,7 @@ static void smk_cipso_doi(void)
audit_info.sessionid = audit_get_sessionid(current); audit_info.sessionid = audit_get_sessionid(current);
audit_info.secid = smack_to_secid(current_security()); audit_info.secid = smack_to_secid(current_security());
rc = netlbl_cfg_map_del(NULL, &audit_info); rc = netlbl_cfg_map_del(NULL, PF_UNSPEC, NULL, NULL, &audit_info);
if (rc != 0) if (rc != 0)
printk(KERN_WARNING "%s:%d remove rc = %d\n", printk(KERN_WARNING "%s:%d remove rc = %d\n",
__func__, __LINE__, rc); __func__, __LINE__, rc);
...@@ -365,11 +365,20 @@ static void smk_cipso_doi(void) ...@@ -365,11 +365,20 @@ static void smk_cipso_doi(void)
for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++) for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
doip->tags[rc] = CIPSO_V4_TAG_INVALID; doip->tags[rc] = CIPSO_V4_TAG_INVALID;
rc = netlbl_cfg_cipsov4_add_map(doip, NULL, &audit_info); rc = netlbl_cfg_cipsov4_add(doip, &audit_info);
if (rc != 0) { if (rc != 0) {
printk(KERN_WARNING "%s:%d add rc = %d\n", printk(KERN_WARNING "%s:%d cipso add rc = %d\n",
__func__, __LINE__, rc);
kfree(doip);
return;
}
rc = netlbl_cfg_cipsov4_map_add(doip->doi,
NULL, NULL, NULL, &audit_info);
if (rc != 0) {
printk(KERN_WARNING "%s:%d map add rc = %d\n",
__func__, __LINE__, rc); __func__, __LINE__, rc);
kfree(doip); kfree(doip);
return;
} }
} }
...@@ -386,13 +395,15 @@ static void smk_unlbl_ambient(char *oldambient) ...@@ -386,13 +395,15 @@ static void smk_unlbl_ambient(char *oldambient)
audit_info.secid = smack_to_secid(current_security()); audit_info.secid = smack_to_secid(current_security());
if (oldambient != NULL) { if (oldambient != NULL) {
rc = netlbl_cfg_map_del(oldambient, &audit_info); rc = netlbl_cfg_map_del(oldambient,
PF_UNSPEC, NULL, NULL, &audit_info);
if (rc != 0) if (rc != 0)
printk(KERN_WARNING "%s:%d remove rc = %d\n", printk(KERN_WARNING "%s:%d remove rc = %d\n",
__func__, __LINE__, rc); __func__, __LINE__, rc);
} }
rc = netlbl_cfg_unlbl_add_map(smack_net_ambient, &audit_info); rc = netlbl_cfg_unlbl_map_add(smack_net_ambient,
PF_INET, NULL, NULL, &audit_info);
if (rc != 0) if (rc != 0)
printk(KERN_WARNING "%s:%d add rc = %d\n", printk(KERN_WARNING "%s:%d add rc = %d\n",
__func__, __LINE__, rc); __func__, __LINE__, rc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment