summaryrefslogtreecommitdiff
path: root/net/netlabel/netlabel_kapi.c
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2013-08-02 14:45:08 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-02 16:57:01 -0700
commit6a8b7f0c85f1f42eb8b6e68ef3d5ba8020d8e272 (patch)
tree2097e9baf7e2af21a6cc80206df4f3c58c8a4840 /net/netlabel/netlabel_kapi.c
parent5f671d6b4ec3e6d66c2a868738af2cdea09e7509 (diff)
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: Paul Moore <pmoore@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlabel/netlabel_kapi.c')
-rw-r--r--net/netlabel/netlabel_kapi.c88
1 files changed, 35 insertions, 53 deletions
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 7c94aedd0912..96a458e12f60 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -122,7 +122,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
}
if (addr == NULL && mask == NULL)
- entry->type = NETLBL_NLTYPE_UNLABELED;
+ entry->def.type = NETLBL_NLTYPE_UNLABELED;
else if (addr != NULL && mask != NULL) {
addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
if (addrmap == NULL)
@@ -137,7 +137,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
if (map4 == NULL)
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.mask = mask4->s_addr;
map4->list.valid = 1;
@@ -154,7 +154,7 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
if (map6 == NULL)
goto cfg_unlbl_map_add_failure;
- map6->type = NETLBL_NLTYPE_UNLABELED;
+ map6->def.type = NETLBL_NLTYPE_UNLABELED;
map6->list.addr = *addr6;
map6->list.addr.s6_addr32[0] &= mask6->s6_addr32[0];
map6->list.addr.s6_addr32[1] &= mask6->s6_addr32[1];
@@ -174,8 +174,8 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
break;
}
- entry->type_def.addrsel = addrmap;
- entry->type = NETLBL_NLTYPE_ADDRSELECT;
+ entry->def.addrsel = addrmap;
+ entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
} else {
ret_val = -EINVAL;
goto cfg_unlbl_map_add_failure;
@@ -355,8 +355,8 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
}
if (addr == NULL && mask == NULL) {
- entry->type_def.cipsov4 = doi_def;
- entry->type = NETLBL_NLTYPE_CIPSOV4;
+ entry->def.cipso = doi_def;
+ entry->def.type = NETLBL_NLTYPE_CIPSOV4;
} else if (addr != NULL && mask != NULL) {
addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC);
if (addrmap == NULL)
@@ -367,8 +367,8 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC);
if (addrinfo == NULL)
goto out_addrinfo;
- addrinfo->type_def.cipsov4 = doi_def;
- addrinfo->type = NETLBL_NLTYPE_CIPSOV4;
+ addrinfo->def.cipso = doi_def;
+ addrinfo->def.type = NETLBL_NLTYPE_CIPSOV4;
addrinfo->list.addr = addr->s_addr & mask->s_addr;
addrinfo->list.mask = mask->s_addr;
addrinfo->list.valid = 1;
@@ -376,8 +376,8 @@ int netlbl_cfg_cipsov4_map_add(u32 doi,
if (ret_val != 0)
goto cfg_cipsov4_map_add_failure;
- entry->type_def.addrsel = addrmap;
- entry->type = NETLBL_NLTYPE_ADDRSELECT;
+ entry->def.addrsel = addrmap;
+ entry->def.type = NETLBL_NLTYPE_ADDRSELECT;
} else {
ret_val = -EINVAL;
goto out_addrmap;
@@ -657,14 +657,14 @@ int netlbl_sock_setattr(struct sock *sk,
}
switch (family) {
case AF_INET:
- switch (dom_entry->type) {
+ switch (dom_entry->def.type) {
case NETLBL_NLTYPE_ADDRSELECT:
ret_val = -EDESTADDRREQ;
break;
case NETLBL_NLTYPE_CIPSOV4:
ret_val = cipso_v4_sock_setattr(sk,
- dom_entry->type_def.cipsov4,
- secattr);
+ dom_entry->def.cipso,
+ secattr);
break;
case NETLBL_NLTYPE_UNLABELED:
ret_val = 0;
@@ -754,23 +754,22 @@ int netlbl_conn_setattr(struct sock *sk,
{
int ret_val;
struct sockaddr_in *addr4;
- struct netlbl_domaddr4_map *af4_entry;
+ struct netlbl_dommap_def *entry;
rcu_read_lock();
switch (addr->sa_family) {
case AF_INET:
addr4 = (struct sockaddr_in *)addr;
- af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
- addr4->sin_addr.s_addr);
- if (af4_entry == NULL) {
+ entry = netlbl_domhsh_getentry_af4(secattr->domain,
+ addr4->sin_addr.s_addr);
+ if (entry == NULL) {
ret_val = -ENOENT;
goto conn_setattr_return;
}
- switch (af4_entry->type) {
+ switch (entry->type) {
case NETLBL_NLTYPE_CIPSOV4:
ret_val = cipso_v4_sock_setattr(sk,
- af4_entry->type_def.cipsov4,
- secattr);
+ entry->cipso, secattr);
break;
case NETLBL_NLTYPE_UNLABELED:
/* just delete the protocols we support for right now
@@ -812,36 +811,21 @@ int netlbl_req_setattr(struct request_sock *req,
const struct netlbl_lsm_secattr *secattr)
{
int ret_val;
- struct netlbl_dom_map *dom_entry;
- struct netlbl_domaddr4_map *af4_entry;
- u32 proto_type;
- struct cipso_v4_doi *proto_cv4;
+ struct netlbl_dommap_def *entry;
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) {
case AF_INET:
- if (dom_entry->type == NETLBL_NLTYPE_ADDRSELECT) {
- struct inet_request_sock *req_inet = inet_rsk(req);
- af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
- req_inet->rmt_addr);
- if (af4_entry == NULL) {
- 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;
+ entry = netlbl_domhsh_getentry_af4(secattr->domain,
+ inet_rsk(req)->rmt_addr);
+ if (entry == NULL) {
+ ret_val = -ENOENT;
+ goto req_setattr_return;
}
- switch (proto_type) {
+ switch (entry->type) {
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;
case NETLBL_NLTYPE_UNLABELED:
/* just delete the protocols we support for right now
@@ -899,23 +883,21 @@ int netlbl_skbuff_setattr(struct sk_buff *skb,
{
int ret_val;
struct iphdr *hdr4;
- struct netlbl_domaddr4_map *af4_entry;
+ struct netlbl_dommap_def *entry;
rcu_read_lock();
switch (family) {
case AF_INET:
hdr4 = ip_hdr(skb);
- af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
- hdr4->daddr);
- if (af4_entry == NULL) {
+ entry = netlbl_domhsh_getentry_af4(secattr->domain,hdr4->daddr);
+ if (entry == NULL) {
ret_val = -ENOENT;
goto skbuff_setattr_return;
}
- switch (af4_entry->type) {
+ switch (entry->type) {
case NETLBL_NLTYPE_CIPSOV4:
- ret_val = cipso_v4_skbuff_setattr(skb,
- af4_entry->type_def.cipsov4,
- secattr);
+ ret_val = cipso_v4_skbuff_setattr(skb, entry->cipso,
+ secattr);
break;
case NETLBL_NLTYPE_UNLABELED:
/* just delete the protocols we support for right now