Commit 6a8b7f0c authored by Paul Moore's avatar Paul Moore Committed by David S. Miller

netlabel: use domain based selectors when address based selectors are not available

NetLabel has the ability to selectively assign network security labels
to outbound traffic based on either the LSM's "domain" (different for
each LSM), the network destination, or a combination of both.  Depending
on the type of traffic, local or forwarded, and the type of traffic
selector, domain or address based, different hooks are used to label the
traffic; the goal being minimal overhead.

Unfortunately, there is a bug such that a system using NetLabel domain
based traffic selectors does not correctly label outbound local traffic
that is not assigned to a socket.  The issue is that in these cases
the associated NetLabel hook only looks at the address based selectors
and not the domain based selectors.  This patch corrects this by
checking both the domain and address based selectors so that the correct
labeling is applied, regardless of the configuration type.

In order to acomplish this fix, this patch also simplifies some of the
NetLabel domainhash structures to use a more common outbound traffic
mapping type: struct netlbl_dommap_def.  This simplifies some of the code
in this patch and paves the way for further simplifications in the
future.
Signed-off-by: default avatarPaul Moore <pmoore@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5f671d6b
...@@ -691,8 +691,8 @@ static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg) ...@@ -691,8 +691,8 @@ static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
{ {
struct netlbl_domhsh_walk_arg *cb_arg = arg; struct netlbl_domhsh_walk_arg *cb_arg = arg;
if (entry->type == NETLBL_NLTYPE_CIPSOV4 && if (entry->def.type == NETLBL_NLTYPE_CIPSOV4 &&
entry->type_def.cipsov4->doi == cb_arg->doi) entry->def.cipso->doi == cb_arg->doi)
return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info); return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);
return 0; return 0;
......
...@@ -84,15 +84,15 @@ static void netlbl_domhsh_free_entry(struct rcu_head *entry) ...@@ -84,15 +84,15 @@ static void netlbl_domhsh_free_entry(struct rcu_head *entry)
#endif /* IPv6 */ #endif /* IPv6 */
ptr = container_of(entry, struct netlbl_dom_map, rcu); ptr = container_of(entry, struct netlbl_dom_map, rcu);
if (ptr->type == NETLBL_NLTYPE_ADDRSELECT) { if (ptr->def.type == NETLBL_NLTYPE_ADDRSELECT) {
netlbl_af4list_foreach_safe(iter4, tmp4, netlbl_af4list_foreach_safe(iter4, tmp4,
&ptr->type_def.addrsel->list4) { &ptr->def.addrsel->list4) {
netlbl_af4list_remove_entry(iter4); netlbl_af4list_remove_entry(iter4);
kfree(netlbl_domhsh_addr4_entry(iter4)); kfree(netlbl_domhsh_addr4_entry(iter4));
} }
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_safe(iter6, tmp6, netlbl_af6list_foreach_safe(iter6, tmp6,
&ptr->type_def.addrsel->list6) { &ptr->def.addrsel->list6) {
netlbl_af6list_remove_entry(iter6); netlbl_af6list_remove_entry(iter6);
kfree(netlbl_domhsh_addr6_entry(iter6)); kfree(netlbl_domhsh_addr6_entry(iter6));
} }
...@@ -213,21 +213,21 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry, ...@@ -213,21 +213,21 @@ static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
if (addr4 != NULL) { if (addr4 != NULL) {
struct netlbl_domaddr4_map *map4; struct netlbl_domaddr4_map *map4;
map4 = netlbl_domhsh_addr4_entry(addr4); map4 = netlbl_domhsh_addr4_entry(addr4);
type = map4->type; type = map4->def.type;
cipsov4 = map4->type_def.cipsov4; cipsov4 = map4->def.cipso;
netlbl_af4list_audit_addr(audit_buf, 0, NULL, netlbl_af4list_audit_addr(audit_buf, 0, NULL,
addr4->addr, addr4->mask); addr4->addr, addr4->mask);
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
} else if (addr6 != NULL) { } else if (addr6 != NULL) {
struct netlbl_domaddr6_map *map6; struct netlbl_domaddr6_map *map6;
map6 = netlbl_domhsh_addr6_entry(addr6); map6 = netlbl_domhsh_addr6_entry(addr6);
type = map6->type; type = map6->def.type;
netlbl_af6list_audit_addr(audit_buf, 0, NULL, netlbl_af6list_audit_addr(audit_buf, 0, NULL,
&addr6->addr, &addr6->mask); &addr6->addr, &addr6->mask);
#endif /* IPv6 */ #endif /* IPv6 */
} else { } else {
type = entry->type; type = entry->def.type;
cipsov4 = entry->type_def.cipsov4; cipsov4 = entry->def.cipso;
} }
switch (type) { switch (type) {
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
...@@ -265,26 +265,25 @@ static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry) ...@@ -265,26 +265,25 @@ static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
if (entry == NULL) if (entry == NULL)
return -EINVAL; return -EINVAL;
switch (entry->type) { switch (entry->def.type) {
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
if (entry->type_def.cipsov4 != NULL || if (entry->def.cipso != NULL || entry->def.addrsel != NULL)
entry->type_def.addrsel != NULL)
return -EINVAL; return -EINVAL;
break; break;
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
if (entry->type_def.cipsov4 == NULL) if (entry->def.cipso == NULL)
return -EINVAL; return -EINVAL;
break; break;
case NETLBL_NLTYPE_ADDRSELECT: case NETLBL_NLTYPE_ADDRSELECT:
netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) { netlbl_af4list_foreach(iter4, &entry->def.addrsel->list4) {
map4 = netlbl_domhsh_addr4_entry(iter4); map4 = netlbl_domhsh_addr4_entry(iter4);
switch (map4->type) { switch (map4->def.type) {
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
if (map4->type_def.cipsov4 != NULL) if (map4->def.cipso != NULL)
return -EINVAL; return -EINVAL;
break; break;
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
if (map4->type_def.cipsov4 == NULL) if (map4->def.cipso == NULL)
return -EINVAL; return -EINVAL;
break; break;
default: default:
...@@ -292,9 +291,9 @@ static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry) ...@@ -292,9 +291,9 @@ static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry)
} }
} }
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) { netlbl_af6list_foreach(iter6, &entry->def.addrsel->list6) {
map6 = netlbl_domhsh_addr6_entry(iter6); map6 = netlbl_domhsh_addr6_entry(iter6);
switch (map6->type) { switch (map6->def.type) {
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
break; break;
default: default:
...@@ -402,32 +401,31 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, ...@@ -402,32 +401,31 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
rcu_assign_pointer(netlbl_domhsh_def, entry); rcu_assign_pointer(netlbl_domhsh_def, entry);
} }
if (entry->type == NETLBL_NLTYPE_ADDRSELECT) { if (entry->def.type == NETLBL_NLTYPE_ADDRSELECT) {
netlbl_af4list_foreach_rcu(iter4, netlbl_af4list_foreach_rcu(iter4,
&entry->type_def.addrsel->list4) &entry->def.addrsel->list4)
netlbl_domhsh_audit_add(entry, iter4, NULL, netlbl_domhsh_audit_add(entry, iter4, NULL,
ret_val, audit_info); ret_val, audit_info);
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(iter6, netlbl_af6list_foreach_rcu(iter6,
&entry->type_def.addrsel->list6) &entry->def.addrsel->list6)
netlbl_domhsh_audit_add(entry, NULL, iter6, netlbl_domhsh_audit_add(entry, NULL, iter6,
ret_val, audit_info); ret_val, audit_info);
#endif /* IPv6 */ #endif /* IPv6 */
} else } else
netlbl_domhsh_audit_add(entry, NULL, NULL, netlbl_domhsh_audit_add(entry, NULL, NULL,
ret_val, audit_info); ret_val, audit_info);
} else if (entry_old->type == NETLBL_NLTYPE_ADDRSELECT && } else if (entry_old->def.type == NETLBL_NLTYPE_ADDRSELECT &&
entry->type == NETLBL_NLTYPE_ADDRSELECT) { entry->def.type == NETLBL_NLTYPE_ADDRSELECT) {
struct list_head *old_list4; struct list_head *old_list4;
struct list_head *old_list6; struct list_head *old_list6;
old_list4 = &entry_old->type_def.addrsel->list4; old_list4 = &entry_old->def.addrsel->list4;
old_list6 = &entry_old->type_def.addrsel->list6; old_list6 = &entry_old->def.addrsel->list6;
/* we only allow the addition of address selectors if all of /* we only allow the addition of address selectors if all of
* the selectors do not exist in the existing domain map */ * the selectors do not exist in the existing domain map */
netlbl_af4list_foreach_rcu(iter4, netlbl_af4list_foreach_rcu(iter4, &entry->def.addrsel->list4)
&entry->type_def.addrsel->list4)
if (netlbl_af4list_search_exact(iter4->addr, if (netlbl_af4list_search_exact(iter4->addr,
iter4->mask, iter4->mask,
old_list4)) { old_list4)) {
...@@ -435,8 +433,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, ...@@ -435,8 +433,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
goto add_return; goto add_return;
} }
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(iter6, netlbl_af6list_foreach_rcu(iter6, &entry->def.addrsel->list6)
&entry->type_def.addrsel->list6)
if (netlbl_af6list_search_exact(&iter6->addr, if (netlbl_af6list_search_exact(&iter6->addr,
&iter6->mask, &iter6->mask,
old_list6)) { old_list6)) {
...@@ -446,7 +443,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, ...@@ -446,7 +443,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
#endif /* IPv6 */ #endif /* IPv6 */
netlbl_af4list_foreach_safe(iter4, tmp4, netlbl_af4list_foreach_safe(iter4, tmp4,
&entry->type_def.addrsel->list4) { &entry->def.addrsel->list4) {
netlbl_af4list_remove_entry(iter4); netlbl_af4list_remove_entry(iter4);
iter4->valid = 1; iter4->valid = 1;
ret_val = netlbl_af4list_add(iter4, old_list4); ret_val = netlbl_af4list_add(iter4, old_list4);
...@@ -457,7 +454,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry, ...@@ -457,7 +454,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
} }
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_safe(iter6, tmp6, netlbl_af6list_foreach_safe(iter6, tmp6,
&entry->type_def.addrsel->list6) { &entry->def.addrsel->list6) {
netlbl_af6list_remove_entry(iter6); netlbl_af6list_remove_entry(iter6);
iter6->valid = 1; iter6->valid = 1;
ret_val = netlbl_af6list_add(iter6, old_list6); ret_val = netlbl_af6list_add(iter6, old_list6);
...@@ -538,18 +535,18 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry, ...@@ -538,18 +535,18 @@ int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
struct netlbl_af4list *iter4; struct netlbl_af4list *iter4;
struct netlbl_domaddr4_map *map4; struct netlbl_domaddr4_map *map4;
switch (entry->type) { switch (entry->def.type) {
case NETLBL_NLTYPE_ADDRSELECT: case NETLBL_NLTYPE_ADDRSELECT:
netlbl_af4list_foreach_rcu(iter4, netlbl_af4list_foreach_rcu(iter4,
&entry->type_def.addrsel->list4) { &entry->def.addrsel->list4) {
map4 = netlbl_domhsh_addr4_entry(iter4); map4 = netlbl_domhsh_addr4_entry(iter4);
cipso_v4_doi_putdef(map4->type_def.cipsov4); cipso_v4_doi_putdef(map4->def.cipso);
} }
/* no need to check the IPv6 list since we currently /* no need to check the IPv6 list since we currently
* support only unlabeled protocols for IPv6 */ * support only unlabeled protocols for IPv6 */
break; break;
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
cipso_v4_doi_putdef(entry->type_def.cipsov4); cipso_v4_doi_putdef(entry->def.cipso);
break; break;
} }
call_rcu(&entry->rcu, netlbl_domhsh_free_entry); call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
...@@ -590,20 +587,21 @@ int netlbl_domhsh_remove_af4(const char *domain, ...@@ -590,20 +587,21 @@ int netlbl_domhsh_remove_af4(const char *domain,
entry_map = netlbl_domhsh_search(domain); entry_map = netlbl_domhsh_search(domain);
else else
entry_map = netlbl_domhsh_search_def(domain); entry_map = netlbl_domhsh_search_def(domain);
if (entry_map == NULL || entry_map->type != NETLBL_NLTYPE_ADDRSELECT) if (entry_map == NULL ||
entry_map->def.type != NETLBL_NLTYPE_ADDRSELECT)
goto remove_af4_failure; goto remove_af4_failure;
spin_lock(&netlbl_domhsh_lock); spin_lock(&netlbl_domhsh_lock);
entry_addr = netlbl_af4list_remove(addr->s_addr, mask->s_addr, entry_addr = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
&entry_map->type_def.addrsel->list4); &entry_map->def.addrsel->list4);
spin_unlock(&netlbl_domhsh_lock); spin_unlock(&netlbl_domhsh_lock);
if (entry_addr == NULL) if (entry_addr == NULL)
goto remove_af4_failure; goto remove_af4_failure;
netlbl_af4list_foreach_rcu(iter4, &entry_map->type_def.addrsel->list4) netlbl_af4list_foreach_rcu(iter4, &entry_map->def.addrsel->list4)
goto remove_af4_single_addr; goto remove_af4_single_addr;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(iter6, &entry_map->type_def.addrsel->list6) netlbl_af6list_foreach_rcu(iter6, &entry_map->def.addrsel->list6)
goto remove_af4_single_addr; goto remove_af4_single_addr;
#endif /* IPv6 */ #endif /* IPv6 */
/* the domain mapping is empty so remove it from the mapping table */ /* the domain mapping is empty so remove it from the mapping table */
...@@ -616,7 +614,7 @@ int netlbl_domhsh_remove_af4(const char *domain, ...@@ -616,7 +614,7 @@ int netlbl_domhsh_remove_af4(const char *domain,
* shouldn't be a problem */ * shouldn't be a problem */
synchronize_rcu(); synchronize_rcu();
entry = netlbl_domhsh_addr4_entry(entry_addr); entry = netlbl_domhsh_addr4_entry(entry_addr);
cipso_v4_doi_putdef(entry->type_def.cipsov4); cipso_v4_doi_putdef(entry->def.cipso);
kfree(entry); kfree(entry);
return 0; return 0;
...@@ -693,8 +691,8 @@ struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain) ...@@ -693,8 +691,8 @@ struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain)
* responsible for ensuring that rcu_read_[un]lock() is called. * responsible for ensuring that rcu_read_[un]lock() is called.
* *
*/ */
struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain, struct netlbl_dommap_def *netlbl_domhsh_getentry_af4(const char *domain,
__be32 addr) __be32 addr)
{ {
struct netlbl_dom_map *dom_iter; struct netlbl_dom_map *dom_iter;
struct netlbl_af4list *addr_iter; struct netlbl_af4list *addr_iter;
...@@ -702,15 +700,13 @@ struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain, ...@@ -702,15 +700,13 @@ struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain,
dom_iter = netlbl_domhsh_search_def(domain); dom_iter = netlbl_domhsh_search_def(domain);
if (dom_iter == NULL) if (dom_iter == NULL)
return NULL; return NULL;
if (dom_iter->type != NETLBL_NLTYPE_ADDRSELECT)
return NULL;
addr_iter = netlbl_af4list_search(addr, if (dom_iter->def.type != NETLBL_NLTYPE_ADDRSELECT)
&dom_iter->type_def.addrsel->list4); return &dom_iter->def;
addr_iter = netlbl_af4list_search(addr, &dom_iter->def.addrsel->list4);
if (addr_iter == NULL) if (addr_iter == NULL)
return NULL; return NULL;
return &(netlbl_domhsh_addr4_entry(addr_iter)->def);
return netlbl_domhsh_addr4_entry(addr_iter);
} }
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
...@@ -725,7 +721,7 @@ struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain, ...@@ -725,7 +721,7 @@ struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain,
* responsible for ensuring that rcu_read_[un]lock() is called. * responsible for ensuring that rcu_read_[un]lock() is called.
* *
*/ */
struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain, struct netlbl_dommap_def *netlbl_domhsh_getentry_af6(const char *domain,
const struct in6_addr *addr) const struct in6_addr *addr)
{ {
struct netlbl_dom_map *dom_iter; struct netlbl_dom_map *dom_iter;
...@@ -734,15 +730,13 @@ struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain, ...@@ -734,15 +730,13 @@ struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain,
dom_iter = netlbl_domhsh_search_def(domain); dom_iter = netlbl_domhsh_search_def(domain);
if (dom_iter == NULL) if (dom_iter == NULL)
return NULL; return NULL;
if (dom_iter->type != NETLBL_NLTYPE_ADDRSELECT)
return NULL;
addr_iter = netlbl_af6list_search(addr, if (dom_iter->def.type != NETLBL_NLTYPE_ADDRSELECT)
&dom_iter->type_def.addrsel->list6); return &dom_iter->def;
addr_iter = netlbl_af6list_search(addr, &dom_iter->def.addrsel->list6);
if (addr_iter == NULL) if (addr_iter == NULL)
return NULL; return NULL;
return &(netlbl_domhsh_addr6_entry(addr_iter)->def);
return netlbl_domhsh_addr6_entry(addr_iter);
} }
#endif /* IPv6 */ #endif /* IPv6 */
......
...@@ -43,37 +43,35 @@ ...@@ -43,37 +43,35 @@
#define NETLBL_DOMHSH_BITSIZE 7 #define NETLBL_DOMHSH_BITSIZE 7
/* Domain mapping definition structures */ /* Domain mapping definition structures */
struct netlbl_domaddr_map {
struct list_head list4;
struct list_head list6;
};
struct netlbl_dommap_def {
u32 type;
union {
struct netlbl_domaddr_map *addrsel;
struct cipso_v4_doi *cipso;
};
};
#define netlbl_domhsh_addr4_entry(iter) \ #define netlbl_domhsh_addr4_entry(iter) \
container_of(iter, struct netlbl_domaddr4_map, list) container_of(iter, struct netlbl_domaddr4_map, list)
struct netlbl_domaddr4_map { struct netlbl_domaddr4_map {
u32 type; struct netlbl_dommap_def def;
union {
struct cipso_v4_doi *cipsov4;
} type_def;
struct netlbl_af4list list; struct netlbl_af4list list;
}; };
#define netlbl_domhsh_addr6_entry(iter) \ #define netlbl_domhsh_addr6_entry(iter) \
container_of(iter, struct netlbl_domaddr6_map, list) container_of(iter, struct netlbl_domaddr6_map, list)
struct netlbl_domaddr6_map { struct netlbl_domaddr6_map {
u32 type; struct netlbl_dommap_def def;
/* NOTE: no 'type_def' union needed at present since we don't currently
* support any IPv6 labeling protocols */
struct netlbl_af6list list; struct netlbl_af6list list;
}; };
struct netlbl_domaddr_map {
struct list_head list4;
struct list_head list6;
};
struct netlbl_dom_map { struct netlbl_dom_map {
char *domain; char *domain;
u32 type; struct netlbl_dommap_def def;
union {
struct cipso_v4_doi *cipsov4;
struct netlbl_domaddr_map *addrsel;
} type_def;
u32 valid; u32 valid;
struct list_head list; struct list_head list;
...@@ -97,16 +95,16 @@ int netlbl_domhsh_remove_af4(const char *domain, ...@@ -97,16 +95,16 @@ int netlbl_domhsh_remove_af4(const char *domain,
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);
struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain, struct netlbl_dommap_def *netlbl_domhsh_getentry_af4(const char *domain,
__be32 addr); __be32 addr);
#if IS_ENABLED(CONFIG_IPV6)
struct netlbl_dommap_def *netlbl_domhsh_getentry_af6(const char *domain,
const struct in6_addr *addr);
#endif /* IPv6 */
int netlbl_domhsh_walk(u32 *skip_bkt, int netlbl_domhsh_walk(u32 *skip_bkt,
u32 *skip_chain, u32 *skip_chain,
int (*callback) (struct netlbl_dom_map *entry, void *arg), int (*callback) (struct netlbl_dom_map *entry, void *arg),
void *cb_arg); void *cb_arg);
#if IS_ENABLED(CONFIG_IPV6)
struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain,
const struct in6_addr *addr);
#endif /* IPv6 */
#endif #endif
...@@ -122,7 +122,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, ...@@ -122,7 +122,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
} }
if (addr == NULL && mask == NULL) if (addr == NULL && mask == NULL)
entry->type = NETLBL_NLTYPE_UNLABELED; entry->def.type = NETLBL_NLTYPE_UNLABELED;
else if (addr != NULL && mask != NULL) { else if (addr != NULL && mask != NULL) {
addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
if (addrmap == NULL) if (addrmap == NULL)
...@@ -137,7 +137,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, ...@@ -137,7 +137,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
map4 = kzalloc(sizeof(*map4), GFP_ATOMIC); map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
if (map4 == NULL) if (map4 == NULL)
goto cfg_unlbl_map_add_failure; goto cfg_unlbl_map_add_failure;
map4->type = NETLBL_NLTYPE_UNLABELED; map4->def.type = NETLBL_NLTYPE_UNLABELED;
map4->list.addr = addr4->s_addr & mask4->s_addr; map4->list.addr = addr4->s_addr & mask4->s_addr;
map4->list.mask = mask4->s_addr; map4->list.mask = mask4->s_addr;
map4->list.valid = 1; map4->list.valid = 1;
...@@ -154,7 +154,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain, ...@@ -154,7 +154,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
map6 = kzalloc(sizeof(*map6), GFP_ATOMIC); map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
if (map6 == NULL) if (map6 == NULL)
goto cfg_unlbl_map_add_failure; goto cfg_unlbl_map_add_failure;
map6->type = NETLBL_NLTYPE_UNLABELED; map6->def.type = NETLBL_NLTYPE_UNLABELED;
map6->list.addr = *addr6; map6->list.addr = *addr6;
map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0]; map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1]; map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
...@@ -174,8 +174,8 @@ int netlbl_cfg_unlbl_map_add(const char *domain, ...@@ -174,8 +174,8 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
break; break;
} }
entry->type_def.addrsel = addrmap; entry->def.addrsel = addrmap;
entry->type = NETLBL_NLTYPE_ADDRSELECT; entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
} else { } else {
ret_val = -EINVAL; ret_val = -EINVAL;
goto cfg_unlbl_map_add_failure; goto cfg_unlbl_map_add_failure;
...@@ -355,8 +355,8 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, ...@@ -355,8 +355,8 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
} }
if (addr == NULL && mask == NULL) { if (addr == NULL && mask == NULL) {
entry->type_def.cipsov4 = doi_def; entry->def.cipso = doi_def;
entry->type = NETLBL_NLTYPE_CIPSOV4; entry->def.type = NETLBL_NLTYPE_CIPSOV4;
} else if (addr != NULL && mask != NULL) { } else if (addr != NULL && mask != NULL) {
addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
if (addrmap == NULL) if (addrmap == NULL)
...@@ -367,8 +367,8 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, ...@@ -367,8 +367,8 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
if (addrinfo == NULL) if (addrinfo == NULL)
goto out_addrinfo; goto out_addrinfo;
addrinfo->type_def.cipsov4 = doi_def; addrinfo->def.cipso = doi_def;
addrinfo->type = NETLBL_NLTYPE_CIPSOV4; addrinfo->def.type = NETLBL_NLTYPE_CIPSOV4;
addrinfo->list.addr = addr->s_addr & mask->s_addr; addrinfo->list.addr = addr->s_addr & mask->s_addr;
addrinfo->list.mask = mask->s_addr; addrinfo->list.mask = mask->s_addr;
addrinfo->list.valid = 1; addrinfo->list.valid = 1;
...@@ -376,8 +376,8 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, ...@@ -376,8 +376,8 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
if (ret_val != 0) if (ret_val != 0)
goto cfg_cipsov4_map_add_failure; goto cfg_cipsov4_map_add_failure;
entry->type_def.addrsel = addrmap; entry->def.addrsel = addrmap;
entry->type = NETLBL_NLTYPE_ADDRSELECT; entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
} else { } else {
ret_val = -EINVAL; ret_val = -EINVAL;
goto out_addrmap; goto out_addrmap;
...@@ -657,14 +657,14 @@ int netlbl_sock_setattr(struct sock *sk, ...@@ -657,14 +657,14 @@ int netlbl_sock_setattr(struct sock *sk,
} }
switch (family) { switch (family) {
case AF_INET: case AF_INET:
switch (dom_entry->type) { switch (dom_entry->def.type) {
case NETLBL_NLTYPE_ADDRSELECT: case NETLBL_NLTYPE_ADDRSELECT:
ret_val = -EDESTADDRREQ; ret_val = -EDESTADDRREQ;
break; break;
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
ret_val = cipso_v4_sock_setattr(sk, ret_val = cipso_v4_sock_setattr(sk,
dom_entry->type_def.cipsov4, dom_entry->def.cipso,
secattr); secattr);
break; break;
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
ret_val = 0; ret_val = 0;
...@@ -754,23 +754,22 @@ int netlbl_conn_setattr(struct sock *sk, ...@@ -754,23 +754,22 @@ int netlbl_conn_setattr(struct sock *sk,
{ {
int ret_val; int ret_val;
struct sockaddr_in *addr4; struct sockaddr_in *addr4;
struct netlbl_domaddr4_map *af4_entry; struct netlbl_dommap_def *entry;
rcu_read_lock(); rcu_read_lock();
switch (addr->sa_family) { switch (addr->sa_family) {
case AF_INET: case AF_INET:
addr4 = (struct sockaddr_in *)addr; addr4 = (struct sockaddr_in *)addr;
af4_entry = netlbl_domhsh_getentry_af4(secattr->domain, entry = netlbl_domhsh_getentry_af4(secattr->domain,
addr4->sin_addr.s_addr); addr4->sin_addr.s_addr);
if (af4_entry == NULL) { if (entry == NULL) {
ret_val = -ENOENT; ret_val = -ENOENT;
goto conn_setattr_return; goto conn_setattr_return;
} }
switch (af4_entry->type) { switch (entry->type) {
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
ret_val = cipso_v4_sock_setattr(sk, ret_val = cipso_v4_sock_setattr(sk,
af4_entry->type_def.cipsov4, entry->cipso, secattr);
secattr);
break; break;
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
/* just delete the protocols we support for right now /* just delete the protocols we support for right now
...@@ -812,36 +811,21 @@ int netlbl_req_setattr(struct request_sock *req, ...@@ -812,36 +811,21 @@ int netlbl_req_setattr(struct request_sock *req,
const struct netlbl_lsm_secattr *secattr) const struct netlbl_lsm_secattr *secattr)
{ {
int ret_val; int ret_val;
struct netlbl_dom_map *dom_entry; struct netlbl_dommap_def *entry;
struct netlbl_domaddr4_map *af4_entry;
u32 proto_type;
struct cipso_v4_doi *proto_cv4;
rcu_read_lock(); rcu_read_lock();
dom_entry = netlbl_domhsh_getentry(secattr->domain);
if (dom_entry == NULL) {
ret_val = -ENOENT;
goto req_setattr_return;
}
switch (req->rsk_ops->family) { switch (req->rsk_ops->family) {
case AF_INET: case AF_INET:
if (dom_entry->type == NETLBL_NLTYPE_ADDRSELECT) { entry = netlbl_domhsh_getentry_af4(secattr->domain,
struct inet_request_sock *req_inet = inet_rsk(req); inet_rsk(req)->rmt_addr);
af4_entry = netlbl_domhsh_getentry_af4(secattr->domain, if (entry == NULL) {
req_inet->rmt_addr); ret_val = -ENOENT;
if (af4_entry == NULL) { goto req_setattr_return;
ret_val = -ENOENT;
goto req_setattr_return;
}
proto_type = af4_entry->type;
proto_cv4 = af4_entry->type_def.cipsov4;
} else {
proto_type = dom_entry->type;
proto_cv4 = dom_entry->type_def.cipsov4;
} }
switch (proto_type) { switch (entry->type) {
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
ret_val = cipso_v4_req_setattr(req, proto_cv4, secattr); ret_val = cipso_v4_req_setattr(req,
entry->cipso, secattr);
break; break;
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
/* just delete the protocols we support for right now /* just delete the protocols we support for right now
...@@ -899,23 +883,21 @@ int netlbl_skbuff_setattr(struct sk_buff *skb, ...@@ -899,23 +883,21 @@ int netlbl_skbuff_setattr(struct sk_buff *skb,
{ {
int ret_val; int ret_val;
struct iphdr *hdr4; struct iphdr *hdr4;
struct netlbl_domaddr4_map *af4_entry; struct netlbl_dommap_def *entry;
rcu_read_lock(); rcu_read_lock();
switch (family) { switch (family) {
case AF_INET: case AF_INET:
hdr4 = ip_hdr(skb); hdr4 = ip_hdr(skb);
af4_entry = netlbl_domhsh_getentry_af4(secattr->domain, entry = netlbl_domhsh_getentry_af4(secattr->domain,hdr4->daddr);
hdr4->daddr); if (entry == NULL) {
if (af4_entry == NULL) {
ret_val = -ENOENT; ret_val = -ENOENT;
goto skbuff_setattr_return; goto skbuff_setattr_return;
} }
switch (af4_entry->type) { switch (entry->type) {
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
ret_val = cipso_v4_skbuff_setattr(skb, ret_val = cipso_v4_skbuff_setattr(skb, entry->cipso,
af4_entry->type_def.cipsov4, secattr);
secattr);
break; break;
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
/* just delete the protocols we support for right now /* just delete the protocols we support for right now
......
...@@ -104,7 +104,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ...@@ -104,7 +104,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
ret_val = -ENOMEM; ret_val = -ENOMEM;
goto add_failure; goto add_failure;
} }
entry->type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]); entry->def.type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]);
if (info->attrs[NLBL_MGMT_A_DOMAIN]) { if (info->attrs[NLBL_MGMT_A_DOMAIN]) {
size_t tmp_size = nla_len(info->attrs[NLBL_MGMT_A_DOMAIN]); size_t tmp_size = nla_len(info->attrs[NLBL_MGMT_A_DOMAIN]);
entry->domain = kmalloc(tmp_size, GFP_KERNEL); entry->domain = kmalloc(tmp_size, GFP_KERNEL);
...@@ -116,12 +116,12 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ...@@ -116,12 +116,12 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size); info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size);
} }
/* NOTE: internally we allow/use a entry->type value of /* NOTE: internally we allow/use a entry->def.type value of
* NETLBL_NLTYPE_ADDRSELECT but we don't currently allow users * NETLBL_NLTYPE_ADDRSELECT but we don't currently allow users
* to pass that as a protocol value because we need to know the * to pass that as a protocol value because we need to know the
* "real" protocol */ * "real" protocol */
switch (entry->type) { switch (entry->def.type) {
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
break; break;
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
...@@ -132,7 +132,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ...@@ -132,7 +132,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
cipsov4 = cipso_v4_doi_getdef(tmp_val); cipsov4 = cipso_v4_doi_getdef(tmp_val);
if (cipsov4 == NULL) if (cipsov4 == NULL)
goto add_failure; goto add_failure;
entry->type_def.cipsov4 = cipsov4; entry->def.cipso = cipsov4;
break; break;
default: default:
goto add_failure; goto add_failure;
...@@ -172,9 +172,9 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ...@@ -172,9 +172,9 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
map->list.addr = addr->s_addr & mask->s_addr; map->list.addr = addr->s_addr & mask->s_addr;
map->list.mask = mask->s_addr; map->list.mask = mask->s_addr;
map->list.valid = 1; map->list.valid = 1;
map->type = entry->type; map->def.type = entry->def.type;
if (cipsov4) if (cipsov4)
map->type_def.cipsov4 = cipsov4; map->def.cipso = cipsov4;
ret_val = netlbl_af4list_add(&map->list, &addrmap->list4); ret_val = netlbl_af4list_add(&map->list, &addrmap->list4);
if (ret_val != 0) { if (ret_val != 0) {
...@@ -182,8 +182,8 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ...@@ -182,8 +182,8 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
goto add_failure; goto add_failure;
} }
entry->type = NETLBL_NLTYPE_ADDRSELECT; entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
entry->type_def.addrsel = addrmap; entry->def.addrsel = addrmap;
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
} else if (info->attrs[NLBL_MGMT_A_IPV6ADDR]) { } else if (info->attrs[NLBL_MGMT_A_IPV6ADDR]) {
struct in6_addr *addr; struct in6_addr *addr;
...@@ -223,7 +223,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ...@@ -223,7 +223,7 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
map->list.addr.s6_addr32[3] &= mask->s6_addr32[3]; map->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
map->list.mask = *mask; map->list.mask = *mask;
map->list.valid = 1; map->list.valid = 1;
map->type = entry->type; map->def.type = entry->def.type;
ret_val = netlbl_af6list_add(&map->list, &addrmap->list6); ret_val = netlbl_af6list_add(&map->list, &addrmap->list6);
if (ret_val != 0) { if (ret_val != 0) {
...@@ -231,8 +231,8 @@ static int netlbl_mgmt_add_common(struct genl_info *info, ...@@ -231,8 +231,8 @@ static int netlbl_mgmt_add_common(struct genl_info *info,
goto add_failure; goto add_failure;
} }
entry->type = NETLBL_NLTYPE_ADDRSELECT; entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
entry->type_def.addrsel = addrmap; entry->def.addrsel = addrmap;
#endif /* IPv6 */ #endif /* IPv6 */
} }
...@@ -281,14 +281,13 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb, ...@@ -281,14 +281,13 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb,
return ret_val; return ret_val;
} }
switch (entry->type) { switch (entry->def.type) {
case NETLBL_NLTYPE_ADDRSELECT: case NETLBL_NLTYPE_ADDRSELECT:
nla_a = nla_nest_start(skb, NLBL_MGMT_A_SELECTORLIST); nla_a = nla_nest_start(skb, NLBL_MGMT_A_SELECTORLIST);
if (nla_a == NULL) if (nla_a == NULL)
return -ENOMEM; return -ENOMEM;
netlbl_af4list_foreach_rcu(iter4, netlbl_af4list_foreach_rcu(iter4, &entry->def.addrsel->list4) {
&entry->type_def.addrsel->list4) {
struct netlbl_domaddr4_map *map4; struct netlbl_domaddr4_map *map4;
struct in_addr addr_struct; struct in_addr addr_struct;
...@@ -310,13 +309,13 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb, ...@@ -310,13 +309,13 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb,
return ret_val; return ret_val;
map4 = netlbl_domhsh_addr4_entry(iter4); map4 = netlbl_domhsh_addr4_entry(iter4);
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL, ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
map4->type); map4->def.type);
if (ret_val != 0) if (ret_val != 0)
return ret_val; return ret_val;
switch (map4->type) { switch (map4->def.type) {
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI, ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI,
map4->type_def.cipsov4->doi); map4->def.cipso->doi);
if (ret_val != 0) if (ret_val != 0)
return ret_val; return ret_val;
break; break;
...@@ -325,8 +324,7 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb, ...@@ -325,8 +324,7 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb,
nla_nest_end(skb, nla_b); nla_nest_end(skb, nla_b);
} }
#if IS_ENABLED(CONFIG_IPV6) #if IS_ENABLED(CONFIG_IPV6)
netlbl_af6list_foreach_rcu(iter6, netlbl_af6list_foreach_rcu(iter6, &entry->def.addrsel->list6) {
&entry->type_def.addrsel->list6) {
struct netlbl_domaddr6_map *map6; struct netlbl_domaddr6_map *map6;
nla_b = nla_nest_start(skb, NLBL_MGMT_A_ADDRSELECTOR); nla_b = nla_nest_start(skb, NLBL_MGMT_A_ADDRSELECTOR);
...@@ -345,7 +343,7 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb, ...@@ -345,7 +343,7 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb,
return ret_val; return ret_val;
map6 = netlbl_domhsh_addr6_entry(iter6); map6 = netlbl_domhsh_addr6_entry(iter6);
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL, ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
map6->type); map6->def.type);
if (ret_val != 0) if (ret_val != 0)
return ret_val; return ret_val;
...@@ -356,14 +354,14 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb, ...@@ -356,14 +354,14 @@ static int netlbl_mgmt_listentry(struct sk_buff *skb,
nla_nest_end(skb, nla_a); nla_nest_end(skb, nla_a);
break; break;
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL, entry->type); ret_val = nla_put_u32(skb,NLBL_MGMT_A_PROTOCOL,entry->def.type);
break; break;
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL, entry->type); ret_val = nla_put_u32(skb,NLBL_MGMT_A_PROTOCOL,entry->def.type);
if (ret_val != 0) if (ret_val != 0)
return ret_val; return ret_val;
ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI, ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI,
entry->type_def.cipsov4->doi); entry->def.cipso->doi);
break; break;
} }
......
...@@ -1541,7 +1541,7 @@ int __init netlbl_unlabel_defconf(void) ...@@ -1541,7 +1541,7 @@ int __init netlbl_unlabel_defconf(void)
entry = kzalloc(sizeof(*entry), GFP_KERNEL); entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (entry == NULL) if (entry == NULL)
return -ENOMEM; return -ENOMEM;
entry->type = NETLBL_NLTYPE_UNLABELED; entry->def.type = NETLBL_NLTYPE_UNLABELED;
ret_val = netlbl_domhsh_add_default(entry, &audit_info); ret_val = netlbl_domhsh_add_default(entry, &audit_info);
if (ret_val != 0) if (ret_val != 0)
return ret_val; return ret_val;
......
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