From patchwork Tue Aug 4 21:22:04 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Moore X-Patchwork-Id: 30745 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@bilbo.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from ozlabs.org (ozlabs.org [203.10.76.45]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "mx.ozlabs.org", Issuer "CA Cert Signing Authority" (verified OK)) by bilbo.ozlabs.org (Postfix) with ESMTPS id 8FFE8B6F1E for ; Wed, 5 Aug 2009 07:22:32 +1000 (EST) Received: by ozlabs.org (Postfix) id 7D21BDDDA0; Wed, 5 Aug 2009 07:22:32 +1000 (EST) Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id B4C13DDD04 for ; Wed, 5 Aug 2009 07:22:31 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932872AbZHDVWW (ORCPT ); Tue, 4 Aug 2009 17:22:22 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S932667AbZHDVWV (ORCPT ); Tue, 4 Aug 2009 17:22:21 -0400 Received: from g5t0009.atlanta.hp.com ([15.192.0.46]:13168 "EHLO g5t0009.atlanta.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932502AbZHDVWU (ORCPT ); Tue, 4 Aug 2009 17:22:20 -0400 Received: from g5t0030.atlanta.hp.com (g5t0030.atlanta.hp.com [16.228.8.142]) by g5t0009.atlanta.hp.com (Postfix) with ESMTP id 7C4713023B; Tue, 4 Aug 2009 21:22:21 +0000 (UTC) Received: from ldl (ldl.fc.hp.com [15.11.146.30]) by g5t0030.atlanta.hp.com (Postfix) with ESMTP id 3C8362423B; Tue, 4 Aug 2009 21:22:06 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by ldl (Postfix) with ESMTP id 1C374CF001E; Tue, 4 Aug 2009 15:22:06 -0600 (MDT) Received: from ldl ([127.0.0.1]) by localhost (ldl.fc.hp.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fmyv833-eAgh; Tue, 4 Aug 2009 15:22:06 -0600 (MDT) Received: from flek.lan (squirrel.fc.hp.com [15.11.146.57]) by ldl (Postfix) with ESMTP id 5D493CF000D; Tue, 4 Aug 2009 15:22:05 -0600 (MDT) From: Paul Moore Subject: [RFC PATCH v1 2/2] selinux: Support for the new TUN LSM hooks To: netdev@vger.kernel.org, linux-security-module@vger.kernel.org, selinux@tycho.nsa.gov Date: Tue, 04 Aug 2009 17:22:04 -0400 Message-ID: <20090804212204.10798.53727.stgit@flek.lan> In-Reply-To: <20090804211304.10798.65601.stgit@flek.lan> References: <20090804211304.10798.65601.stgit@flek.lan> User-Agent: StGIT/0.14.3 MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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. This patch also includes a new policy capability, tun_perms, to ensure that the new access controls do not affect older SELinux policies. --- NOTE: This relies on some changes to the policy to add the new object class and its associated permissions, I will ensure that the policy is sorted and merged before pushing this patch upstream. Also, you will notice that the new tun_socket object class simply inherits the base socket object class, thoughts? --- security/selinux/hooks.c | 76 +++++++++++++++++++++++++++- security/selinux/include/av_inherit.h | 1 security/selinux/include/av_permissions.h | 22 ++++++++ security/selinux/include/class_to_string.h | 1 security/selinux/include/flask.h | 1 security/selinux/include/security.h | 2 + security/selinux/selinuxfs.c | 3 + security/selinux/ss/services.c | 3 + 8 files changed, 106 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 15c2a08..6ba99c2 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -13,8 +13,8 @@ * Eric Paris * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * - * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. - * Paul Moore + * Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P. + * Paul Moore * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. * Yuichi Nakamura * @@ -4296,6 +4296,75 @@ static void selinux_req_classify_flow(const struct request_sock *req, fl->secid = req->secid; } +static int selinux_tun_dev_create(void) +{ + u32 sid; + int err; + + err = cap_tun_dev_create(); + if (err) + return err; + + if (!selinux_policycap_tunperm) + return 0; + + /* 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 understand of why this socket is special */ + + sid = current_sid(); + return avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE, + NULL); +} + +static void selinux_tun_dev_post_create(struct sock *tun_sk) +{ + struct sk_security_struct *sksec = tun_sk->sk_security; + + /* see the comments in _tun_dev_create() about why we don't use the + * sockcreate SID here */ + + /* 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 */ + + sksec->sid = current_sid(); + sksec->sclass = SECCLASS_TUN_SOCKET; +} + +static int selinux_tun_dev_attach(struct sock *tun_sk) +{ + struct sk_security_struct *tun_sksec = tun_sk->sk_security; + u32 sid; + int err; + + err = cap_tun_dev_attach(); + if (err) + return err; + + if (!selinux_policycap_tunperm) + return 0; + + sid = current_sid(); + err = avc_has_perm(sid, tun_sksec->sid, SECCLASS_TUN_SOCKET, + TUN_SOCKET__RELABELFROM, NULL); + if (err) + return err; + err = avc_has_perm(sid, sid, SECCLASS_RAWIP_SOCKET, + TUN_SOCKET__RELABELTO, NULL); + if (err) + return err; + tun_sksec->sid = sid; + + return 0; +} + static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) { int err = 0; @@ -5464,6 +5533,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, diff --git a/security/selinux/include/av_inherit.h b/security/selinux/include/av_inherit.h index 8377a4b..abedcd7 100644 --- a/security/selinux/include/av_inherit.h +++ b/security/selinux/include/av_inherit.h @@ -15,6 +15,7 @@ S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_TUN_SOCKET, socket, 0x00400000UL) S_(SECCLASS_IPC, ipc, 0x00000200UL) S_(SECCLASS_SEM, ipc, 0x00000200UL) S_(SECCLASS_MSGQ, ipc, 0x00000200UL) diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index d645192..0b41ad5 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h @@ -423,6 +423,28 @@ #define UNIX_DGRAM_SOCKET__RECV_MSG 0x00080000UL #define UNIX_DGRAM_SOCKET__SEND_MSG 0x00100000UL #define UNIX_DGRAM_SOCKET__NAME_BIND 0x00200000UL +#define TUN_SOCKET__IOCTL 0x00000001UL +#define TUN_SOCKET__READ 0x00000002UL +#define TUN_SOCKET__WRITE 0x00000004UL +#define TUN_SOCKET__CREATE 0x00000008UL +#define TUN_SOCKET__GETATTR 0x00000010UL +#define TUN_SOCKET__SETATTR 0x00000020UL +#define TUN_SOCKET__LOCK 0x00000040UL +#define TUN_SOCKET__RELABELFROM 0x00000080UL +#define TUN_SOCKET__RELABELTO 0x00000100UL +#define TUN_SOCKET__APPEND 0x00000200UL +#define TUN_SOCKET__BIND 0x00000400UL +#define TUN_SOCKET__CONNECT 0x00000800UL +#define TUN_SOCKET__LISTEN 0x00001000UL +#define TUN_SOCKET__ACCEPT 0x00002000UL +#define TUN_SOCKET__GETOPT 0x00004000UL +#define TUN_SOCKET__SETOPT 0x00008000UL +#define TUN_SOCKET__SHUTDOWN 0x00010000UL +#define TUN_SOCKET__RECVFROM 0x00020000UL +#define TUN_SOCKET__SENDTO 0x00040000UL +#define TUN_SOCKET__RECV_MSG 0x00080000UL +#define TUN_SOCKET__SEND_MSG 0x00100000UL +#define TUN_SOCKET__NAME_BIND 0x00200000UL #define PROCESS__FORK 0x00000001UL #define PROCESS__TRANSITION 0x00000002UL #define PROCESS__SIGCHLD 0x00000004UL diff --git a/security/selinux/include/class_to_string.h b/security/selinux/include/class_to_string.h index 21ec786..7ab9299 100644 --- a/security/selinux/include/class_to_string.h +++ b/security/selinux/include/class_to_string.h @@ -77,3 +77,4 @@ S_(NULL) S_(NULL) S_("kernel_service") + S_("tun_socket") diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h index 882f27d..f248500 100644 --- a/security/selinux/include/flask.h +++ b/security/selinux/include/flask.h @@ -53,6 +53,7 @@ #define SECCLASS_PEER 68 #define SECCLASS_CAPABILITY2 69 #define SECCLASS_KERNEL_SERVICE 74 +#define SECCLASS_TUN_SOCKET 75 /* * Security identifier indices for initial entities diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index ca83579..188af8d 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -63,12 +63,14 @@ extern int selinux_mls_enabled; enum { POLICYDB_CAPABILITY_NETPEER, POLICYDB_CAPABILITY_OPENPERM, + POLICYDB_CAPABILITY_TUNPERM, __POLICYDB_CAPABILITY_MAX }; #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) extern int selinux_policycap_netpeer; extern int selinux_policycap_openperm; +extern int selinux_policycap_tunperm; /* * type_datum properties diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index b4fc506..770e059 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -42,7 +42,8 @@ /* Policy capability filenames */ static char *policycap_names[] = { "network_peer_controls", - "open_perms" + "open_perms", + "tun_perms" }; unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 500e6f7..adbe6d5 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -64,6 +64,7 @@ unsigned int policydb_loaded_version; int selinux_policycap_netpeer; int selinux_policycap_openperm; +int selinux_policycap_tunperm; /* * This is declared in avc.c @@ -1593,6 +1594,8 @@ static void security_load_policycaps(void) POLICYDB_CAPABILITY_NETPEER); selinux_policycap_openperm = ebitmap_get_bit(&policydb.policycaps, POLICYDB_CAPABILITY_OPENPERM); + selinux_policycap_tunperm = ebitmap_get_bit(&policydb.policycaps, + POLICYDB_CAPABILITY_TUNPERM); } extern void selinux_complete_init(void);