diff options
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index fc774436a26..b9f8d9731c3 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -73,6 +73,7 @@ #include "avc.h" #include "objsec.h" #include "netif.h" +#include "xfrm.h" #define XATTR_SELINUX_SUFFIX "selinux" #define XATTR_NAME_SELINUX XATTR_SECURITY_PREFIX XATTR_SELINUX_SUFFIX @@ -1018,7 +1019,7 @@ static inline int dentry_has_perm(struct task_struct *tsk, has the same SID as the process. If av is zero, then access to the file is not checked, e.g. for cases where only the descriptor is affected like seek. */ -static inline int file_has_perm(struct task_struct *tsk, +static int file_has_perm(struct task_struct *tsk, struct file *file, u32 av) { @@ -1662,7 +1663,7 @@ static inline void flush_unauthorized_files(struct files_struct * files) continue; } if (devnull) { - rcuref_inc(&devnull->f_count); + get_file(devnull); } else { devnull = dentry_open(dget(selinux_null), mntget(selinuxfs_mount), O_RDWR); if (!devnull) { @@ -3349,6 +3350,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) err = avc_has_perm(sock_sid, port_sid, sock_class, recv_perm, &ad); } + + if (!err) + err = selinux_xfrm_sock_rcv_skb(sock_sid, skb); + out: return err; } @@ -3401,6 +3406,24 @@ static void selinux_sk_free_security(struct sock *sk) sk_free_security(sk); } +static unsigned int selinux_sk_getsid_security(struct sock *sk, struct flowi *fl, u8 dir) +{ + struct inode_security_struct *isec; + u32 sock_sid = SECINITSID_ANY_SOCKET; + + if (!sk) + return selinux_no_sk_sid(fl); + + read_lock_bh(&sk->sk_callback_lock); + isec = get_sock_isec(sk); + + if (isec) + sock_sid = isec->sid; + + read_unlock_bh(&sk->sk_callback_lock); + return sock_sid; +} + static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) { int err = 0; @@ -3536,6 +3559,11 @@ static unsigned int selinux_ip_postroute_last(unsigned int hooknum, send_perm, &ad) ? NF_DROP : NF_ACCEPT; } + if (err != NF_ACCEPT) + goto out; + + err = selinux_xfrm_postroute_last(isec->sid, skb); + out: return err; } @@ -4380,6 +4408,16 @@ static struct security_operations selinux_ops = { .socket_getpeersec = selinux_socket_getpeersec, .sk_alloc_security = selinux_sk_alloc_security, .sk_free_security = selinux_sk_free_security, + .sk_getsid = selinux_sk_getsid_security, +#endif + +#ifdef CONFIG_SECURITY_NETWORK_XFRM + .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, + .xfrm_policy_clone_security = selinux_xfrm_policy_clone, + .xfrm_policy_free_security = selinux_xfrm_policy_free, + .xfrm_state_alloc_security = selinux_xfrm_state_alloc, + .xfrm_state_free_security = selinux_xfrm_state_free, + .xfrm_policy_lookup = selinux_xfrm_policy_lookup, #endif }; @@ -4491,6 +4529,7 @@ static int __init selinux_nf_ip_init(void) panic("SELinux: nf_register_hook for IPv6: error %d\n", err); #endif /* IPV6 */ + out: return err; } |