diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 38 |
1 files changed, 21 insertions, 17 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 5d1b8c733199..d67abf77584a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -269,15 +269,13 @@ static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | |||
269 | { | 269 | { |
270 | struct sk_security_struct *ssec; | 270 | struct sk_security_struct *ssec; |
271 | 271 | ||
272 | if (family != PF_UNIX) | ||
273 | return 0; | ||
274 | |||
275 | ssec = kzalloc(sizeof(*ssec), priority); | 272 | ssec = kzalloc(sizeof(*ssec), priority); |
276 | if (!ssec) | 273 | if (!ssec) |
277 | return -ENOMEM; | 274 | return -ENOMEM; |
278 | 275 | ||
279 | ssec->sk = sk; | 276 | ssec->sk = sk; |
280 | ssec->peer_sid = SECINITSID_UNLABELED; | 277 | ssec->peer_sid = SECINITSID_UNLABELED; |
278 | ssec->sid = SECINITSID_UNLABELED; | ||
281 | sk->sk_security = ssec; | 279 | sk->sk_security = ssec; |
282 | 280 | ||
283 | return 0; | 281 | return 0; |
@@ -287,9 +285,6 @@ static void sk_free_security(struct sock *sk) | |||
287 | { | 285 | { |
288 | struct sk_security_struct *ssec = sk->sk_security; | 286 | struct sk_security_struct *ssec = sk->sk_security; |
289 | 287 | ||
290 | if (sk->sk_family != PF_UNIX) | ||
291 | return; | ||
292 | |||
293 | sk->sk_security = NULL; | 288 | sk->sk_security = NULL; |
294 | kfree(ssec); | 289 | kfree(ssec); |
295 | } | 290 | } |
@@ -3068,6 +3063,7 @@ static void selinux_socket_post_create(struct socket *sock, int family, | |||
3068 | { | 3063 | { |
3069 | struct inode_security_struct *isec; | 3064 | struct inode_security_struct *isec; |
3070 | struct task_security_struct *tsec; | 3065 | struct task_security_struct *tsec; |
3066 | struct sk_security_struct *sksec; | ||
3071 | u32 newsid; | 3067 | u32 newsid; |
3072 | 3068 | ||
3073 | isec = SOCK_INODE(sock)->i_security; | 3069 | isec = SOCK_INODE(sock)->i_security; |
@@ -3078,6 +3074,11 @@ static void selinux_socket_post_create(struct socket *sock, int family, | |||
3078 | isec->sid = kern ? SECINITSID_KERNEL : newsid; | 3074 | isec->sid = kern ? SECINITSID_KERNEL : newsid; |
3079 | isec->initialized = 1; | 3075 | isec->initialized = 1; |
3080 | 3076 | ||
3077 | if (sock->sk) { | ||
3078 | sksec = sock->sk->sk_security; | ||
3079 | sksec->sid = isec->sid; | ||
3080 | } | ||
3081 | |||
3081 | return; | 3082 | return; |
3082 | } | 3083 | } |
3083 | 3084 | ||
@@ -3551,22 +3552,24 @@ static void selinux_sk_free_security(struct sock *sk) | |||
3551 | sk_free_security(sk); | 3552 | sk_free_security(sk); |
3552 | } | 3553 | } |
3553 | 3554 | ||
3554 | static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir) | 3555 | static void selinux_sk_clone_security(const struct sock *sk, struct sock *newsk) |
3555 | { | 3556 | { |
3556 | struct inode_security_struct *isec; | 3557 | struct sk_security_struct *ssec = sk->sk_security; |
3557 | u32 sock_sid = SECINITSID_ANY_SOCKET; | 3558 | struct sk_security_struct *newssec = newsk->sk_security; |
3558 | 3559 | ||
3560 | newssec->sid = ssec->sid; | ||
3561 | newssec->peer_sid = ssec->peer_sid; | ||
3562 | } | ||
3563 | |||
3564 | static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir) | ||
3565 | { | ||
3559 | if (!sk) | 3566 | if (!sk) |
3560 | return selinux_no_sk_sid(fl); | 3567 | return selinux_no_sk_sid(fl); |
3568 | else { | ||
3569 | struct sk_security_struct *sksec = sk->sk_security; | ||
3561 | 3570 | ||
3562 | read_lock_bh(&sk->sk_callback_lock); | 3571 | return sksec->sid; |
3563 | isec = get_sock_isec(sk); | 3572 | } |
3564 | |||
3565 | if (isec) | ||
3566 | sock_sid = isec->sid; | ||
3567 | |||
3568 | read_unlock_bh(&sk->sk_callback_lock); | ||
3569 | return sock_sid; | ||
3570 | } | 3573 | } |
3571 | 3574 | ||
3572 | static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | 3575 | static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) |
@@ -4618,6 +4621,7 @@ static struct security_operations selinux_ops = { | |||
4618 | .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram, | 4621 | .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram, |
4619 | .sk_alloc_security = selinux_sk_alloc_security, | 4622 | .sk_alloc_security = selinux_sk_alloc_security, |
4620 | .sk_free_security = selinux_sk_free_security, | 4623 | .sk_free_security = selinux_sk_free_security, |
4624 | .sk_clone_security = selinux_sk_clone_security, | ||
4621 | .sk_getsid = selinux_sk_getsid_security, | 4625 | .sk_getsid = selinux_sk_getsid_security, |
4622 | 4626 | ||
4623 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 4627 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |