All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH v2 0/2] Updated patches based on comments
@ 2007-09-26 21:32 Paul Moore
  2007-09-26 21:32 ` [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22 Paul Moore
  2007-09-26 21:32 ` [RFC PATCH v2 2/2] [SELINUX] Better integration between peer labeling subsystems Paul Moore
  0 siblings, 2 replies; 8+ messages in thread
From: Paul Moore @ 2007-09-26 21:32 UTC (permalink / raw)
  To: selinux

I'm resending these patches because I've made some non-trivial changes based on
comments from the list and I'd like to check to make sure I'm moving in the
right direction.  The two big changes are the shift from a policy capability
version number to a policy capability bitmap and the transfer of much of the
logic within selinux_skb_peerlbl_sid() into the new security server function
selinux_skb_peerlbl_sid().

Once again, these patches compile and boot, but use at your own risk.

-- 
paul moore
linux security @ hp


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22
  2007-09-26 21:32 [RFC PATCH v2 0/2] Updated patches based on comments Paul Moore
@ 2007-09-26 21:32 ` Paul Moore
  2007-09-26 22:24   ` Joshua Brindle
  2007-09-26 21:32 ` [RFC PATCH v2 2/2] [SELINUX] Better integration between peer labeling subsystems Paul Moore
  1 sibling, 1 reply; 8+ messages in thread
From: Paul Moore @ 2007-09-26 21:32 UTC (permalink / raw)
  To: selinux

Add a new policy capabilities bitmap to SELinux policy version 22.  This bitmap
will enable the security server to query the policy to determine which features
it supports.
---

 security/selinux/include/security.h |   15 +++++-
 security/selinux/selinuxfs.c        |   90 +++++++++++++++++++++++++++++++++--
 security/selinux/ss/policydb.c      |   18 +++++++
 security/selinux/ss/policydb.h      |    2 +
 security/selinux/ss/services.c      |   39 +++++++++++++++
 5 files changed, 158 insertions(+), 6 deletions(-)

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 83bdd4d..d7e6ed2 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -25,13 +25,14 @@
 #define POLICYDB_VERSION_MLS		19
 #define POLICYDB_VERSION_AVTAB		20
 #define POLICYDB_VERSION_RANGETRANS	21
+#define POLICYDB_VERSION_CAPBITMAP	22
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_RANGETRANS
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_CAPBITMAP
 #endif
 
 struct netlbl_lsm_secattr;
@@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
 extern int selinux_enabled;
 extern int selinux_mls_enabled;
 
+/* Policy capabilities */
+enum {
+	POLICYDB_CAPABILITY_NETPEER,
+	__POLICYDB_CAPABILITY_MAX
+};
+#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
+
+extern int selinux_policycap_netpeer;
+
 int security_load_policy(void * data, size_t len);
 
+int security_policycap_supported(unsigned int req_cap);
+
 #define SEL_VEC_MAX 32
 struct av_decision {
 	u32 allowed;
@@ -90,6 +102,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
 
 int security_get_classes(char ***classes, int *nclasses);
 int security_get_permissions(char *class, char ***perms, int *nperms);
+int security_get_policycaps(int *len, int **values);
 
 #define SECURITY_FS_USE_XATTR		1 /* use xattr */
 #define SECURITY_FS_USE_TRANS		2 /* use transition SIDs, e.g. devpts/tmpfs */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index c9e92da..c3e6f06 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2,6 +2,11 @@
  *
  * 	Added conditional policy language extensions
  *
+ *  Updated: Hewlett-Packard <paul.moore@hp.com>
+ *
+ *      Added support for the policy capability bitmap
+ *
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
  * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
  *	This program is free software; you can redistribute it and/or modify
@@ -35,6 +40,11 @@
 #include "objsec.h"
 #include "conditional.h"
 
+/* Policy capability filenames */
+static char *policycap_names[] = {
+	"network_peer_controls"
+};
+
 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
 
 #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
@@ -71,6 +81,9 @@ static int *bool_pending_values = NULL;
 static struct dentry *class_dir = NULL;
 static unsigned long last_class_ino;
 
+/* global data for policy capabilities */
+static struct dentry *policycap_dir = NULL;
+
 extern void selnl_notify_setenforce(int val);
 
 /* Check whether a task is allowed to use a security operation. */
@@ -108,10 +121,11 @@ enum sel_inos {
 
 static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
 
-#define SEL_INITCON_INO_OFFSET 	0x01000000
-#define SEL_BOOL_INO_OFFSET	0x02000000
-#define SEL_CLASS_INO_OFFSET	0x04000000
-#define SEL_INO_MASK		0x00ffffff
+#define SEL_INITCON_INO_OFFSET		0x01000000
+#define SEL_BOOL_INO_OFFSET		0x02000000
+#define SEL_CLASS_INO_OFFSET		0x04000000
+#define SEL_POLICYCAP_INO_OFFSET	0x08000000
+#define SEL_INO_MASK			0x00ffffff
 
 #define TMPBUFLEN	12
 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
@@ -243,6 +257,7 @@ static const struct file_operations sel_policyvers_ops = {
 /* declaration for sel_write_load */
 static int sel_make_bools(void);
 static int sel_make_classes(void);
+static int sel_make_policycap(void);
 
 /* declaration for sel_make_class_dirs */
 static int sel_make_dir(struct inode *dir, struct dentry *dentry,
@@ -303,6 +318,12 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
 	}
 
 	ret = sel_make_classes();
+	if (ret) {
+		length = ret;
+		goto out1;
+	}
+
+	ret = sel_make_policycap();
 	if (ret)
 		length = ret;
 	else
@@ -1384,6 +1405,25 @@ static const struct file_operations sel_perm_ops = {
 	.read		= sel_read_perm,
 };
 
+static ssize_t sel_read_policycap(struct file *file, char __user *buf,
+				  size_t count, loff_t *ppos)
+{
+	int value;
+	char tmpbuf[TMPBUFLEN];
+	ssize_t length;
+	unsigned long inode = file->f_path.dentry->d_inode->i_ino;
+
+	value = security_policycap_supported(inode &
+					     (SEL_POLICYCAP_INO_OFFSET - 1));
+	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
+
+	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
+}
+
+static const struct file_operations sel_policycap_ops = {
+	.read		= sel_read_policycap,
+};
+
 static int sel_make_perm_files(char *objclass, int classvalue,
 				struct dentry *dir)
 {
@@ -1530,6 +1570,36 @@ out:
 	return rc;
 }
 
+static int sel_make_policycap(void)
+{
+	unsigned int iter;
+	struct dentry *dentry = NULL;
+	struct inode *inode = NULL;
+
+	sel_remove_entries(policycap_dir);
+
+	for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
+		if (iter <= ARRAY_SIZE(policycap_names))
+			dentry = d_alloc_name(policycap_dir,
+					      policycap_names[iter]);
+		else
+			dentry = d_alloc_name(policycap_dir, "unknown");
+
+		if (dentry == NULL)
+			return -ENOMEM;
+
+		inode = sel_make_inode(policycap_dir->d_sb, S_IFREG | S_IRUGO);
+		if (inode == NULL)
+			return -ENOMEM;
+
+		inode->i_fop = &sel_policycap_ops;
+		inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
+		d_add(dentry, inode);	
+	}
+
+	return 0;
+}
+
 static int sel_make_dir(struct inode *dir, struct dentry *dentry,
 			unsigned long *ino)
 {
@@ -1656,6 +1726,18 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
 
 	class_dir = dentry;
 
+	dentry = d_alloc_name(sb->s_root, "policy_capabilities");
+	if (!dentry) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
+	if (ret)
+		goto err;
+
+	policycap_dir = dentry;
+
 out:
 	return ret;
 err:
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index f05f97a..e85a479 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -13,6 +13,11 @@
  *
  * 	Added conditional policy language extensions
  *
+ * Updated: Hewlett-Packard <paul.moore@hp.com>
+ *
+ *      Added support for the policy capability bitmap
+ *
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
  *	This program is free software; you can redistribute it and/or modify
@@ -102,6 +107,11 @@ static struct policydb_compat_info policydb_compat[] = {
 		.sym_num        = SYM_NUM,
 		.ocon_num       = OCON_NUM,
 	},
+	{
+		.version        = POLICYDB_VERSION_CAPBITMAP,
+		.sym_num        = SYM_NUM,
+		.ocon_num       = OCON_NUM,
+	}
 };
 
 static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -183,6 +193,8 @@ static int policydb_init(struct policydb *p)
 	if (rc)
 		goto out_free_avtab;
 
+	ebitmap_init(&p->policycaps);
+
 out:
 	return rc;
 
@@ -677,6 +689,8 @@ void policydb_destroy(struct policydb *p)
 	}
 	kfree(p->type_attr_map);
 
+	ebitmap_destroy(&p->policycaps);
+
 	return;
 }
 
@@ -1531,6 +1545,10 @@ int policydb_read(struct policydb *p, void *fp)
 		}
 	}
 
+	if (p->policyvers >= POLICYDB_VERSION_CAPBITMAP &&
+	    ebitmap_read(&p->policycaps, fp) != 0)
+		goto bad;
+
 	info = policydb_lookup_compat(p->policyvers);
 	if (!info) {
 		printk(KERN_ERR "security:  unable to find policy compat info "
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 8319d5f..e621048 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -241,6 +241,8 @@ struct policydb {
 	/* type -> attribute reverse mapping */
 	struct ebitmap *type_attr_map;
 
+	struct ebitmap policycaps;
+
 	unsigned int policyvers;
 };
 
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 6100fc0..7d8c656 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -16,12 +16,13 @@
  * Updated: Hewlett-Packard <paul.moore@hp.com>
  *
  *      Added support for NetLabel
+ *      Added support for the policy capability bitmap
  *
  * Updated: Chad Sellers <csellers@tresys.com>
  *
  *  Added validation of kernel classes and permissions
  *
- * Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
+ * Copyright (C) 2006 - 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
  * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC
  * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
@@ -59,6 +60,8 @@
 extern void selnl_notify_policyload(u32 seqno);
 unsigned int policydb_loaded_version;
 
+int selinux_policycap_netpeer;
+
 /*
  * This is declared in avc.c
  */
@@ -1304,6 +1307,9 @@ int security_load_policy(void *data, size_t len)
 			return -EINVAL;
 		}
 		policydb_loaded_version = policydb.policyvers;
+		selinux_policycap_netpeer = 
+		  ebitmap_get_bit(&policydb.policycaps,
+				  POLICYDB_CAPABILITY_NETPEER);
 		ss_initialized = 1;
 		seqno = ++latest_granting;
 		LOAD_UNLOCK;
@@ -2102,6 +2108,37 @@ err:
 	return rc;
 }
 
+int security_get_policycaps(int *len, int **values)
+{
+	int rc = -ENOMEM;
+	unsigned int iter;
+
+	POLICY_RDLOCK;
+
+	*values = kcalloc(POLICYDB_CAPABILITY_MAX, sizeof(int), GFP_ATOMIC);
+	if (*values == NULL)
+		goto out;
+	for (iter = 0; iter < POLICYDB_CAPABILITY_MAX; iter++)
+		(*values)[iter] = ebitmap_get_bit(&policydb.policycaps, iter);
+
+	*len = POLICYDB_CAPABILITY_MAX;
+
+out:
+	POLICY_RDUNLOCK;
+	return rc;
+}
+
+int security_policycap_supported(unsigned int req_cap)
+{
+	int rc;
+
+	POLICY_RDLOCK;
+	rc = ebitmap_get_bit(&policydb.policycaps, req_cap);
+	POLICY_RDUNLOCK;
+
+	return rc;
+}
+
 struct selinux_audit_rule {
 	u32 au_seqno;
 	struct context au_ctxt;


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [RFC PATCH v2 2/2] [SELINUX] Better integration between peer labeling subsystems
  2007-09-26 21:32 [RFC PATCH v2 0/2] Updated patches based on comments Paul Moore
  2007-09-26 21:32 ` [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22 Paul Moore
@ 2007-09-26 21:32 ` Paul Moore
  1 sibling, 0 replies; 8+ messages in thread
From: Paul Moore @ 2007-09-26 21:32 UTC (permalink / raw)
  To: selinux

Rename the existing selinux_skb_extlbl_sid() function to
selinux_skb_peerlbl_sid() and modify it's behavior such that it now reconciles
multiple peer/external labels and if reconciliation is not possible it returns
an error to the caller.
---

 security/selinux/hooks.c            |   42 +++++++++++--------
 security/selinux/include/security.h |    2 +
 security/selinux/ss/services.c      |   76 +++++++++++++++++++++++++++++++++++
 3 files changed, 101 insertions(+), 19 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 0753b20..9923c01 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3132,32 +3132,31 @@ static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
 }
 
 /**
- * selinux_skb_extlbl_sid - Determine the external label of a packet
+ * selinux_skb_peerlbl_sid - Determine the peer label of a packet
  * @skb: the packet
- * @sid: the packet's SID
+ * @sid: the packet's peer label SID
  *
  * Description:
- * Check the various different forms of external packet labeling and determine
- * the external SID for the packet.  If only one form of external labeling is
- * present then it is used, if both labeled IPsec and NetLabel labels are
- * present then the SELinux type information is taken from the labeled IPsec
- * SA and the MLS sensitivity label information is taken from the NetLabel
- * security attributes.  This bit of "magic" is done in the call to
- * selinux_netlbl_skbuff_getsid().
+ * Check the various different forms of network peer labeling and determine
+ * the peer label/SID for the packet; most of the magic actually occurs in
+ * the security server function security_net_peersid_cmp().  The function
+ * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
+ * or -EACCES if @sid is invalid due to inconsistencies with the different
+ * peer labels.
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb, u32 *sid)
+static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u32 *sid)
 {
 	u32 xfrm_sid;
 	u32 nlbl_sid;
 
 	selinux_skb_xfrm_sid(skb, &xfrm_sid);
-	if (selinux_netlbl_skbuff_getsid(skb,
-					 (xfrm_sid == SECSID_NULL ?
-					  SECINITSID_NETMSG : xfrm_sid),
-					 &nlbl_sid) != 0)
-		nlbl_sid = SECSID_NULL;
-	*sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
+	selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &nlbl_sid);
+
+	if (security_net_peersid_resolve(nlbl_sid, xfrm_sid, sid) != 0)
+		return -EACCES;
+
+	return 0;
 }
 
 /* socket security operations */
@@ -3640,6 +3639,9 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 	if (err)
 		goto out;
 
+	/* XXX - make use of selinux_skb_peerlbl_sid() here but only once we
+	 *       have the new peer object class in place */
+
 	err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad);
 	if (err)
 		goto out;
@@ -3701,7 +3703,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff *
 	if (sock && sock->sk->sk_family == PF_UNIX)
 		selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
 	else if (skb)
-		selinux_skb_extlbl_sid(skb, &peer_secid);
+		selinux_skb_peerlbl_sid(skb, &peer_secid);
 
 	if (peer_secid == SECSID_NULL)
 		err = -EINVAL;
@@ -3762,7 +3764,9 @@ static int selinux_inet_conn_request(struct sock *sk, struct sk_buff *skb,
 	u32 newsid;
 	u32 peersid;
 
-	selinux_skb_extlbl_sid(skb, &peersid);
+	err = selinux_skb_peerlbl_sid(skb, &peersid);
+	if (err)
+		return err;
 	if (peersid == SECSID_NULL) {
 		req->secid = sksec->sid;
 		req->peer_secid = SECSID_NULL;
@@ -3800,7 +3804,7 @@ static void selinux_inet_conn_established(struct sock *sk,
 {
 	struct sk_security_struct *sksec = sk->sk_security;
 
-	selinux_skb_extlbl_sid(skb, &sksec->peer_sid);
+	selinux_skb_peerlbl_sid(skb, &sksec->peer_sid);
 }
 
 static void selinux_req_classify_flow(const struct request_sock *req,
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index d7e6ed2..4817dcf 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -100,6 +100,8 @@ int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid,
 
 int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
 
+int security_net_peersid_resolve(u32 nlbl_sid, u32 xfrm_sid, u32 *peer_sid);
+
 int security_get_classes(char ***classes, int *nclasses);
 int security_get_permissions(char *class, char ***perms, int *nperms);
 int security_get_policycaps(int *len, int **values);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 7d8c656..1669028 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2013,6 +2013,82 @@ out:
 	return rc;
 }
 
+/**
+ * security_net_peersid_cmp - Compare and resolve two network peer SIDs
+ * @nlbl_sid: NetLabel SID
+ * @xfrm_sid: XFRM SID
+ *
+ * Description:
+ * Compare the @nlbl_sid and @xfrm_sid values and if the two SIDs can be
+ * resolved into a single SID it is returned via @peer_sid and the function
+ * returns zero.  Otherwise @peer_sid is set to SECSID_NULL and the function
+ * returns a negative value.  A table summarizing the behavior is below:
+ *
+ *                                 | function return |      @sid
+ *   ------------------------------+-----------------+-----------------
+ *   no peer labels                |        0        |    SECSID_NULL
+ *   single peer label             |        0        |    <peer_label>
+ *   multiple, consistent labels   |        0        |    <peer_label>
+ *   multiple, inconsistent labels |    -<errno>     |    SECSID_NULL
+ *
+ */
+int security_net_peersid_resolve(u32 nlbl_sid, u32 xfrm_sid, u32 *peer_sid)
+{
+	int rc;
+	struct context *nlbl_ctx;
+	struct context *xfrm_ctx;
+
+	/* handle the common (which also happens to be the set of easy) cases
+	 * right away, these two if statements catch everything involving a
+	 * single or absent peer SID/label */
+	if (xfrm_sid == SECSID_NULL) {
+		*peer_sid = nlbl_sid;
+		return 0;
+	}
+	if (nlbl_sid == SECSID_NULL) {
+		*peer_sid = xfrm_sid;
+		return 0;
+	}
+
+	if (!ss_initialized || !selinux_mls_enabled) {
+		*peer_sid = SECSID_NULL;
+		return 0;
+	}
+
+	POLICY_RDLOCK;
+
+	nlbl_ctx = sidtab_search(&sidtab, nlbl_sid);
+	if (!nlbl_ctx) {
+		printk(KERN_ERR
+		       "security_sid_mls_cmp:  unrecognized SID %d\n",
+		       nlbl_sid);
+		rc = -EINVAL;
+		goto net_peersid_resolve_return_slowpath;
+	}
+	xfrm_ctx = sidtab_search(&sidtab, xfrm_sid);
+	if (!xfrm_ctx) {
+		printk(KERN_ERR
+		       "security_sid_mls_cmp:  unrecognized SID %d\n",
+		       xfrm_sid);
+		rc = -EINVAL;
+		goto net_peersid_resolve_return_slowpath;
+	}
+	rc = mls_context_cmp(nlbl_ctx, xfrm_ctx);
+
+net_peersid_resolve_return_slowpath:
+	POLICY_RDUNLOCK;
+	if (rc == 0)
+		/* at present NetLabel SIDs/labels really only carry MLS
+		 * information so if the MLS portion of the NetLabel SID
+		 * matches the MLS portion of the labeled XFRM SID/label
+		 * then pass along the XFRM SID as it has the most peer label
+		 * information */
+		*peer_sid = xfrm_sid;
+	else
+		*peer_sid = SECSID_NULL;
+	return rc;
+}
+
 static int get_classes_callback(void *k, void *d, void *args)
 {
 	struct class_datum *datum = d;


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22
  2007-09-26 21:32 ` [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22 Paul Moore
@ 2007-09-26 22:24   ` Joshua Brindle
  2007-09-27 11:36     ` Stephen Smalley
  2007-09-27 11:46     ` Paul Moore
  0 siblings, 2 replies; 8+ messages in thread
From: Joshua Brindle @ 2007-09-26 22:24 UTC (permalink / raw)
  To: Paul Moore; +Cc: selinux

Paul Moore wrote:
> Add a new policy capabilities bitmap to SELinux policy version 22.  This bitmap
> will enable the security server to query the policy to determine which features
> it supports.
> ---
>
>  security/selinux/include/security.h |   15 +++++-
>  security/selinux/selinuxfs.c        |   90 +++++++++++++++++++++++++++++++++--
>  security/selinux/ss/policydb.c      |   18 +++++++
>  security/selinux/ss/policydb.h      |    2 +
>  security/selinux/ss/services.c      |   39 +++++++++++++++
>  5 files changed, 158 insertions(+), 6 deletions(-)
>
> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> index 83bdd4d..d7e6ed2 100644
> --- a/security/selinux/include/security.h
> +++ b/security/selinux/include/security.h
> @@ -25,13 +25,14 @@
>  #define POLICYDB_VERSION_MLS		19
>  #define POLICYDB_VERSION_AVTAB		20
>  #define POLICYDB_VERSION_RANGETRANS	21
> +#define POLICYDB_VERSION_CAPBITMAP	22
>  
>   

I didn't like this name (I almost used it myself) because it sounds like 
we are doing something with linux capabilities, I ended up using 
POLICYDB_VERSION_PCAPS (for policy capabilities)

>  /* Range of policy versions we understand*/
>  #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
>  #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
>  #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
>  #else
> -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_RANGETRANS
> +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_CAPBITMAP
>  #endif
>  
>  struct netlbl_lsm_secattr;
> @@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
>  extern int selinux_enabled;
>  extern int selinux_mls_enabled;
>  
> +/* Policy capabilities */
> +enum {
> +	POLICYDB_CAPABILITY_NETPEER,
> +	__POLICYDB_CAPABILITY_MAX
> +};
> +#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
> +
>   

Hrm, I just used an ebitmap and didn't set a max at all.

> +extern int selinux_policycap_netpeer;
> +
>  int security_load_policy(void * data, size_t len);
>  
> +int security_policycap_supported(unsigned int req_cap);
> +
>  #define SEL_VEC_MAX 32
>  struct av_decision {
>  	u32 allowed;
> @@ -90,6 +102,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
>  
>  int security_get_classes(char ***classes, int *nclasses);
>  int security_get_permissions(char *class, char ***perms, int *nperms);
> +int security_get_policycaps(int *len, int **values);
>  
>   

We can fill in an array but I thought it'd be better just to use an 
ebitmap and ebitmap_get_bit()

>  #define SECURITY_FS_USE_XATTR		1 /* use xattr */
>  #define SECURITY_FS_USE_TRANS		2 /* use transition SIDs, e.g. devpts/tmpfs */
> diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> index c9e92da..c3e6f06 100644
> --- a/security/selinux/selinuxfs.c
> +++ b/security/selinux/selinuxfs.c
> @@ -2,6 +2,11 @@
>   *
>   * 	Added conditional policy language extensions
>   *
> + *  Updated: Hewlett-Packard <paul.moore@hp.com>
> + *
> + *      Added support for the policy capability bitmap
> + *
> + * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
>   * Copyright (C) 2003 - 2004 Tresys Technology, LLC
>   * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
>   *	This program is free software; you can redistribute it and/or modify
> @@ -35,6 +40,11 @@
>  #include "objsec.h"
>  #include "conditional.h"
>  
> +/* Policy capability filenames */
> +static char *policycap_names[] = {
> +	"network_peer_controls"
> +};
> +
>  unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
>  
>  #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
> @@ -71,6 +81,9 @@ static int *bool_pending_values = NULL;
>  static struct dentry *class_dir = NULL;
>  static unsigned long last_class_ino;
>  
> +/* global data for policy capabilities */
> +static struct dentry *policycap_dir = NULL;
> +
>  extern void selnl_notify_setenforce(int val);
>  
>  /* Check whether a task is allowed to use a security operation. */
> @@ -108,10 +121,11 @@ enum sel_inos {
>  
>  static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
>  
> -#define SEL_INITCON_INO_OFFSET 	0x01000000
> -#define SEL_BOOL_INO_OFFSET	0x02000000
> -#define SEL_CLASS_INO_OFFSET	0x04000000
> -#define SEL_INO_MASK		0x00ffffff
> +#define SEL_INITCON_INO_OFFSET		0x01000000
> +#define SEL_BOOL_INO_OFFSET		0x02000000
> +#define SEL_CLASS_INO_OFFSET		0x04000000
> +#define SEL_POLICYCAP_INO_OFFSET	0x08000000
> +#define SEL_INO_MASK			0x00ffffff
>   

whitespace changes?

>  
>  #define TMPBUFLEN	12
>  static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
> @@ -243,6 +257,7 @@ static const struct file_operations sel_policyvers_ops = {
>  /* declaration for sel_write_load */
>  static int sel_make_bools(void);
>  static int sel_make_classes(void);
> +static int sel_make_policycap(void);
>  
>  /* declaration for sel_make_class_dirs */
>  static int sel_make_dir(struct inode *dir, struct dentry *dentry,
> @@ -303,6 +318,12 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
>  	}
>  
>  	ret = sel_make_classes();
> +	if (ret) {
> +		length = ret;
> +		goto out1;
> +	}
> +
> +	ret = sel_make_policycap();
>  	if (ret)
>  		length = ret;
>  	else
> @@ -1384,6 +1405,25 @@ static const struct file_operations sel_perm_ops = {
>  	.read		= sel_read_perm,
>  };
>  
> +static ssize_t sel_read_policycap(struct file *file, char __user *buf,
> +				  size_t count, loff_t *ppos)
> +{
> +	int value;
> +	char tmpbuf[TMPBUFLEN];
> +	ssize_t length;
> +	unsigned long inode = file->f_path.dentry->d_inode->i_ino;
> +
> +	value = security_policycap_supported(inode &
> +					     (SEL_POLICYCAP_INO_OFFSET - 1));
> +	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
> +
> +	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
> +}
> +
> +static const struct file_operations sel_policycap_ops = {
> +	.read		= sel_read_policycap,
> +};
> +
>   

Yea, I wondered how we were going to do this, we could have symbolic 
names for each of them or we could just output offsets and let userspace 
decipher it. I guess having symbolic names in a directory is better 
(eg., /selinux/policy_caps/peersid_reconciliation)

>  static int sel_make_perm_files(char *objclass, int classvalue,
>  				struct dentry *dir)
>  {
> @@ -1530,6 +1570,36 @@ out:
>  	return rc;
>  }
>  
> +static int sel_make_policycap(void)
> +{
> +	unsigned int iter;
> +	struct dentry *dentry = NULL;
> +	struct inode *inode = NULL;
> +
> +	sel_remove_entries(policycap_dir);
> +
> +	for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
> +		if (iter <= ARRAY_SIZE(policycap_names))
> +			dentry = d_alloc_name(policycap_dir,
> +					      policycap_names[iter]);
> +		else
> +			dentry = d_alloc_name(policycap_dir, "unknown");
> +
> +		if (dentry == NULL)
> +			return -ENOMEM;
> +
> +		inode = sel_make_inode(policycap_dir->d_sb, S_IFREG | S_IRUGO);
> +		if (inode == NULL)
> +			return -ENOMEM;
> +
> +		inode->i_fop = &sel_policycap_ops;
> +		inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
> +		d_add(dentry, inode);	
> +	}
> +
> +	return 0;
> +}
> +
>   

err, yea, agreed :)

>  static int sel_make_dir(struct inode *dir, struct dentry *dentry,
>  			unsigned long *ino)
>  {
> @@ -1656,6 +1726,18 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
>  
>  	class_dir = dentry;
>  
> +	dentry = d_alloc_name(sb->s_root, "policy_capabilities");
> +	if (!dentry) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
> +	if (ret)
> +		goto err;
> +
> +	policycap_dir = dentry;
> +
>  out:
>  	return ret;
>  err:
> diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
> index f05f97a..e85a479 100644
> --- a/security/selinux/ss/policydb.c
> +++ b/security/selinux/ss/policydb.c
> @@ -13,6 +13,11 @@
>   *
>   * 	Added conditional policy language extensions
>   *
> + * Updated: Hewlett-Packard <paul.moore@hp.com>
> + *
> + *      Added support for the policy capability bitmap
> + *
> + * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
>   * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
>   * Copyright (C) 2003 - 2004 Tresys Technology, LLC
>   *	This program is free software; you can redistribute it and/or modify
> @@ -102,6 +107,11 @@ static struct policydb_compat_info policydb_compat[] = {
>  		.sym_num        = SYM_NUM,
>  		.ocon_num       = OCON_NUM,
>  	},
> +	{
> +		.version        = POLICYDB_VERSION_CAPBITMAP,
> +		.sym_num        = SYM_NUM,
> +		.ocon_num       = OCON_NUM,
> +	}
>  };
>  
>  static struct policydb_compat_info *policydb_lookup_compat(int version)
> @@ -183,6 +193,8 @@ static int policydb_init(struct policydb *p)
>  	if (rc)
>  		goto out_free_avtab;
>  
> +	ebitmap_init(&p->policycaps);
> +
>  out:
>  	return rc;
>  
> @@ -677,6 +689,8 @@ void policydb_destroy(struct policydb *p)
>  	}
>  	kfree(p->type_attr_map);
>  
> +	ebitmap_destroy(&p->policycaps);
> +
>  	return;
>  }
>  
> @@ -1531,6 +1545,10 @@ int policydb_read(struct policydb *p, void *fp)
>  		}
>  	}
>  
> +	if (p->policyvers >= POLICYDB_VERSION_CAPBITMAP &&
> +	    ebitmap_read(&p->policycaps, fp) != 0)
> +		goto bad;
> +
>  	info = policydb_lookup_compat(p->policyvers);
>  	if (!info) {
>  		printk(KERN_ERR "security:  unable to find policy compat info "
> diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
> index 8319d5f..e621048 100644
> --- a/security/selinux/ss/policydb.h
> +++ b/security/selinux/ss/policydb.h
> @@ -241,6 +241,8 @@ struct policydb {
>  	/* type -> attribute reverse mapping */
>  	struct ebitmap *type_attr_map;
>  
> +	struct ebitmap policycaps;
> +
>  	unsigned int policyvers;
>  };
>  
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index 6100fc0..7d8c656 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -16,12 +16,13 @@
>   * Updated: Hewlett-Packard <paul.moore@hp.com>
>   *
>   *      Added support for NetLabel
> + *      Added support for the policy capability bitmap
>   *
>   * Updated: Chad Sellers <csellers@tresys.com>
>   *
>   *  Added validation of kernel classes and permissions
>   *
> - * Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
> + * Copyright (C) 2006 - 2007 Hewlett-Packard Development Company, L.P.
>   * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
>   * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC
>   * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
> @@ -59,6 +60,8 @@
>  extern void selnl_notify_policyload(u32 seqno);
>  unsigned int policydb_loaded_version;
>  
> +int selinux_policycap_netpeer;
> +
>  /*
>   * This is declared in avc.c
>   */
> @@ -1304,6 +1307,9 @@ int security_load_policy(void *data, size_t len)
>  			return -EINVAL;
>  		}
>  		policydb_loaded_version = policydb.policyvers;
> +		selinux_policycap_netpeer = 
> +		  ebitmap_get_bit(&policydb.policycaps,
> +				  POLICYDB_CAPABILITY_NETPEER);
>  		ss_initialized = 1;
>  		seqno = ++latest_granting;
>  		LOAD_UNLOCK;
> @@ -2102,6 +2108,37 @@ err:
>  	return rc;
>  }
>  
> +int security_get_policycaps(int *len, int **values)
> +{
> +	int rc = -ENOMEM;
> +	unsigned int iter;
> +
> +	POLICY_RDLOCK;
> +
> +	*values = kcalloc(POLICYDB_CAPABILITY_MAX, sizeof(int), GFP_ATOMIC);
> +	if (*values == NULL)
> +		goto out;
> +	for (iter = 0; iter < POLICYDB_CAPABILITY_MAX; iter++)
> +		(*values)[iter] = ebitmap_get_bit(&policydb.policycaps, iter);
> +
> +	*len = POLICYDB_CAPABILITY_MAX;
> +
> +out:
> +	POLICY_RDUNLOCK;
> +	return rc;
> +}
> +
>   

Why do we want to write out to an array instead of just passing the 
ebitmap around?

> +int security_policycap_supported(unsigned int req_cap)
> +{
> +	int rc;
> +
> +	POLICY_RDLOCK;
> +	rc = ebitmap_get_bit(&policydb.policycaps, req_cap);
> +	POLICY_RDUNLOCK;
> +
> +	return rc;
> +}
> +
>   

Shouldn't this just check if policyvers > POLICYDB_VERSION_CAPBITMAP? it 
could be inlined too.

>  struct selinux_audit_rule {
>  	u32 au_seqno;
>  	struct context au_ctxt;
>
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
>
>   



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22
  2007-09-26 22:24   ` Joshua Brindle
@ 2007-09-27 11:36     ` Stephen Smalley
  2007-09-27 18:10       ` Joshua Brindle
  2007-09-27 19:07       ` Paul Moore
  2007-09-27 11:46     ` Paul Moore
  1 sibling, 2 replies; 8+ messages in thread
From: Stephen Smalley @ 2007-09-27 11:36 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: Paul Moore, selinux

On Wed, 2007-09-26 at 18:24 -0400, Joshua Brindle wrote:
> Paul Moore wrote:
> > Add a new policy capabilities bitmap to SELinux policy version 22.  This bitmap
> > will enable the security server to query the policy to determine which features
> > it supports.
> > ---
> >
> >  security/selinux/include/security.h |   15 +++++-
> >  security/selinux/selinuxfs.c        |   90 +++++++++++++++++++++++++++++++++--
> >  security/selinux/ss/policydb.c      |   18 +++++++
> >  security/selinux/ss/policydb.h      |    2 +
> >  security/selinux/ss/services.c      |   39 +++++++++++++++
> >  5 files changed, 158 insertions(+), 6 deletions(-)
> >
> > diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
> > index 83bdd4d..d7e6ed2 100644
> > --- a/security/selinux/include/security.h
> > +++ b/security/selinux/include/security.h
> > @@ -25,13 +25,14 @@
> >  #define POLICYDB_VERSION_MLS		19
> >  #define POLICYDB_VERSION_AVTAB		20
> >  #define POLICYDB_VERSION_RANGETRANS	21
> > +#define POLICYDB_VERSION_CAPBITMAP	22
> >  
> >   
> 
> I didn't like this name (I almost used it myself) because it sounds like 
> we are doing something with linux capabilities, I ended up using 
> POLICYDB_VERSION_PCAPS (for policy capabilities)

Doesn't help much; PCAP sounds like process capabilities, and
CAP_SETPCAP ;)  I don't think the name matters either way.

> >  /* Range of policy versions we understand*/
> >  #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
> >  #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
> >  #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
> >  #else
> > -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_RANGETRANS
> > +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_CAPBITMAP
> >  #endif
> >  
> >  struct netlbl_lsm_secattr;
> > @@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
> >  extern int selinux_enabled;
> >  extern int selinux_mls_enabled;
> >  
> > +/* Policy capabilities */
> > +enum {
> > +	POLICYDB_CAPABILITY_NETPEER,
> > +	__POLICYDB_CAPABILITY_MAX
> > +};
> > +#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
> > +
> >   
> 
> Hrm, I just used an ebitmap and didn't set a max at all.

ebitmaps are a security server internal construct; you have to export
them in a different form to users of the security server, like
selinuxfs, the hook functions, etc.  Or you'd have to move them out a
layer.

> 
> > +extern int selinux_policycap_netpeer;
> > +
> >  int security_load_policy(void * data, size_t len);
> >  
> > +int security_policycap_supported(unsigned int req_cap);
> > +
> >  #define SEL_VEC_MAX 32
> >  struct av_decision {
> >  	u32 allowed;
> > @@ -90,6 +102,7 @@ int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid);
> >  
> >  int security_get_classes(char ***classes, int *nclasses);
> >  int security_get_permissions(char *class, char ***perms, int *nperms);
> > +int security_get_policycaps(int *len, int **values);
> >  
> >   
> 
> We can fill in an array but I thought it'd be better just to use an 
> ebitmap and ebitmap_get_bit()

See above.

> 
> >  #define SECURITY_FS_USE_XATTR		1 /* use xattr */
> >  #define SECURITY_FS_USE_TRANS		2 /* use transition SIDs, e.g. devpts/tmpfs */
> > diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
> > index c9e92da..c3e6f06 100644
> > --- a/security/selinux/selinuxfs.c
> > +++ b/security/selinux/selinuxfs.c
> > @@ -2,6 +2,11 @@
> >   *
> >   * 	Added conditional policy language extensions
> >   *
> > + *  Updated: Hewlett-Packard <paul.moore@hp.com>
> > + *
> > + *      Added support for the policy capability bitmap
> > + *
> > + * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
> >   * Copyright (C) 2003 - 2004 Tresys Technology, LLC
> >   * Copyright (C) 2004 Red Hat, Inc., James Morris <jmorris@redhat.com>
> >   *	This program is free software; you can redistribute it and/or modify
> > @@ -35,6 +40,11 @@
> >  #include "objsec.h"
> >  #include "conditional.h"
> >  
> > +/* Policy capability filenames */
> > +static char *policycap_names[] = {
> > +	"network_peer_controls"
> > +};
> > +
> >  unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
> >  
> >  #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
> > @@ -71,6 +81,9 @@ static int *bool_pending_values = NULL;
> >  static struct dentry *class_dir = NULL;
> >  static unsigned long last_class_ino;
> >  
> > +/* global data for policy capabilities */
> > +static struct dentry *policycap_dir = NULL;
> > +
> >  extern void selnl_notify_setenforce(int val);
> >  
> >  /* Check whether a task is allowed to use a security operation. */
> > @@ -108,10 +121,11 @@ enum sel_inos {
> >  
> >  static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
> >  
> > -#define SEL_INITCON_INO_OFFSET 	0x01000000
> > -#define SEL_BOOL_INO_OFFSET	0x02000000
> > -#define SEL_CLASS_INO_OFFSET	0x04000000
> > -#define SEL_INO_MASK		0x00ffffff
> > +#define SEL_INITCON_INO_OFFSET		0x01000000
> > +#define SEL_BOOL_INO_OFFSET		0x02000000
> > +#define SEL_CLASS_INO_OFFSET		0x04000000
> > +#define SEL_POLICYCAP_INO_OFFSET	0x08000000
> > +#define SEL_INO_MASK			0x00ffffff
> >   
> 
> whitespace changes?

Are ok to make them consistent when modifying the code (addition of
POLICYCAP_INO_OFFSET).

> 
> >  
> >  #define TMPBUFLEN	12
> >  static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
> > @@ -243,6 +257,7 @@ static const struct file_operations sel_policyvers_ops = {
> >  /* declaration for sel_write_load */
> >  static int sel_make_bools(void);
> >  static int sel_make_classes(void);
> > +static int sel_make_policycap(void);
> >  
> >  /* declaration for sel_make_class_dirs */
> >  static int sel_make_dir(struct inode *dir, struct dentry *dentry,
> > @@ -303,6 +318,12 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
> >  	}
> >  
> >  	ret = sel_make_classes();
> > +	if (ret) {
> > +		length = ret;
> > +		goto out1;
> > +	}
> > +
> > +	ret = sel_make_policycap();
> >  	if (ret)
> >  		length = ret;
> >  	else
> > @@ -1384,6 +1405,25 @@ static const struct file_operations sel_perm_ops = {
> >  	.read		= sel_read_perm,
> >  };
> >  
> > +static ssize_t sel_read_policycap(struct file *file, char __user *buf,
> > +				  size_t count, loff_t *ppos)
> > +{
> > +	int value;
> > +	char tmpbuf[TMPBUFLEN];
> > +	ssize_t length;
> > +	unsigned long inode = file->f_path.dentry->d_inode->i_ino;
> > +
> > +	value = security_policycap_supported(inode &
> > +					     (SEL_POLICYCAP_INO_OFFSET - 1));
> > +	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
> > +
> > +	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
> > +}
> > +
> > +static const struct file_operations sel_policycap_ops = {
> > +	.read		= sel_read_policycap,
> > +};
> > +
> >   
> 
> Yea, I wondered how we were going to do this, we could have symbolic 
> names for each of them or we could just output offsets and let userspace 
> decipher it. I guess having symbolic names in a directory is better 
> (eg., /selinux/policy_caps/peersid_reconciliation)
> 
> >  static int sel_make_perm_files(char *objclass, int classvalue,
> >  				struct dentry *dir)
> >  {
> > @@ -1530,6 +1570,36 @@ out:
> >  	return rc;
> >  }
> >  
> > +static int sel_make_policycap(void)
> > +{
> > +	unsigned int iter;
> > +	struct dentry *dentry = NULL;
> > +	struct inode *inode = NULL;
> > +
> > +	sel_remove_entries(policycap_dir);
> > +
> > +	for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
> > +		if (iter <= ARRAY_SIZE(policycap_names))
> > +			dentry = d_alloc_name(policycap_dir,
> > +					      policycap_names[iter]);
> > +		else
> > +			dentry = d_alloc_name(policycap_dir, "unknown");
> > +
> > +		if (dentry == NULL)
> > +			return -ENOMEM;
> > +
> > +		inode = sel_make_inode(policycap_dir->d_sb, S_IFREG | S_IRUGO);
> > +		if (inode == NULL)
> > +			return -ENOMEM;
> > +
> > +		inode->i_fop = &sel_policycap_ops;
> > +		inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
> > +		d_add(dentry, inode);	
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >   
> 
> err, yea, agreed :)
> 
> >  static int sel_make_dir(struct inode *dir, struct dentry *dentry,
> >  			unsigned long *ino)
> >  {
> > @@ -1656,6 +1726,18 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent)
> >  
> >  	class_dir = dentry;
> >  
> > +	dentry = d_alloc_name(sb->s_root, "policy_capabilities");
> > +	if (!dentry) {
> > +		ret = -ENOMEM;
> > +		goto err;
> > +	}
> > +
> > +	ret = sel_make_dir(root_inode, dentry, &sel_last_ino);
> > +	if (ret)
> > +		goto err;
> > +
> > +	policycap_dir = dentry;
> > +
> >  out:
> >  	return ret;
> >  err:
> > diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
> > index f05f97a..e85a479 100644
> > --- a/security/selinux/ss/policydb.c
> > +++ b/security/selinux/ss/policydb.c
> > @@ -13,6 +13,11 @@
> >   *
> >   * 	Added conditional policy language extensions
> >   *
> > + * Updated: Hewlett-Packard <paul.moore@hp.com>
> > + *
> > + *      Added support for the policy capability bitmap
> > + *
> > + * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
> >   * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
> >   * Copyright (C) 2003 - 2004 Tresys Technology, LLC
> >   *	This program is free software; you can redistribute it and/or modify
> > @@ -102,6 +107,11 @@ static struct policydb_compat_info policydb_compat[] = {
> >  		.sym_num        = SYM_NUM,
> >  		.ocon_num       = OCON_NUM,
> >  	},
> > +	{
> > +		.version        = POLICYDB_VERSION_CAPBITMAP,
> > +		.sym_num        = SYM_NUM,
> > +		.ocon_num       = OCON_NUM,
> > +	}
> >  };
> >  
> >  static struct policydb_compat_info *policydb_lookup_compat(int version)
> > @@ -183,6 +193,8 @@ static int policydb_init(struct policydb *p)
> >  	if (rc)
> >  		goto out_free_avtab;
> >  
> > +	ebitmap_init(&p->policycaps);
> > +
> >  out:
> >  	return rc;
> >  
> > @@ -677,6 +689,8 @@ void policydb_destroy(struct policydb *p)
> >  	}
> >  	kfree(p->type_attr_map);
> >  
> > +	ebitmap_destroy(&p->policycaps);
> > +
> >  	return;
> >  }
> >  
> > @@ -1531,6 +1545,10 @@ int policydb_read(struct policydb *p, void *fp)
> >  		}
> >  	}
> >  
> > +	if (p->policyvers >= POLICYDB_VERSION_CAPBITMAP &&
> > +	    ebitmap_read(&p->policycaps, fp) != 0)
> > +		goto bad;
> > +
> >  	info = policydb_lookup_compat(p->policyvers);
> >  	if (!info) {
> >  		printk(KERN_ERR "security:  unable to find policy compat info "
> > diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
> > index 8319d5f..e621048 100644
> > --- a/security/selinux/ss/policydb.h
> > +++ b/security/selinux/ss/policydb.h
> > @@ -241,6 +241,8 @@ struct policydb {
> >  	/* type -> attribute reverse mapping */
> >  	struct ebitmap *type_attr_map;
> >  
> > +	struct ebitmap policycaps;
> > +
> >  	unsigned int policyvers;
> >  };
> >  
> > diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> > index 6100fc0..7d8c656 100644
> > --- a/security/selinux/ss/services.c
> > +++ b/security/selinux/ss/services.c
> > @@ -16,12 +16,13 @@
> >   * Updated: Hewlett-Packard <paul.moore@hp.com>
> >   *
> >   *      Added support for NetLabel
> > + *      Added support for the policy capability bitmap
> >   *
> >   * Updated: Chad Sellers <csellers@tresys.com>
> >   *
> >   *  Added validation of kernel classes and permissions
> >   *
> > - * Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
> > + * Copyright (C) 2006 - 2007 Hewlett-Packard Development Company, L.P.
> >   * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
> >   * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC
> >   * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com>
> > @@ -59,6 +60,8 @@
> >  extern void selnl_notify_policyload(u32 seqno);
> >  unsigned int policydb_loaded_version;
> >  
> > +int selinux_policycap_netpeer;
> > +
> >  /*
> >   * This is declared in avc.c
> >   */
> > @@ -1304,6 +1307,9 @@ int security_load_policy(void *data, size_t len)
> >  			return -EINVAL;
> >  		}
> >  		policydb_loaded_version = policydb.policyvers;
> > +		selinux_policycap_netpeer = 
> > +		  ebitmap_get_bit(&policydb.policycaps,
> > +				  POLICYDB_CAPABILITY_NETPEER);
> >  		ss_initialized = 1;
> >  		seqno = ++latest_granting;
> >  		LOAD_UNLOCK;
> > @@ -2102,6 +2108,37 @@ err:
> >  	return rc;
> >  }
> >  
> > +int security_get_policycaps(int *len, int **values)
> > +{
> > +	int rc = -ENOMEM;
> > +	unsigned int iter;
> > +
> > +	POLICY_RDLOCK;
> > +
> > +	*values = kcalloc(POLICYDB_CAPABILITY_MAX, sizeof(int), GFP_ATOMIC);
> > +	if (*values == NULL)
> > +		goto out;
> > +	for (iter = 0; iter < POLICYDB_CAPABILITY_MAX; iter++)
> > +		(*values)[iter] = ebitmap_get_bit(&policydb.policycaps, iter);
> > +
> > +	*len = POLICYDB_CAPABILITY_MAX;
> > +
> > +out:
> > +	POLICY_RDUNLOCK;
> > +	return rc;
> > +}
> > +
> >   
> 
> Why do we want to write out to an array instead of just passing the 
> ebitmap around?

