diff mbox

[2/3] Smack: Fix the issue of permission denied error in ipv6 hook

Message ID 1479877319-12433-1-git-send-email-vishal.goel@samsung.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vishal Goel Nov. 23, 2016, 5:01 a.m. UTC
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>
---
 security/smack/smack.h     | 1 +
 security/smack/smack_lsm.c | 5 +++--
 2 files changed, 4 insertions(+), 2 deletions(-)

Comments

Casey Schaufler Nov. 28, 2016, 10:32 p.m. UTC | #1
On 11/22/2016 9:01 PM, Vishal Goel wrote:
> 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>

Acked-by: Casey Schaufler <casey@schaufler-ca.com>

I have queued this for 4.11 as it's too late for 4.10 with the
minor modifications mentioned inline.

> ---
>  security/smack/smack.h     | 1 +
>  security/smack/smack_lsm.c | 5 +++--
>  2 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/security/smack/smack.h b/security/smack/smack.h
> index 51fd301..7d92c74 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			sock_type;	/*Socket type*/

Changed sock_type to smk_sock_type throughout.
Fixed the comment to be /* Socket type */

>  };
>  #endif /* SMACK_IPV6_PORT_LABELING */
>  
> diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
> index 404919d..0ed61e9 100644
> --- a/security/smack/smack_lsm.c
> +++ b/security/smack/smack_lsm.c
> @@ -2636,7 +2636,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->sock_type != sock->type)
>  			continue;
>  		spp->smk_port = port;
>  		spp->smk_sock = sk;
> @@ -2657,6 +2657,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->sock_type = sock->type;
>  
>  	mutex_lock(&smack_ipv6_lock);
>  	list_add_rcu(&spp->list, &smk_ipv6_port_list);
> @@ -2713,7 +2714,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->sock_type != sk->sk_type)
>  			continue;
>  		object = spp->smk_in;
>  		if (act == SMK_CONNECTING)

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/security/smack/smack.h b/security/smack/smack.h
index 51fd301..7d92c74 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			sock_type;	/*Socket type*/
 };
 #endif /* SMACK_IPV6_PORT_LABELING */
 
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 404919d..0ed61e9 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2636,7 +2636,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->sock_type != sock->type)
 			continue;
 		spp->smk_port = port;
 		spp->smk_sock = sk;
@@ -2657,6 +2657,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->sock_type = sock->type;
 
 	mutex_lock(&smack_ipv6_lock);
 	list_add_rcu(&spp->list, &smk_ipv6_port_list);
@@ -2713,7 +2714,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->sock_type != sk->sk_type)
 			continue;
 		object = spp->smk_in;
 		if (act == SMK_CONNECTING)