diff options
Diffstat (limited to 'security/smack/smack_lsm.c')
-rw-r--r-- | security/smack/smack_lsm.c | 94 |
1 files changed, 86 insertions, 8 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 1fa72317bbec..81b30e32c526 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -52,8 +52,11 @@ #define SMK_RECEIVING 1 #define SMK_SENDING 2 +#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) LIST_HEAD(smk_ipv6_port_list); +#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ static struct kmem_cache *smack_inode_cache; +int smack_enabled; #ifdef CONFIG_SECURITY_SMACK_BRINGUP static void smk_bu_mode(int mode, char *s) @@ -2213,6 +2216,7 @@ static int smack_netlabel_send(struct sock *sk, struct sockaddr_in *sap) return smack_netlabel(sk, sk_lbl); } +#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) /** * smk_ipv6_port_label - Smack port access table management * @sock: socket @@ -2362,6 +2366,7 @@ auditout: rc = smk_bu_note("IPv6 port check", skp, object, MAY_WRITE, rc); return rc; } +#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ /** * smack_inode_setsecurity - set smack xattrs @@ -2422,8 +2427,10 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, } else return -EOPNOTSUPP; +#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) if (sock->sk->sk_family == PF_INET6) smk_ipv6_port_label(sock, NULL); +#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ return 0; } @@ -2451,6 +2458,7 @@ static int smack_socket_post_create(struct socket *sock, int family, return smack_netlabel(sock->sk, SMACK_CIPSO_SOCKET); } +#ifndef CONFIG_SECURITY_SMACK_NETFILTER /** * smack_socket_bind - record port binding information. * @sock: the socket @@ -2464,11 +2472,14 @@ static int smack_socket_post_create(struct socket *sock, int family, static int smack_socket_bind(struct socket *sock, struct sockaddr *address, int addrlen) { +#if IS_ENABLED(CONFIG_IPV6) if (sock->sk != NULL && sock->sk->sk_family == PF_INET6) smk_ipv6_port_label(sock, address); +#endif return 0; } +#endif /* !CONFIG_SECURITY_SMACK_NETFILTER */ /** * smack_socket_connect - connect access check @@ -2497,8 +2508,10 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap, case PF_INET6: if (addrlen < sizeof(struct sockaddr_in6)) return -EINVAL; +#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) rc = smk_ipv6_port_check(sock->sk, (struct sockaddr_in6 *)sap, SMK_CONNECTING); +#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ break; } return rc; @@ -3381,7 +3394,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, int size) { struct sockaddr_in *sip = (struct sockaddr_in *) msg->msg_name; +#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) struct sockaddr_in6 *sap = (struct sockaddr_in6 *) msg->msg_name; +#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ int rc = 0; /* @@ -3395,7 +3410,9 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, rc = smack_netlabel_send(sock->sk, sip); break; case AF_INET6: +#if IS_ENABLED(CONFIG_IPV6) && !defined(CONFIG_SECURITY_SMACK_NETFILTER) rc = smk_ipv6_port_check(sock->sk, sap, SMK_SENDING); +#endif /* CONFIG_IPV6 && !CONFIG_SECURITY_SMACK_NETFILTER */ break; } return rc; @@ -3486,6 +3503,7 @@ static struct smack_known *smack_from_secattr(struct netlbl_lsm_secattr *sap, return smack_net_ambient; } +#if IS_ENABLED(CONFIG_IPV6) static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) { u8 nexthdr; @@ -3532,6 +3550,7 @@ static int smk_skb_to_addr_ipv6(struct sk_buff *skb, struct sockaddr_in6 *sip) } return proto; } +#endif /* CONFIG_IPV6 */ /** * smack_socket_sock_rcv_skb - Smack packet delivery access check @@ -3544,15 +3563,30 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) { struct netlbl_lsm_secattr secattr; struct socket_smack *ssp = sk->sk_security; - struct smack_known *skp; - struct sockaddr_in6 sadd; + struct smack_known *skp = NULL; int rc = 0; struct smk_audit_info ad; #ifdef CONFIG_AUDIT struct lsm_network_audit net; #endif +#if IS_ENABLED(CONFIG_IPV6) + struct sockaddr_in6 sadd; + int proto; +#endif /* CONFIG_IPV6 */ + switch (sk->sk_family) { case PF_INET: +#ifdef CONFIG_SECURITY_SMACK_NETFILTER + /* + * If there is a secmark use it rather than the CIPSO label. + * If there is no secmark fall back to CIPSO. + * The secmark is assumed to reflect policy better. + */ + if (skb && skb->secmark != 0) { + skp = smack_from_secid(skb->secmark); + goto access_check; + } +#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ /* * Translate what netlabel gave us. */ @@ -3566,6 +3600,9 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) netlbl_secattr_destroy(&secattr); +#ifdef CONFIG_SECURITY_SMACK_NETFILTER +access_check: +#endif #ifdef CONFIG_AUDIT smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); ad.a.u.net->family = sk->sk_family; @@ -3584,14 +3621,32 @@ static int smack_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) if (rc != 0) netlbl_skbuff_err(skb, rc, 0); break; +#if IS_ENABLED(CONFIG_IPV6) case PF_INET6: - rc = smk_skb_to_addr_ipv6(skb, &sadd); - if (rc == IPPROTO_UDP || rc == IPPROTO_TCP) - rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); + proto = smk_skb_to_addr_ipv6(skb, &sadd); + if (proto != IPPROTO_UDP && proto != IPPROTO_TCP) + break; +#ifdef CONFIG_SECURITY_SMACK_NETFILTER + if (skb && skb->secmark != 0) + skp = smack_from_secid(skb->secmark); else - rc = 0; + skp = smack_net_ambient; +#ifdef CONFIG_AUDIT + smk_ad_init_net(&ad, __func__, LSM_AUDIT_DATA_NET, &net); + ad.a.u.net->family = sk->sk_family; + ad.a.u.net->netif = skb->skb_iif; + ipv6_skb_to_auditdata(skb, &ad.a, NULL); +#endif /* CONFIG_AUDIT */ + rc = smk_access(skp, ssp->smk_in, MAY_WRITE, &ad); + rc = smk_bu_note("IPv6 delivery", skp, ssp->smk_in, + MAY_WRITE, rc); +#else /* CONFIG_SECURITY_SMACK_NETFILTER */ + rc = smk_ipv6_port_check(sk, &sadd, SMK_RECEIVING); +#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ break; +#endif /* CONFIG_IPV6 */ } + return rc; } @@ -3653,16 +3708,25 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, if (skb != NULL) { if (skb->protocol == htons(ETH_P_IP)) family = PF_INET; +#if IS_ENABLED(CONFIG_IPV6) else if (skb->protocol == htons(ETH_P_IPV6)) family = PF_INET6; +#endif /* CONFIG_IPV6 */ } if (family == PF_UNSPEC && sock != NULL) family = sock->sk->sk_family; - if (family == PF_UNIX) { + switch (family) { + case PF_UNIX: ssp = sock->sk->sk_security; s = ssp->smk_out->smk_secid; - } else if (family == PF_INET || family == PF_INET6) { + break; + case PF_INET: +#ifdef CONFIG_SECURITY_SMACK_NETFILTER + s = skb->secmark; + if (s != 0) + break; +#endif /* * Translate what netlabel gave us. */ @@ -3675,6 +3739,14 @@ static int smack_socket_getpeersec_dgram(struct socket *sock, s = skp->smk_secid; } netlbl_secattr_destroy(&secattr); + break; +#if IS_ENABLED(CONFIG_IPV6) + case PF_INET6: +#ifdef CONFIG_SECURITY_SMACK_NETFILTER + s = skb->secmark; +#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ + break; +#endif /* CONFIG_IPV6 */ } *secid = s; if (s == 0) @@ -3730,6 +3802,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, struct lsm_network_audit net; #endif +#if IS_ENABLED(CONFIG_IPV6) if (family == PF_INET6) { /* * Handle mapped IPv4 packets arriving @@ -3741,6 +3814,7 @@ static int smack_inet_conn_request(struct sock *sk, struct sk_buff *skb, else return 0; } +#endif /* CONFIG_IPV6 */ netlbl_secattr_init(&secattr); rc = netlbl_skbuff_getattr(skb, family, &secattr); @@ -4199,7 +4273,9 @@ struct security_operations smack_ops = { .unix_may_send = smack_unix_may_send, .socket_post_create = smack_socket_post_create, +#ifndef CONFIG_SECURITY_SMACK_NETFILTER .socket_bind = smack_socket_bind, +#endif /* CONFIG_SECURITY_SMACK_NETFILTER */ .socket_connect = smack_socket_connect, .socket_sendmsg = smack_socket_sendmsg, .socket_sock_rcv_skb = smack_socket_sock_rcv_skb, @@ -4280,6 +4356,8 @@ static __init int smack_init(void) if (!security_module_enable(&smack_ops)) return 0; + smack_enabled = 1; + smack_inode_cache = KMEM_CACHE(inode_smack, 0); if (!smack_inode_cache) return -ENOMEM; |