summaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorVishal Goel <vishal.goel@samsung.com>2016-11-23 10:31:59 +0530
committerCasey Schaufler <casey@schaufler-ca.com>2017-01-10 09:47:20 -0800
commit9d44c97384fdc04585c5d5c985fe88ba7285b5ac (patch)
tree64a6b1d1b3203b6234ed2bcc1099d447e7442d3d /security
parent3c7ce3427106f0fa2d8593f9fd8f82c494215782 (diff)
downloadlinux-stable-9d44c97384fdc04585c5d5c985fe88ba7285b5ac.tar.gz
linux-stable-9d44c97384fdc04585c5d5c985fe88ba7285b5ac.tar.bz2
linux-stable-9d44c97384fdc04585c5d5c985fe88ba7285b5ac.zip
Smack: Fix the issue of permission denied error in ipv6 hook
Permission denied error comes when 2 IPv6 servers are running and client tries to connect one of them. Scenario is that both servers are using same IP and port but different protocols(Udp and tcp). They are using different SMACK64IPIN labels.Tcp server is using "test" and udp server is using "test-in". When we try to run tcp client with SMACK64IPOUT label as "test", then connection denied error comes. It should not happen since both tcp server and client labels are same.This happens because there is no check for protocol in smk_ipv6_port_label() function while searching for the earlier port entry. It checks whether there is an existing port entry on the basis of port only. So it updates the earlier port entry in the list. Due to which smack label gets changed for earlier entry in the "smk_ipv6_port_list" list and permission denied error comes. Now a check is added for socket type also.Now if 2 processes use same port but different protocols (tcp or udp), then 2 different port entries will be added in the list. Similarly while checking smack access in smk_ipv6_port_check() function, port entry is searched on the basis of both port and protocol. Signed-off-by: Vishal Goel <vishal.goel@samsung.com> Signed-off-by: Himanshu Shukla <Himanshu.sh@samsung.com> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Diffstat (limited to 'security')
-rw-r--r--security/smack/smack.h1
-rw-r--r--security/smack/smack_lsm.c5
2 files changed, 4 insertions, 2 deletions
diff --git a/security/smack/smack.h b/security/smack/smack.h
index 77abe2efacae..73480ee07478 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -173,6 +173,7 @@ struct smk_port_label {
unsigned short smk_port; /* the port number */
struct smack_known *smk_in; /* inbound label */
struct smack_known *smk_out; /* outgoing label */
+ short smk_sock_type; /* Socket type */
};
#endif /* SMACK_IPV6_PORT_LABELING */
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index b76696b84e5c..5e4d2bdb38cb 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2635,7 +2635,7 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
*/
rcu_read_lock();
list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
- if (spp->smk_port != port)
+ if (spp->smk_port != port || spp->smk_sock_type != sock->type)
continue;
spp->smk_port = port;
spp->smk_sock = sk;
@@ -2656,6 +2656,7 @@ static void smk_ipv6_port_label(struct socket *sock, struct sockaddr *address)
spp->smk_sock = sk;
spp->smk_in = ssp->smk_in;
spp->smk_out = ssp->smk_out;
+ spp->smk_sock_type = sock->type;
mutex_lock(&smack_ipv6_lock);
list_add_rcu(&spp->list, &smk_ipv6_port_list);
@@ -2712,7 +2713,7 @@ static int smk_ipv6_port_check(struct sock *sk, struct sockaddr_in6 *address,
port = ntohs(address->sin6_port);
rcu_read_lock();
list_for_each_entry_rcu(spp, &smk_ipv6_port_list, list) {
- if (spp->smk_port != port)
+ if (spp->smk_port != port || spp->smk_sock_type != sk->sk_type)
continue;
object = spp->smk_in;
if (act == SMK_CONNECTING)