aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c137
-rw-r--r--security/selinux/xfrm.c1
2 files changed, 93 insertions, 45 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 4e5989d584ce..1dc935f7b919 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3328,8 +3328,9 @@ static int selinux_socket_unix_stream_connect(struct socket *sock,
3328 /* server child socket */ 3328 /* server child socket */
3329 ssec = newsk->sk_security; 3329 ssec = newsk->sk_security;
3330 ssec->peer_sid = isec->sid; 3330 ssec->peer_sid = isec->sid;
3331 3331 err = security_sid_mls_copy(other_isec->sid, ssec->peer_sid, &ssec->sid);
3332 return 0; 3332
3333 return err;
3333} 3334}
3334 3335
3335static int selinux_socket_unix_may_send(struct socket *sock, 3336static int selinux_socket_unix_may_send(struct socket *sock,
@@ -3355,11 +3356,29 @@ static int selinux_socket_unix_may_send(struct socket *sock,
3355} 3356}
3356 3357
3357static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, 3358static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
3358 struct avc_audit_data *ad, u32 sock_sid, u16 sock_class, 3359 struct avc_audit_data *ad, u16 family, char *addrp, int len)
3359 u16 family, char *addrp, int len)
3360{ 3360{
3361 int err = 0; 3361 int err = 0;
3362 u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0; 3362 u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
3363 struct socket *sock;
3364 u16 sock_class = 0;
3365 u32 sock_sid = 0;
3366
3367 read_lock_bh(&sk->sk_callback_lock);
3368 sock = sk->sk_socket;
3369 if (sock) {
3370 struct inode *inode;
3371 inode = SOCK_INODE(sock);
3372 if (inode) {
3373 struct inode_security_struct *isec;
3374 isec = inode->i_security;
3375 sock_sid = isec->sid;
3376 sock_class = isec->sclass;
3377 }
3378 }
3379 read_unlock_bh(&sk->sk_callback_lock);
3380 if (!sock_sid)
3381 goto out;
3363 3382
3364 if (!skb->dev) 3383 if (!skb->dev)
3365 goto out; 3384 goto out;
@@ -3419,12 +3438,10 @@ out:
3419static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) 3438static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3420{ 3439{
3421 u16 family; 3440 u16 family;
3422 u16 sock_class = 0;
3423 char *addrp; 3441 char *addrp;
3424 int len, err = 0; 3442 int len, err = 0;
3425 u32 sock_sid = 0;
3426 struct socket *sock;
3427 struct avc_audit_data ad; 3443 struct avc_audit_data ad;
3444 struct sk_security_struct *sksec = sk->sk_security;
3428 3445
3429 family = sk->sk_family; 3446 family = sk->sk_family;
3430 if (family != PF_INET && family != PF_INET6) 3447 if (family != PF_INET && family != PF_INET6)
@@ -3434,22 +3451,6 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3434 if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP)) 3451 if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP))
3435 family = PF_INET; 3452 family = PF_INET;
3436 3453
3437 read_lock_bh(&sk->sk_callback_lock);
3438 sock = sk->sk_socket;
3439 if (sock) {
3440 struct inode *inode;
3441 inode = SOCK_INODE(sock);
3442 if (inode) {
3443 struct inode_security_struct *isec;
3444 isec = inode->i_security;
3445 sock_sid = isec->sid;
3446 sock_class = isec->sclass;
3447 }
3448 }
3449 read_unlock_bh(&sk->sk_callback_lock);
3450 if (!sock_sid)
3451 goto out;
3452
3453 AVC_AUDIT_DATA_INIT(&ad, NET); 3454 AVC_AUDIT_DATA_INIT(&ad, NET);
3454 ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]"; 3455 ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
3455 ad.u.net.family = family; 3456 ad.u.net.family = family;
@@ -3459,16 +3460,15 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3459 goto out; 3460 goto out;
3460 3461
3461 if (selinux_compat_net) 3462 if (selinux_compat_net)
3462 err = selinux_sock_rcv_skb_compat(sk, skb, &ad, sock_sid, 3463 err = selinux_sock_rcv_skb_compat(sk, skb, &ad, family,
3463 sock_class, family,
3464 addrp, len); 3464 addrp, len);
3465 else 3465 else
3466 err = avc_has_perm(sock_sid, skb->secmark, SECCLASS_PACKET, 3466 err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET,
3467 PACKET__RECV, &ad); 3467 PACKET__RECV, &ad);
3468 if (err) 3468 if (err)
3469 goto out; 3469 goto out;
3470 3470
3471 err = selinux_xfrm_sock_rcv_skb(sock_sid, skb, &ad); 3471 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
3472out: 3472out:
3473 return err; 3473 return err;
3474} 3474}
@@ -3572,6 +3572,49 @@ static void selinux_sk_getsecid(struct sock *sk, u32 *secid)
3572 } 3572 }
3573} 3573}
3574 3574
3575void selinux_sock_graft(struct sock* sk, struct socket *parent)
3576{
3577 struct inode_security_struct *isec = SOCK_INODE(parent)->i_security;
3578 struct sk_security_struct *sksec = sk->sk_security;
3579
3580 isec->sid = sksec->sid;
3581}
3582
3583int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3584 struct request_sock *req)
3585{
3586 struct sk_security_struct *sksec = sk->sk_security;
3587 int err;
3588 u32 newsid = 0;
3589 u32 peersid;
3590
3591 err = selinux_xfrm_decode_session(skb, &peersid, 0);
3592 BUG_ON(err);
3593
3594 err = security_sid_mls_copy(sksec->sid, peersid, &newsid);
3595 if (err)
3596 return err;
3597
3598 req->secid = newsid;
3599 return 0;
3600}
3601
3602void selinux_inet_csk_clone(struct sock *newsk, const struct request_sock *req)
3603{
3604 struct sk_security_struct *newsksec = newsk->sk_security;
3605
3606 newsksec->sid = req->secid;
3607 /* NOTE: Ideally, we should also get the isec->sid for the
3608 new socket in sync, but we don't have the isec available yet.
3609 So we will wait until sock_graft to do it, by which
3610 time it will have been created and available. */
3611}
3612
3613void selinux_req_classify_flow(const struct request_sock *req, struct flowi *fl)
3614{
3615 fl->secid = req->secid;
3616}
3617
3575static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) 3618static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
3576{ 3619{
3577 int err = 0; 3620 int err = 0;
@@ -3611,12 +3654,24 @@ out:
3611#ifdef CONFIG_NETFILTER 3654#ifdef CONFIG_NETFILTER
3612 3655
3613static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev, 3656static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device *dev,
3614 struct inode_security_struct *isec,
3615 struct avc_audit_data *ad, 3657 struct avc_audit_data *ad,
3616 u16 family, char *addrp, int len) 3658 u16 family, char *addrp, int len)
3617{ 3659{
3618 int err; 3660 int err = 0;
3619 u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0; 3661 u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0;
3662 struct socket *sock;
3663 struct inode *inode;
3664 struct inode_security_struct *isec;
3665
3666 sock = sk->sk_socket;
3667 if (!sock)
3668 goto out;
3669
3670 inode = SOCK_INODE(sock);
3671 if (!inode)
3672 goto out;
3673
3674 isec = inode->i_security;
3620 3675
3621 err = sel_netif_sids(dev, &if_sid, NULL); 3676 err = sel_netif_sids(dev, &if_sid, NULL);
3622 if (err) 3677 if (err)
@@ -3681,26 +3736,16 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3681 char *addrp; 3736 char *addrp;
3682 int len, err = 0; 3737 int len, err = 0;
3683 struct sock *sk; 3738 struct sock *sk;
3684 struct socket *sock;
3685 struct inode *inode;
3686 struct sk_buff *skb = *pskb; 3739 struct sk_buff *skb = *pskb;
3687 struct inode_security_struct *isec;
3688 struct avc_audit_data ad; 3740 struct avc_audit_data ad;
3689 struct net_device *dev = (struct net_device *)out; 3741 struct net_device *dev = (struct net_device *)out;
3742 struct sk_security_struct *sksec;
3690 3743
3691 sk = skb->sk; 3744 sk = skb->sk;
3692 if (!sk) 3745 if (!sk)
3693 goto out; 3746 goto out;
3694 3747
3695 sock = sk->sk_socket; 3748 sksec = sk->sk_security;
3696 if (!sock)
3697 goto out;
3698
3699 inode = SOCK_INODE(sock);
3700 if (!inode)
3701 goto out;
3702
3703 isec = inode->i_security;
3704 3749
3705 AVC_AUDIT_DATA_INIT(&ad, NET); 3750 AVC_AUDIT_DATA_INIT(&ad, NET);
3706 ad.u.net.netif = dev->name; 3751 ad.u.net.netif = dev->name;
@@ -3711,16 +3756,16 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum,
3711 goto out; 3756 goto out;
3712 3757
3713 if (selinux_compat_net) 3758 if (selinux_compat_net)
3714 err = selinux_ip_postroute_last_compat(sk, dev, isec, &ad, 3759 err = selinux_ip_postroute_last_compat(sk, dev, &ad,
3715 family, addrp, len); 3760 family, addrp, len);
3716 else 3761 else
3717 err = avc_has_perm(isec->sid, skb->secmark, SECCLASS_PACKET, 3762 err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET,
3718 PACKET__SEND, &ad); 3763 PACKET__SEND, &ad);
3719 3764
3720 if (err) 3765 if (err)
3721 goto out; 3766 goto out;
3722 3767
3723 err = selinux_xfrm_postroute_last(isec->sid, skb, &ad); 3768 err = selinux_xfrm_postroute_last(sksec->sid, skb, &ad);
3724out: 3769out:
3725 return err ? NF_DROP : NF_ACCEPT; 3770 return err ? NF_DROP : NF_ACCEPT;
3726} 3771}
@@ -4623,6 +4668,10 @@ static struct security_operations selinux_ops = {
4623 .sk_free_security = selinux_sk_free_security, 4668 .sk_free_security = selinux_sk_free_security,
4624 .sk_clone_security = selinux_sk_clone_security, 4669 .sk_clone_security = selinux_sk_clone_security,
4625 .sk_getsecid = selinux_sk_getsecid, 4670 .sk_getsecid = selinux_sk_getsecid,
4671 .sock_graft = selinux_sock_graft,
4672 .inet_conn_request = selinux_inet_conn_request,
4673 .inet_csk_clone = selinux_inet_csk_clone,
4674 .req_classify_flow = selinux_req_classify_flow,
4626 4675
4627#ifdef CONFIG_SECURITY_NETWORK_XFRM 4676#ifdef CONFIG_SECURITY_NETWORK_XFRM
4628 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, 4677 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index d3690f985135..3e742b850af6 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -271,7 +271,6 @@ not_from_user:
271 goto out; 271 goto out;
272 } 272 }
273 273
274
275 ctx->ctx_doi = XFRM_SC_DOI_LSM; 274 ctx->ctx_doi = XFRM_SC_DOI_LSM;
276 ctx->ctx_alg = XFRM_SC_ALG_SELINUX; 275 ctx->ctx_alg = XFRM_SC_ALG_SELINUX;
277 ctx->ctx_sid = ctx_sid; 276 ctx->ctx_sid = ctx_sid;