aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index b1f6fb36c699..bfe122764c98 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2682,4 +2682,41 @@ u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb)
2682 2682
2683 return peer_sid; 2683 return peer_sid;
2684} 2684}
2685
2686/**
2687 * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel
2688 * @sock: the socket
2689 * @level: the socket level or protocol
2690 * @optname: the socket option name
2691 *
2692 * Description:
2693 * Check the setsockopt() call and if the user is trying to replace the IP
2694 * options on a socket and a NetLabel is in place for the socket deny the
2695 * access; otherwise allow the access. Returns zero when the access is
2696 * allowed, -EACCES when denied, and other negative values on error.
2697 *
2698 */
2699int selinux_netlbl_socket_setsockopt(struct socket *sock,
2700 int level,
2701 int optname)
2702{
2703 int rc = 0;
2704 struct inode *inode = SOCK_INODE(sock);
2705 struct sk_security_struct *sksec = sock->sk->sk_security;
2706 struct inode_security_struct *isec = inode->i_security;
2707 struct netlbl_lsm_secattr secattr;
2708
2709 mutex_lock(&isec->lock);
2710 if (level == IPPROTO_IP && optname == IP_OPTIONS &&
2711 sksec->nlbl_state == NLBL_LABELED) {
2712 netlbl_secattr_init(&secattr);
2713 rc = netlbl_socket_getattr(sock, &secattr);
2714 if (rc == 0 && (secattr.cache || secattr.mls_lvl_vld))
2715 rc = -EACCES;
2716 netlbl_secattr_destroy(&secattr);
2717 }
2718 mutex_unlock(&isec->lock);
2719
2720 return rc;
2721}
2685#endif /* CONFIG_NETLABEL */ 2722#endif /* CONFIG_NETLABEL */