Because the callers don't know about ebitmaps and the ebitmap life cycle
is bound to the policy.

> 
> > +int security_policycap_supported(unsigned int req_cap)
> > +{
> > +	int rc;
> > +
> > +	POLICY_RDLOCK;
> > +	rc = ebitmap_get_bit(&policydb.policycaps, req_cap);
> > +	POLICY_RDUNLOCK;
> > +
> > +	return rc;
> > +}
> > +
> >   
> 
> Shouldn't this just check if policyvers > POLICYDB_VERSION_CAPBITMAP? it 
> could be inlined too.

It can't be inlined as it is a security server interface.

I suppose you could check the version first to see if it is < 22 and
always return 0 in that case without having to take the rdlock.

You could also extract the first word of the bitmap to a simple unsigned
long in the policydb at load time and do a direct bit test on it if
req_cap < (sizeof(unsigned long) * 8), without taking policy rdlock.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22
  2007-09-26 22:24   ` Joshua Brindle
  2007-09-27 11:36     ` Stephen Smalley
@ 2007-09-27 11:46     ` Paul Moore
  1 sibling, 0 replies; 8+ messages in thread
From: Paul Moore @ 2007-09-27 11:46 UTC (permalink / raw)
  To: Joshua Brindle; +Cc: selinux

On Wednesday 26 September 2007 6:24:23 pm Joshua Brindle wrote:
> Paul Moore wrote:
> > --- a/security/selinux/include/security.h
> > +++ b/security/selinux/include/security.h
> > @@ -25,13 +25,14 @@
> >  #define POLICYDB_VERSION_MLS		19
> >  #define POLICYDB_VERSION_AVTAB		20
> >  #define POLICYDB_VERSION_RANGETRANS	21
> > +#define POLICYDB_VERSION_CAPBITMAP	22
>
> I didn't like this name (I almost used it myself) because it sounds like
> we are doing something with linux capabilities, I ended up using
> POLICYDB_VERSION_PCAPS (for policy capabilities)

Makes sense, I'll change it to your suggestion.

> >  /* Range of policy versions we understand*/
> >  #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
> >  #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
> >  #define
> > POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
> > #else
> > -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_RANGETRANS
> > +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_CAPBITMAP
> >  #endif
> >
> >  struct netlbl_lsm_secattr;
> > @@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
> >  extern int selinux_enabled;
> >  extern int selinux_mls_enabled;
> >
> > +/* Policy capabilities */
> > +enum {
> > +	POLICYDB_CAPABILITY_NETPEER,
> > +	__POLICYDB_CAPABILITY_MAX
> > +};
> > +#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
> > +
>
> Hrm, I just used an ebitmap and didn't set a max at all.

The "max" value is really just a sentinel value to make life easier in the 
code, it's not a limit of any sort.  Although it does have a side benefit of 
preventing kernels from having to worry about bitmap fields they don't 
understand which could provide some benefits for backwards compatibility.

> >  int security_get_classes(char ***classes, int *nclasses);
> >  int security_get_permissions(char *class, char ***perms, int *nperms);
> > +int security_get_policycaps(int *len, int **values);
>
> We can fill in an array but I thought it'd be better just to use an
> ebitmap and ebitmap_get_bit()

I use the ebitmap data type as much as possible, but keep in mind that the 
ebitmap type exists only inside the security server, i.e. 
security/selinux/ss/*, so any use/queries outside of the security server 
needs to deal with a more general type.  Look at the class and permission 
functions declared just about the policycaps function, they have the 
same/similar problem.

> > -#define SEL_INITCON_INO_OFFSET 	0x01000000
> > -#define SEL_BOOL_INO_OFFSET	0x02000000
> > -#define SEL_CLASS_INO_OFFSET	0x04000000
> > -#define SEL_INO_MASK		0x00ffffff
> > +#define SEL_INITCON_INO_OFFSET		0x01000000
> > +#define SEL_BOOL_INO_OFFSET		0x02000000
> > +#define SEL_CLASS_INO_OFFSET		0x04000000
> > +#define SEL_POLICYCAP_INO_OFFSET	0x08000000
> > +#define SEL_INO_MASK			0x00ffffff
>
> whitespace changes?

Yep, the columns didn't all line up when I added SEL_POLICYCAP_INO_OFFSET so I 
adjusted the rest.  I know you're not *supposed* to do such things, but it 
was bugging me ...

> > +static ssize_t sel_read_policycap(struct file *file, char __user *buf,
> > +				  size_t count, loff_t *ppos)
> > +{
> > +	int value;
> > +	char tmpbuf[TMPBUFLEN];
> > +	ssize_t length;
> > +	unsigned long inode = file->f_path.dentry->d_inode->i_ino;
> > +
> > +	value = security_policycap_supported(inode &
> > +					     (SEL_POLICYCAP_INO_OFFSET - 1));
> > +	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", value);
> > +
> > +	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
> > +}
> > +
> > +static const struct file_operations sel_policycap_ops = {
> > +	.read		= sel_read_policycap,
> > +};
> > +
>
> Yea, I wondered how we were going to do this, we could have symbolic
> names for each of them or we could just output offsets and let userspace
> decipher it. I guess having symbolic names in a directory is better
> (eg., /selinux/policy_caps/peersid_reconciliation)

Based on the discussion between Eric and Eamon I figured symbolic names would 
be better, even though it requires a little bit more work in the kernel.

> > +static int sel_make_policycap(void)
> > +{
> > +	unsigned int iter;
> > +	struct dentry *dentry = NULL;
> > +	struct inode *inode = NULL;
> > +
> > +	sel_remove_entries(policycap_dir);
> > +
> > +	for (iter = 0; iter <= POLICYDB_CAPABILITY_MAX; iter++) {
> > +		if (iter <= ARRAY_SIZE(policycap_names))
> > +			dentry = d_alloc_name(policycap_dir,
> > +					      policycap_names[iter]);
> > +		else
> > +			dentry = d_alloc_name(policycap_dir, "unknown");
> > +
> > +		if (dentry == NULL)
> > +			return -ENOMEM;
> > +
> > +		inode = sel_make_inode(policycap_dir->d_sb, S_IFREG | S_IRUGO);
> > +		if (inode == NULL)
> > +			return -ENOMEM;
> > +
> > +		inode->i_fop = &sel_policycap_ops;
> > +		inode->i_ino = iter | SEL_POLICYCAP_INO_OFFSET;
> > +		d_add(dentry, inode);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
>
> err, yea, agreed :)

Hopefully the cut 'n paste job wasn't too obvious :)

> > +int security_get_policycaps(int *len, int **values)
> > +{
> > +	int rc = -ENOMEM;
> > +	unsigned int iter;
> > +
> > +	POLICY_RDLOCK;
> > +
> > +	*values = kcalloc(POLICYDB_CAPABILITY_MAX, sizeof(int), GFP_ATOMIC);
> > +	if (*values == NULL)
> > +		goto out;
> > +	for (iter = 0; iter < POLICYDB_CAPABILITY_MAX; iter++)
> > +		(*values)[iter] = ebitmap_get_bit(&policydb.policycaps, iter);
> > +
> > +	*len = POLICYDB_CAPABILITY_MAX;
> > +
> > +out:
> > +	POLICY_RDUNLOCK;
> > +	return rc;
> > +}
> > +
>
> Why do we want to write out to an array instead of just passing the
> ebitmap around?

See my earlier comments about the scope of the ebitmap data type.

> > +int security_policycap_supported(unsigned int req_cap)
> > +{
> > +	int rc;
> > +
> > +	POLICY_RDLOCK;
> > +	rc = ebitmap_get_bit(&policydb.policycaps, req_cap);
> > +	POLICY_RDUNLOCK;
> > +
> > +	return rc;
> > +}
> > +
>
> Shouldn't this just check if policyvers > POLICYDB_VERSION_CAPBITMAP? it
> could be inlined too.

I'm not sure the check is needed, if the policy does not support the 
capability bitmap then the function will always return zero regardless of 
what capability is requested because the ebitmap will be empty.  A value of 
zero means the capability is not supported.

We shouldn't inline this function because it's intent is to provide an 
interface into the security server to query capabilities.  For example, code 
in the security/selinux/hooks.c file may need to check a specific capability 
but can't access the ebitmap directly so it would need to use this function.

-- 
paul moore
linux security @ hp

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22
  2007-09-27 11:36     ` Stephen Smalley
