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.c56
1 files changed, 45 insertions, 11 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 33028b3b19ce..2a6bbb921e1e 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -12,6 +12,8 @@
12 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> 12 * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
13 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 13 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
14 * <dgoeddel@trustedcs.com> 14 * <dgoeddel@trustedcs.com>
15 * Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
16 * Paul Moore, <paul.moore@hp.com>
15 * 17 *
16 * This program is free software; you can redistribute it and/or modify 18 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2, 19 * it under the terms of the GNU General Public License version 2,
@@ -74,6 +76,7 @@
74#include "objsec.h" 76#include "objsec.h"
75#include "netif.h" 77#include "netif.h"
76#include "xfrm.h" 78#include "xfrm.h"
79#include "selinux_netlabel.h"
77 80
78#define XATTR_SELINUX_SUFFIX "selinux" 81#define XATTR_SELINUX_SUFFIX "selinux"
79#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX 82#define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX
@@ -2395,6 +2398,7 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t
2395 2398
2396static int selinux_file_permission(struct file *file, int mask) 2399static int selinux_file_permission(struct file *file, int mask)
2397{ 2400{
2401 int rc;
2398 struct inode *inode = file->f_dentry->d_inode; 2402 struct inode *inode = file->f_dentry->d_inode;
2399 2403
2400 if (!mask) { 2404 if (!mask) {
@@ -2406,8 +2410,12 @@ static int selinux_file_permission(struct file *file, int mask)
2406 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) 2410 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE))
2407 mask |= MAY_APPEND; 2411 mask |= MAY_APPEND;
2408 2412
2409 return file_has_perm(current, file, 2413 rc = file_has_perm(current, file,
2410 file_mask_to_av(inode->i_mode, mask)); 2414 file_mask_to_av(inode->i_mode, mask));
2415 if (rc)
2416 return rc;
2417
2418 return selinux_netlbl_inode_permission(inode, mask);
2411} 2419}
2412 2420
2413static int selinux_file_alloc_security(struct file *file) 2421static int selinux_file_alloc_security(struct file *file)
@@ -3058,9 +3066,10 @@ out:
3058 return err; 3066 return err;
3059} 3067}
3060 3068
3061static void selinux_socket_post_create(struct socket *sock, int family, 3069static int selinux_socket_post_create(struct socket *sock, int family,
3062 int type, int protocol, int kern) 3070 int type, int protocol, int kern)
3063{ 3071{
3072 int err = 0;
3064 struct inode_security_struct *isec; 3073 struct inode_security_struct *isec;
3065 struct task_security_struct *tsec; 3074 struct task_security_struct *tsec;
3066 struct sk_security_struct *sksec; 3075 struct sk_security_struct *sksec;
@@ -3077,9 +3086,12 @@ static void selinux_socket_post_create(struct socket *sock, int family,
3077 if (sock->sk) { 3086 if (sock->sk) {
3078 sksec = sock->sk->sk_security; 3087 sksec = sock->sk->sk_security;
3079 sksec->sid = isec->sid; 3088 sksec->sid = isec->sid;
3089 err = selinux_netlbl_socket_post_create(sock,
3090 family,
3091 isec->sid);
3080 } 3092 }
3081 3093
3082 return; 3094 return err;
3083} 3095}
3084 3096
3085/* Range of port numbers used to automatically bind. 3097/* Range of port numbers used to automatically bind.
@@ -3260,7 +3272,13 @@ static int selinux_socket_accept(struct socket *sock, struct socket *newsock)
3260static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg, 3272static int selinux_socket_sendmsg(struct socket *sock, struct msghdr *msg,
3261 int size) 3273 int size)
3262{ 3274{
3263 return socket_has_perm(current, sock, SOCKET__WRITE); 3275 int rc;
3276
3277 rc = socket_has_perm(current, sock, SOCKET__WRITE);
3278 if (rc)
3279 return rc;
3280
3281 return selinux_netlbl_inode_permission(SOCK_INODE(sock), MAY_WRITE);
3264} 3282}
3265 3283
3266static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg, 3284static int selinux_socket_recvmsg(struct socket *sock, struct msghdr *msg,
@@ -3468,6 +3486,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3468 if (err) 3486 if (err)
3469 goto out; 3487 goto out;
3470 3488
3489 err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad);
3490 if (err)
3491 goto out;
3492
3471 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad); 3493 err = selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
3472out: 3494out:
3473 return err; 3495 return err;
@@ -3491,8 +3513,9 @@ static int selinux_socket_getpeersec_stream(struct socket *sock, char __user *op
3491 peer_sid = ssec->peer_sid; 3513 peer_sid = ssec->peer_sid;
3492 } 3514 }
3493 else if (isec->sclass == SECCLASS_TCP_SOCKET) { 3515 else if (isec->sclass == SECCLASS_TCP_SOCKET) {
3494 peer_sid = selinux_socket_getpeer_stream(sock->sk); 3516 peer_sid = selinux_netlbl_socket_getpeersec_stream(sock);
3495 3517 if (peer_sid == SECSID_NULL)
3518 peer_sid = selinux_socket_getpeer_stream(sock->sk);
3496 if (peer_sid == SECSID_NULL) { 3519 if (peer_sid == SECSID_NULL) {
3497 err = -ENOPROTOOPT; 3520 err = -ENOPROTOOPT;
3498 goto out; 3521 goto out;
@@ -3532,8 +3555,11 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
3532 3555
3533 if (sock && (sock->sk->sk_family == PF_UNIX)) 3556 if (sock && (sock->sk->sk_family == PF_UNIX))
3534 selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid); 3557 selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
3535 else if (skb) 3558 else if (skb) {
3536 peer_secid = selinux_socket_getpeer_dgram(skb); 3559 peer_secid = selinux_netlbl_socket_getpeersec_dgram(skb);
3560 if (peer_secid == SECSID_NULL)
3561 peer_secid = selinux_socket_getpeer_dgram(skb);
3562 }
3537 3563
3538 if (peer_secid == SECSID_NULL) 3564 if (peer_secid == SECSID_NULL)
3539 err = -EINVAL; 3565 err = -EINVAL;
@@ -3578,6 +3604,8 @@ void selinux_sock_graft(struct sock* sk, struct socket *parent)
3578 struct sk_security_struct *sksec = sk->sk_security; 3604 struct sk_security_struct *sksec = sk->sk_security;
3579 3605
3580 isec->sid = sksec->sid; 3606 isec->sid = sksec->sid;
3607
3608 selinux_netlbl_sock_graft(sk, parent);
3581} 3609}
3582 3610
3583int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb, 3611int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
@@ -3585,9 +3613,15 @@ int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
3585{ 3613{
3586 struct sk_security_struct *sksec = sk->sk_security; 3614 struct sk_security_struct *sksec = sk->sk_security;
3587 int err; 3615 int err;
3588 u32 newsid = 0; 3616 u32 newsid;
3589 u32 peersid; 3617 u32 peersid;
3590 3618
3619 newsid = selinux_netlbl_inet_conn_request(skb, sksec->sid);
3620 if (newsid != SECSID_NULL) {
3621 req->secid = newsid;
3622 return 0;
3623 }
3624
3591 err = selinux_xfrm_decode_session(skb, &peersid, 0); 3625 err = selinux_xfrm_decode_session(skb, &peersid, 0);
3592 BUG_ON(err); 3626 BUG_ON(err);
3593 3627