diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 28832e689800..b85afcf38527 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -69,6 +69,7 @@ | |||
| 69 | #include <linux/sysctl.h> | 69 | #include <linux/sysctl.h> |
| 70 | #include <linux/audit.h> | 70 | #include <linux/audit.h> |
| 71 | #include <linux/string.h> | 71 | #include <linux/string.h> |
| 72 | #include <linux/selinux.h> | ||
| 72 | 73 | ||
| 73 | #include "avc.h" | 74 | #include "avc.h" |
| 74 | #include "objsec.h" | 75 | #include "objsec.h" |
| @@ -3420,7 +3421,13 @@ out: | |||
| 3420 | static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen) | 3421 | static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen) |
| 3421 | { | 3422 | { |
| 3422 | int err = 0; | 3423 | int err = 0; |
| 3423 | u32 peer_sid = selinux_socket_getpeer_dgram(skb); | 3424 | u32 peer_sid; |
| 3425 | |||
| 3426 | if (skb->sk->sk_family == PF_UNIX) | ||
| 3427 | selinux_get_inode_sid(SOCK_INODE(skb->sk->sk_socket), | ||
| 3428 | &peer_sid); | ||
| 3429 | else | ||
| 3430 | peer_sid = selinux_socket_getpeer_dgram(skb); | ||
| 3424 | 3431 | ||
| 3425 | if (peer_sid == SECSID_NULL) | 3432 | if (peer_sid == SECSID_NULL) |
| 3426 | return -EINVAL; | 3433 | return -EINVAL; |
| @@ -3432,8 +3439,6 @@ static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, | |||
| 3432 | return 0; | 3439 | return 0; |
| 3433 | } | 3440 | } |
| 3434 | 3441 | ||
| 3435 | |||
| 3436 | |||
| 3437 | static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) | 3442 | static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) |
| 3438 | { | 3443 | { |
| 3439 | return sk_alloc_security(sk, family, priority); | 3444 | return sk_alloc_security(sk, family, priority); |
| @@ -3641,32 +3646,32 @@ static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum, | |||
| 3641 | 3646 | ||
| 3642 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | 3647 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 3643 | { | 3648 | { |
| 3644 | struct task_security_struct *tsec; | ||
| 3645 | struct av_decision avd; | ||
| 3646 | int err; | 3649 | int err; |
| 3647 | 3650 | ||
| 3648 | err = secondary_ops->netlink_send(sk, skb); | 3651 | err = secondary_ops->netlink_send(sk, skb); |
| 3649 | if (err) | 3652 | if (err) |
| 3650 | return err; | 3653 | return err; |
| 3651 | 3654 | ||
| 3652 | tsec = current->security; | ||
| 3653 | |||
| 3654 | avd.allowed = 0; | ||
| 3655 | avc_has_perm_noaudit(tsec->sid, tsec->sid, | ||
| 3656 | SECCLASS_CAPABILITY, ~0, &avd); | ||
| 3657 | cap_mask(NETLINK_CB(skb).eff_cap, avd.allowed); | ||
| 3658 | |||
| 3659 | if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS) | 3655 | if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS) |
| 3660 | err = selinux_nlmsg_perm(sk, skb); | 3656 | err = selinux_nlmsg_perm(sk, skb); |
| 3661 | 3657 | ||
| 3662 | return err; | 3658 | return err; |
| 3663 | } | 3659 | } |
| 3664 | 3660 | ||
| 3665 | static int selinux_netlink_recv(struct sk_buff *skb) | 3661 | static int selinux_netlink_recv(struct sk_buff *skb, int capability) |
| 3666 | { | 3662 | { |
| 3667 | if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) | 3663 | int err; |
| 3668 | return -EPERM; | 3664 | struct avc_audit_data ad; |
| 3669 | return 0; | 3665 | |
| 3666 | err = secondary_ops->netlink_recv(skb, capability); | ||
| 3667 | if (err) | ||
| 3668 | return err; | ||
| 3669 | |||
| 3670 | AVC_AUDIT_DATA_INIT(&ad, CAP); | ||
| 3671 | ad.u.cap = capability; | ||
| 3672 | |||
| 3673 | return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, | ||
| 3674 | SECCLASS_CAPABILITY, CAP_TO_MASK(capability), &ad); | ||
| 3670 | } | 3675 | } |
| 3671 | 3676 | ||
| 3672 | static int ipc_alloc_security(struct task_struct *task, | 3677 | static int ipc_alloc_security(struct task_struct *task, |