@ 2007-09-27 18:10       ` Joshua Brindle
  2007-09-27 19:07       ` Paul Moore
  1 sibling, 0 replies; 8+ messages in thread
From: Joshua Brindle @ 2007-09-27 18:10 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: Paul Moore, selinux

Stephen Smalley wrote:
> On Wed, 2007-09-26 at 18:24 -0400, Joshua Brindle wrote:
>   
>> Paul Moore wrote:
>>     
>>> Add a new policy capabilities bitmap to SELinux policy version 22.  This bitmap
>>> will enable the security server to query the policy to determine which features
>>> it supports.
>>> ---
>>>
>>>  security/selinux/include/security.h |   15 +++++-
>>>  security/selinux/selinuxfs.c        |   90 +++++++++++++++++++++++++++++++++--
>>>  security/selinux/ss/policydb.c      |   18 +++++++
>>>  security/selinux/ss/policydb.h      |    2 +
>>>  security/selinux/ss/services.c      |   39 +++++++++++++++
>>>  5 files changed, 158 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
>>> index 83bdd4d..d7e6ed2 100644
>>> --- a/security/selinux/include/security.h
>>> +++ b/security/selinux/include/security.h
>>> @@ -25,13 +25,14 @@
>>>  #define POLICYDB_VERSION_MLS		19
>>>  #define POLICYDB_VERSION_AVTAB		20
>>>  #define POLICYDB_VERSION_RANGETRANS	21
>>> +#define POLICYDB_VERSION_CAPBITMAP	22
>>>  
>>>   
>>>       
>> I didn't like this name (I almost used it myself) because it sounds like 
>> we are doing something with linux capabilities, I ended up using 
>> POLICYDB_VERSION_PCAPS (for policy capabilities)
>>     
>
> Doesn't help much; PCAP sounds like process capabilities, and
> CAP_SETPCAP ;)  I don't think the name matters either way.
>
>   

