소스 검색

selinux: fix address family in bind() and connect() to match address/port

Since sctp_bindx() and sctp_connectx() can have multiple addresses,
sk_family can differ from sa_family. Therefore, selinux_socket_bind()
and selinux_socket_connect_helper(), which process sockaddr structure
(address and port), should use the address family from that structure
too, and not from the socket one.

The initialization of the data for the audit record is moved above,
in selinux_socket_bind(), so that there is no duplicate changes and
code.

Fixes: d452930fd3b9 ("selinux: Add SCTP support")
Suggested-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Alexey Kodanev <alexey.kodanev@oracle.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Alexey Kodanev 7 년 전
부모
커밋
88b7d370bb
1개의 변경된 파일7개의 추가작업 그리고 11개의 파일을 삭제
  1. 7 11
      security/selinux/hooks.c

+ 7 - 11
security/selinux/hooks.c

@@ -4622,6 +4622,11 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
 			goto err_af;
 			goto err_af;
 		}
 		}
 
 
+		ad.type = LSM_AUDIT_DATA_NET;
+		ad.u.net = &net;
+		ad.u.net->sport = htons(snum);
+		ad.u.net->family = family_sa;
+
 		if (snum) {
 		if (snum) {
 			int low, high;
 			int low, high;
 
 
@@ -4633,10 +4638,6 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
 						      snum, &sid);
 						      snum, &sid);
 				if (err)
 				if (err)
 					goto out;
 					goto out;
-				ad.type = LSM_AUDIT_DATA_NET;
-				ad.u.net = &net;
-				ad.u.net->sport = htons(snum);
-				ad.u.net->family = family;
 				err = avc_has_perm(&selinux_state,
 				err = avc_has_perm(&selinux_state,
 						   sksec->sid, sid,
 						   sksec->sid, sid,
 						   sksec->sclass,
 						   sksec->sclass,
@@ -4668,15 +4669,10 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in
 			break;
 			break;
 		}
 		}
 
 
-		err = sel_netnode_sid(addrp, family, &sid);
+		err = sel_netnode_sid(addrp, family_sa, &sid);
 		if (err)
 		if (err)
 			goto out;
 			goto out;
 
 
-		ad.type = LSM_AUDIT_DATA_NET;
-		ad.u.net = &net;
-		ad.u.net->sport = htons(snum);
-		ad.u.net->family = family;
-
 		if (family_sa == AF_INET)
 		if (family_sa == AF_INET)
 			ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
 			ad.u.net->v4info.saddr = addr4->sin_addr.s_addr;
 		else
 		else
@@ -4772,7 +4768,7 @@ static int selinux_socket_connect_helper(struct socket *sock,
 		ad.type = LSM_AUDIT_DATA_NET;
 		ad.type = LSM_AUDIT_DATA_NET;
 		ad.u.net = &net;
 		ad.u.net = &net;
 		ad.u.net->dport = htons(snum);
 		ad.u.net->dport = htons(snum);
-		ad.u.net->family = sk->sk_family;
+		ad.u.net->family = address->sa_family;
 		err = avc_has_perm(&selinux_state,
 		err = avc_has_perm(&selinux_state,
 				   sksec->sid, sid, sksec->sclass, perm, &ad);
 				   sksec->sid, sid, sksec->sclass, perm, &ad);
 		if (err)
 		if (err)