| From stable-bounces@linux.kernel.org Tue May 12 14:03:40 2009 |
| From: Paul Moore <paul.moore@hp.com> |
| Date: Fri, 08 May 2009 17:58:56 -0400 |
| Subject: selinux: Set the proper NetLabel security attributes for connection requests |
| To: linux-security-module@vger.kernel.org |
| Cc: stable@kernel.org |
| Message-ID: <20090508215855.12179.53798.stgit@flek.lan> |
| |
| From: Paul Moore <paul.moore@hp.com> |
| |
| [NOTE: based on 389fb800ac8be2832efedd19978a2b8ced37eb61] |
| |
| This patch ensures the correct labeling of incoming connection requests |
| responses via NetLabel by enabling the recent changes to NetLabel and the |
| SELinux/Netlabel glue code. |
| |
| Signed-off-by: Paul Moore <paul.moore@hp.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| --- |
| |
| security/selinux/hooks.c | 45 +++++++++--------------------------- |
| security/selinux/include/netlabel.h | 6 +--- |
| security/selinux/netlabel.c | 8 +----- |
| 3 files changed, 16 insertions(+), 43 deletions(-) |
| |
| --- a/security/selinux/hooks.c |
| +++ b/security/selinux/hooks.c |
| @@ -311,7 +311,7 @@ static int sk_alloc_security(struct sock |
| ssec->sid = SECINITSID_UNLABELED; |
| sk->sk_security = ssec; |
| |
| - selinux_netlbl_sk_security_reset(ssec, family); |
| + selinux_netlbl_sk_security_reset(ssec); |
| |
| return 0; |
| } |
| @@ -2952,7 +2952,6 @@ static void selinux_inode_getsecid(const |
| static int selinux_revalidate_file_permission(struct file *file, int mask) |
| { |
| const struct cred *cred = current_cred(); |
| - int rc; |
| struct inode *inode = file->f_path.dentry->d_inode; |
| |
| if (!mask) { |
| @@ -2964,30 +2963,16 @@ static int selinux_revalidate_file_permi |
| if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) |
| mask |= MAY_APPEND; |
| |
| - rc = file_has_perm(cred, file, |
| - file_mask_to_av(inode->i_mode, mask)); |
| - if (rc) |
| - return rc; |
| - |
| - return selinux_netlbl_inode_permission(inode, mask); |
| + return file_has_perm(cred, file, file_mask_to_av(inode->i_mode, mask)); |
| } |
| |
| static int selinux_file_permission(struct file *file, int mask) |
| { |
| - struct inode *inode = file->f_path.dentry->d_inode; |
| - struct file_security_struct *fsec = file->f_security; |
| - struct inode_security_struct *isec = inode->i_security; |
| - u32 sid = current_sid(); |
| - |
| if (!mask) { |
| /* No permission to check. Existence test. */ |
| return 0; |
| } |
| |
| - if (sid == fsec->sid && fsec->isid == isec->sid |
| - && fsec->pseqno == avc_policy_seqno()) |
| - return selinux_netlbl_inode_permission(inode, mask); |
| - |
| return selinux_revalidate_file_permission(file, mask); |
| } |
| |
| @@ -3990,13 +3975,7 @@ static int selinux_socket_accept(struct |
| static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, |
| int size) |
| { |
| - int rc; |
| - |
| - rc = socket_has_perm(current, sock, SOCKET__WRITE); |
| - if (rc) |
| - return rc; |
| - |
| - return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE); |
| + return socket_has_perm(current, sock, SOCKET__WRITE); |
| } |
| |
| static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, |
| @@ -4384,7 +4363,7 @@ static void selinux_sk_clone_security(co |
| newssec->peer_sid = ssec->peer_sid; |
| newssec->sclass = ssec->sclass; |
| |
| - selinux_netlbl_sk_security_reset(newssec, newsk->sk_family); |
| + selinux_netlbl_sk_security_reset(newssec); |
| } |
| |
| static void selinux_sk_getsecid(struct sock *sk, u32 *secid) |
| @@ -4429,15 +4408,15 @@ static int selinux_inet_conn_request(str |
| req->secid = sksec->sid; |
| req->peer_secid = SECSID_NULL; |
| return 0; |
| + } else { |
| + err = security_sid_mls_copy(sksec->sid, peersid, &newsid); |
| + if (err) |
| + return err; |
| + req->secid = newsid; |
| + req->peer_secid = peersid; |
| } |
| |
| - err = security_sid_mls_copy(sksec->sid, peersid, &newsid); |
| - if (err) |
| - return err; |
| - |
| - req->secid = newsid; |
| - req->peer_secid = peersid; |
| - return 0; |
| + return selinux_netlbl_inet_conn_request(req, family); |
| } |
| |
| static void selinux_inet_csk_clone(struct sock *newsk, |
| @@ -4454,7 +4433,7 @@ static void selinux_inet_csk_clone(struc |
| |
| /* We don't need to take any sort of lock here as we are the only |
| * thread with access to newsksec */ |
| - selinux_netlbl_sk_security_reset(newsksec, req->rsk_ops->family); |
| + selinux_netlbl_inet_csk_clone(newsk, req->rsk_ops->family); |
| } |
| |
| static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) |
| --- a/security/selinux/include/netlabel.h |
| +++ b/security/selinux/include/netlabel.h |
| @@ -43,8 +43,7 @@ void selinux_netlbl_cache_invalidate(voi |
| void selinux_netlbl_err(struct sk_buff *skb, int error, int gateway); |
| |
| void selinux_netlbl_sk_security_free(struct sk_security_struct *ssec); |
| -void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, |
| - int family); |
| +void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec); |
| |
| int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, |
| u16 family, |
| @@ -87,8 +86,7 @@ static inline void selinux_netlbl_sk_sec |
| } |
| |
| static inline void selinux_netlbl_sk_security_reset( |
| - struct sk_security_struct *ssec, |
| - int family) |
| + struct sk_security_struct *ssec) |
| { |
| return; |
| } |
| --- a/security/selinux/netlabel.c |
| +++ b/security/selinux/netlabel.c |
| @@ -188,13 +188,9 @@ void selinux_netlbl_sk_security_free(str |
| * The caller is responsibile for all the NetLabel sk_security_struct locking. |
| * |
| */ |
| -void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec, |
| - int family) |
| +void selinux_netlbl_sk_security_reset(struct sk_security_struct *ssec) |
| { |
| - if (family == PF_INET) |
| - ssec->nlbl_state = NLBL_REQUIRE; |
| - else |
| - ssec->nlbl_state = NLBL_UNSET; |
| + ssec->nlbl_state = NLBL_UNSET; |
| } |
| |
| /** |