Fair enough, I'll just use what Paul does next time he releases a 
patchset (no pressure on you to pick the perfect name Paul ;) )

>>>  /* Range of policy versions we understand*/
>>>  #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
>>>  #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
>>>  #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
>>>  #else
>>> -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_RANGETRANS
>>> +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_CAPBITMAP
>>>  #endif
>>>  
>>>  struct netlbl_lsm_secattr;
>>> @@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
>>>  extern int selinux_enabled;
>>>  extern int selinux_mls_enabled;
>>>  
>>> +/* Policy capabilities */
>>> +enum {
>>> +	POLICYDB_CAPABILITY_NETPEER,
>>> +	__POLICYDB_CAPABILITY_MAX
>>> +};
>>> +#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
>>> +
>>>   
>>>       
>> Hrm, I just used an ebitmap and didn't set a max at all.
>>     
>
> ebitmaps are a security server internal construct; you have to export
> them in a different form to users of the security server, like
> selinuxfs, the hook functions, etc.  Or you'd have to move them out a
> layer.
>
>
>   

Oops, yea, I forgot that ebitmaps were private to the security server, 
disregard all comments pertaining to them :)


>> Shouldn't this just check if policyvers > POLICYDB_VERSION_CAPBITMAP? it 
>> could be inlined too.
>>     
>
> It can't be inlined as it is a security server interface.
>
> I suppose you could check the version first to see if it is < 22 and
> always return 0 in that case without having to take the rdlock.
>
> You could also extract the first word of the bitmap to a simple unsigned
> long in the policydb at load time and do a direct bit test on it if
> req_cap < (sizeof(unsigned long) * 8), without taking policy rdlock.
>
>   



