aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c46
1 files changed, 39 insertions, 7 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b65c201e9ff5..5b16196f2823 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3318,24 +3318,38 @@ out:
3318 return err; 3318 return err;
3319} 3319}
3320 3320
3321static int selinux_socket_getpeersec(struct socket *sock, char __user *optval, 3321static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *optval,
3322 int __user *optlen, unsigned len) 3322 int __user *optlen, unsigned len)
3323{ 3323{
3324 int err = 0; 3324 int err = 0;
3325 char *scontext; 3325 char *scontext;
3326 u32 scontext_len; 3326 u32 scontext_len;
3327 struct sk_security_struct *ssec; 3327 struct sk_security_struct *ssec;
3328 struct inode_security_struct *isec; 3328 struct inode_security_struct *isec;
3329 u32 peer_sid = 0;
3329 3330
3330 isec = SOCK_INODE(sock)->i_security; 3331 isec = SOCK_INODE(sock)->i_security;
3331 if (isec->sclass != SECCLASS_UNIX_STREAM_SOCKET) { 3332
3333 /* if UNIX_STREAM check peer_sid, if TCP check dst for labelled sa */
3334 if (isec->sclass == SECCLASS_UNIX_STREAM_SOCKET) {
3335 ssec = sock->sk->sk_security;
3336 peer_sid = ssec->peer_sid;
3337 }
3338 else if (isec->sclass == SECCLASS_TCP_SOCKET) {
3339 peer_sid = selinux_socket_getpeer_stream(sock->sk);
3340
3341 if (peer_sid == SECSID_NULL) {
3342 err = -ENOPROTOOPT;
3343 goto out;
3344 }
3345 }
3346 else {
3332 err = -ENOPROTOOPT; 3347 err = -ENOPROTOOPT;
3333 goto out; 3348 goto out;
3334 } 3349 }
3335 3350
3336 ssec = sock->sk->sk_security; 3351 err = security_sid_to_context(peer_sid, &scontext, &scontext_len);
3337 3352
3338 err = security_sid_to_context(ssec->peer_sid, &scontext, &scontext_len);
3339 if (err) 3353 if (err)
3340 goto out; 3354 goto out;
3341 3355
@@ -3356,6 +3370,23 @@ out:
3356 return err; 3370 return err;
3357} 3371}
3358 3372
3373static int selinux_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata, u32 *seclen)
3374{
3375 int err = 0;
3376 u32 peer_sid = selinux_socket_getpeer_dgram(skb);
3377
3378 if (peer_sid == SECSID_NULL)
3379 return -EINVAL;
3380
3381 err = security_sid_to_context(peer_sid, secdata, seclen);
3382 if (err)
3383 return err;
3384
3385 return 0;
3386}
3387
3388
3389
3359static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority) 3390static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t priority)
3360{ 3391{
3361 return sk_alloc_security(sk, family, priority); 3392 return sk_alloc_security(sk, family, priority);
@@ -4344,7 +4375,8 @@ static struct security_operations selinux_ops = {
4344 .socket_setsockopt = selinux_socket_setsockopt, 4375 .socket_setsockopt = selinux_socket_setsockopt,
4345 .socket_shutdown = selinux_socket_shutdown, 4376 .socket_shutdown = selinux_socket_shutdown,
4346 .socket_sock_rcv_skb = selinux_socket_sock_rcv_skb, 4377 .socket_sock_rcv_skb = selinux_socket_sock_rcv_skb,
4347 .socket_getpeersec = selinux_socket_getpeersec, 4378 .socket_getpeersec_stream = selinux_socket_getpeersec_stream,
4379 .socket_getpeersec_dgram = selinux_socket_getpeersec_dgram,
4348 .sk_alloc_security = selinux_sk_alloc_security, 4380 .sk_alloc_security = selinux_sk_alloc_security,
4349 .sk_free_security = selinux_sk_free_security, 4381 .sk_free_security = selinux_sk_free_security,
4350 .sk_getsid = selinux_sk_getsid_security, 4382 .sk_getsid = selinux_sk_getsid_security,