selinux: Support for the new TUN LSM hooks

Add support for the new TUN LSM hooks: security_tun_dev_create(),
security_tun_dev_post_create() and security_tun_dev_attach().  This includes
the addition of a new object class, tun_socket, which represents the socks
associated with TUN devices.  The _tun_dev_create() and _tun_dev_post_create()
hooks are fairly similar to the standard socket functions but _tun_dev_attach()
is a bit special.  The _tun_dev_attach() is unique because it involves a
domain attaching to an existing TUN device and its associated tun_socket
object, an operation which does not exist with standard sockets and most
closely resembles a relabel operation.

Signed-off-by: Paul Moore <paul.moore@hp.com>
Acked-by: Eric Paris <eparis@parisplace.org>
Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
Paul Moore
2009-08-28 18:12:49 -04:00
committed by James Morris
parent 2b980dbd77
commit ed6d76e4c3
5 changed files with 83 additions and 2 deletions

View File

@@ -13,8 +13,8 @@
* Eric Paris <eparis@redhat.com>
* Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
* <dgoeddel@trustedcs.com>
* Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
* Paul Moore <paul.moore@hp.com>
* Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P.
* Paul Moore <paul.moore@hp.com>
* Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
* Yuichi Nakamura <ynakam@hitachisoft.jp>
*
@@ -4325,6 +4325,59 @@ static void selinux_req_classify_flow(const struct request_sock *req,
fl->secid = req->secid;
}
static int selinux_tun_dev_create(void)
{
u32 sid = current_sid();
/* we aren't taking into account the "sockcreate" SID since the socket
* that is being created here is not a socket in the traditional sense,
* instead it is a private sock, accessible only to the kernel, and
* representing a wide range of network traffic spanning multiple
* connections unlike traditional sockets - check the TUN driver to
* get a better understanding of why this socket is special */
return avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE,
NULL);
}
static void selinux_tun_dev_post_create(struct sock *sk)
{
struct sk_security_struct *sksec = sk->sk_security;
/* we don't currently perform any NetLabel based labeling here and it
* isn't clear that we would want to do so anyway; while we could apply
* labeling without the support of the TUN user the resulting labeled
* traffic from the other end of the connection would almost certainly
* cause confusion to the TUN user that had no idea network labeling
* protocols were being used */
/* see the comments in selinux_tun_dev_create() about why we don't use
* the sockcreate SID here */
sksec->sid = current_sid();
sksec->sclass = SECCLASS_TUN_SOCKET;
}
static int selinux_tun_dev_attach(struct sock *sk)
{
struct sk_security_struct *sksec = sk->sk_security;
u32 sid = current_sid();
int err;
err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET,
TUN_SOCKET__RELABELFROM, NULL);
if (err)
return err;
err = avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET,
TUN_SOCKET__RELABELTO, NULL);
if (err)
return err;
sksec->sid = sid;
return 0;
}
static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
{
int err = 0;
@@ -5494,6 +5547,9 @@ static struct security_operations selinux_ops = {
.inet_csk_clone = selinux_inet_csk_clone,
.inet_conn_established = selinux_inet_conn_established,
.req_classify_flow = selinux_req_classify_flow,
.tun_dev_create = selinux_tun_dev_create,
.tun_dev_post_create = selinux_tun_dev_post_create,
.tun_dev_attach = selinux_tun_dev_attach,
#ifdef CONFIG_SECURITY_NETWORK_XFRM
.xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,