--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22
  2007-09-27 11:36     ` Stephen Smalley
  2007-09-27 18:10       ` Joshua Brindle
@ 2007-09-27 19:07       ` Paul Moore
  1 sibling, 0 replies; 8+ messages in thread
From: Paul Moore @ 2007-09-27 19:07 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: Joshua Brindle, selinux

On Thursday 27 September 2007 7:36:50 am Stephen Smalley wrote:
> On Wed, 2007-09-26 at 18:24 -0400, Joshua Brindle wrote:
> > Paul Moore wrote:
> > > Add a new policy capabilities bitmap to SELinux policy version 22. 
> > > This bitmap will enable the security server to query the policy to
> > > determine which features it supports.
> > > ---
> > >
> > >  security/selinux/include/security.h |   15 +++++-
> > >  security/selinux/selinuxfs.c        |   90
> > > +++++++++++++++++++++++++++++++++-- security/selinux/ss/policydb.c     
> > > |   18 +++++++
> > >  security/selinux/ss/policydb.h      |    2 +
> > >  security/selinux/ss/services.c      |   39 +++++++++++++++
> > >  5 files changed, 158 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/security/selinux/include/security.h
> > > b/security/selinux/include/security.h index 83bdd4d..d7e6ed2 100644
> > > --- a/security/selinux/include/security.h
> > > +++ b/security/selinux/include/security.h
> > > @@ -25,13 +25,14 @@
> > >  #define POLICYDB_VERSION_MLS		19
> > >  #define POLICYDB_VERSION_AVTAB		20
> > >  #define POLICYDB_VERSION_RANGETRANS	21
> > > +#define POLICYDB_VERSION_CAPBITMAP	22
> >
> > I didn't like this name (I almost used it myself) because it sounds like
> > we are doing something with linux capabilities, I ended up using
> > POLICYDB_VERSION_PCAPS (for policy capabilities)
>
> Doesn't help much; PCAP sounds like process capabilities, and
> CAP_SETPCAP ;)  I don't think the name matters either way.

What's in a name after all, right?

 :)

The voices in my head said they liked POLICYDB_VERSION_POLCAP the best, so I'm 
gonna go with that.  I've found it's best not to ignore the voices ...

> > > +int security_policycap_supported(unsigned int req_cap)
> > > +{
> > > +	int rc;
> > > +
> > > +	POLICY_RDLOCK;
> > > +	rc = ebitmap_get_bit(&policydb.policycaps, req_cap);
> > > +	POLICY_RDUNLOCK;
> > > +
> > > +	return rc;
> > > +}
> > > +
> >
> > Shouldn't this just check if policyvers > POLICYDB_VERSION_CAPBITMAP? it
> > could be inlined too.
>
> It can't be inlined as it is a security server interface.
>
> I suppose you could check the version first to see if it is < 22 and
> always return 0 in that case without having to take the rdlock.
>
> You could also extract the first word of the bitmap to a simple unsigned
> long in the policydb at load time and do a direct bit test on it if
> req_cap < (sizeof(unsigned long) * 8), without taking policy rdlock.

My thinking was that for capability checks that are likely to be in 
performance critical sections we could create a separate flag like I did for 
the the netpeer stuff in the patch.  This removes any issues with a function 
call as well as the policy lock.

I suppose that this approach may not scale very well if the bitmap grows to 
include a number of different capabilities, but I don't foresee that 
happening for a while so I'm happy to leave the issue for later.

-- 
paul moore
linux security @ hp

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-09-27 19:12 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-26 21:32 [RFC PATCH v2 0/2] Updated patches based on comments Paul Moore
2007-09-26 21:32 ` [RFC PATCH v2 1/2] [SELINUX] Add a capabilities bitmap to SELinux policy version 22 Paul Moore
2007-09-26 22:24   ` Joshua Brindle
2007-09-27 11:36     ` Stephen Smalley
2007-09-27 18:10       ` Joshua Brindle
2007-09-27 19:07       ` Paul Moore
2007-09-27 11:46     ` Paul Moore
2007-09-26 21:32 ` [RFC PATCH v2 2/2] [SELINUX] Better integration between peer labeling subsystems Paul Moore

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.