All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG
@ 2009-02-09 21:37 Eric Paris
  2009-02-09 21:37 ` [PATCH 2/3] SELinux: call capabilities code directory Eric Paris
                   ` (4 more replies)
  0 siblings, 5 replies; 14+ messages in thread
From: Eric Paris @ 2009-02-09 21:37 UTC (permalink / raw)
  To: selinux; +Cc: sds, jmorris

If CONFIG_BUG is not set places in the code where BUG is called will not
end execution.  Look for places where this might result is system problems
and keep the system running.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 kernel/capability.c            |    1 +
 security/selinux/avc.c         |   13 +++++++++++--
 security/selinux/hooks.c       |    9 ++++++++-
 security/selinux/netnode.c     |    3 +++
 security/selinux/ss/ebitmap.h  |   15 ++++++++++++---
 security/selinux/ss/services.c |   38 +++++++++++++++++++++++++++++++-------
 security/selinux/xfrm.c        |   15 ++++++++++++---
 7 files changed, 78 insertions(+), 16 deletions(-)

diff --git a/kernel/capability.c b/kernel/capability.c
index 4e17041..e8bec6a 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -304,6 +304,7 @@ int capable(int cap)
 	if (unlikely(!cap_valid(cap))) {
 		printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap);
 		BUG();
+		return 0;
 	}
 
 	if (security_capable(cap) == 0) {
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index eb41f43..c22db1e 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -202,6 +202,7 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
 {
 	int rc;
 	char *scontext;
+	const char *class_string;
 	u32 scontext_len;
 
 	rc = security_sid_to_context(ssid, &scontext, &scontext_len);
@@ -220,8 +221,16 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
 		kfree(scontext);
 	}
 
-	BUG_ON(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass]);
-	audit_log_format(ab, " tclass=%s", class_to_string[tclass]);
+	if (unlikely(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass])) {
+		class_string = "unknown";
+		if (tclass >= ARRAY_SIZE(class_to_string))
+			BUG();
+		else
+			BUG();
+	} else {
+		class_string = class_to_string[tclass];
+	}
+	audit_log_format(ab, " tclass=%s", class_string);
 }
 
 /**
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ae5bb64..6e6847d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -995,7 +995,11 @@ static int superblock_doinit(struct super_block *sb, void *data)
 	if (!data)
 		goto out;
 
-	BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA);
+	if (unlikely(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)) {
+		BUG();
+		rc = -EINVAL;
+		goto out_err;
+	}
 
 	rc = selinux_parse_opts_str(options, &opts);
 	if (rc)
@@ -1042,6 +1046,7 @@ static void selinux_write_opts(struct seq_file *m,
 			continue;
 		default:
 			BUG();
+			continue;
 		};
 		/* we need a comma before each option */
 		seq_putc(m, ',');
@@ -1500,6 +1505,8 @@ static int task_has_capability(struct task_struct *tsk,
 		printk(KERN_ERR
 		       "SELinux:  out of range capability %d\n", cap);
 		BUG();
+		/* should I audit somehow? */
+		return -EPERM;
 	}
 
 	rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 7100072..e002d5a 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -140,6 +140,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
 		break;
 	default:
 		BUG();
+		return NULL;
 	}
 
 	list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
@@ -180,6 +181,7 @@ static void sel_netnode_insert(struct sel_netnode *node)
 		break;
 	default:
 		BUG();
+		return;
 	}
 
 	INIT_RCU_HEAD(&node->rcu);
@@ -240,6 +242,7 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
 		break;
 	default:
 		BUG();
+		ret = -EINVAL;
 	}
 	if (ret != 0)
 		goto out;
diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
index f283b43..425f8b8 100644
--- a/security/selinux/ss/ebitmap.h
+++ b/security/selinux/ss/ebitmap.h
@@ -85,7 +85,10 @@ static inline int ebitmap_node_get_bit(struct ebitmap_node *n,
 	unsigned int index = EBITMAP_NODE_INDEX(n, bit);
 	unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
 
-	BUG_ON(index >= EBITMAP_UNIT_NUMS);
+	if (unlikely((index >= EBITMAP_UNIT_NUMS))) {
+		BUG();
+		return 0;
+	}
 	if ((n->maps[index] & (EBITMAP_BIT << ofs)))
 		return 1;
 	return 0;
@@ -97,7 +100,10 @@ static inline void ebitmap_node_set_bit(struct ebitmap_node *n,
 	unsigned int index = EBITMAP_NODE_INDEX(n, bit);
 	unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
 
-	BUG_ON(index >= EBITMAP_UNIT_NUMS);
+	if (unlikely((index >= EBITMAP_UNIT_NUMS))) {
+		BUG();
+		return;
+	}
 	n->maps[index] |= (EBITMAP_BIT << ofs);
 }
 
@@ -107,7 +113,10 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
 	unsigned int index = EBITMAP_NODE_INDEX(n, bit);
 	unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
 
-	BUG_ON(index >= EBITMAP_UNIT_NUMS);
+	if (unlikely((index >= EBITMAP_UNIT_NUMS))) {
+		BUG();
+		return;
+	}
 	n->maps[index] &= ~(EBITMAP_BIT << ofs);
 }
 
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index c65e4fe..cfb0769 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -120,16 +120,25 @@ static int constraint_expr_eval(struct context *scontext,
 	for (e = cexpr; e; e = e->next) {
 		switch (e->expr_type) {
 		case CEXPR_NOT:
-			BUG_ON(sp < 0);
+			if (unlikely(sp < 0)) {
+				BUG();
+				return 0;
+			}
 			s[sp] = !s[sp];
 			break;
 		case CEXPR_AND:
-			BUG_ON(sp < 1);
+			if (unlikely(sp < 1)) {
+				BUG();
+				return 0;
+			}
 			sp--;
 			s[sp] &= s[sp+1];
 			break;
 		case CEXPR_OR:
-			BUG_ON(sp < 1);
+			if (unlikely(sp < 1)) {
+				BUG();
+				return 0;
+			}
 			sp--;
 			s[sp] |= s[sp+1];
 			break;
@@ -541,7 +550,11 @@ int security_permissive_sid(u32 sid)
 	read_lock(&policy_rwlock);
 
 	context = sidtab_search(&sidtab, sid);
-	BUG_ON(!context);
+	if (unlikely(!context)) {
+		BUG();
+		rc = 0;
+		goto out;
+	}
 
 	type = context->type;
 	/*
@@ -550,6 +563,7 @@ int security_permissive_sid(u32 sid)
 	 */
 	rc = ebitmap_get_bit(&policydb.permissive_map, type);
 
+out:
 	read_unlock(&policy_rwlock);
 	return rc;
 }
@@ -697,7 +711,11 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
 	index = new_context->type;
 	while (true) {
 		type = policydb.type_val_to_struct[index - 1];
-		BUG_ON(!type);
+		if (unlikely(!type)) {
+			BUG();
+			rc = -EPERM;
+			goto out;
+		}
 
 		/* not bounded anymore */
 		if (!type->bounds) {
@@ -1381,7 +1399,10 @@ static int validate_classes(struct policydb *p)
 			continue;
 		pol_class = p->p_class_val_to_name[class_val-1];
 		cladatum = hashtab_search(p->p_classes.table, pol_class);
-		BUG_ON(!cladatum);
+		if (unlikely(!cladatum)) {
+			BUG();
+			return -EINVAL;
+		}
 		perms = &cladatum->permissions;
 		nprim = 1 << (perms->nprim - 1);
 		if (perm_val > nprim) {
@@ -1416,7 +1437,10 @@ static int validate_classes(struct policydb *p)
 			continue;
 		pol_class = p->p_class_val_to_name[class_val-1];
 		cladatum = hashtab_search(p->p_classes.table, pol_class);
-		BUG_ON(!cladatum);
+		if (unlikely(!cladatum)) {
+			BUG();
+			return -EINVAL;
+		}
 		if (!cladatum->comdatum) {
 			printk(KERN_ERR
 			       "SELinux:  class %s should have an inherits clause but does not\n",
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index c0eb720..22413ec 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -202,7 +202,10 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
 	char *ctx_str = NULL;
 	u32 str_len;
 
-	BUG_ON(uctx && sid);
+	if (unlikely(ctx && sid)) {
+		BUG();
+		return -EINVAL;
+	}
 
 	if (!uctx)
 		goto not_from_user;
@@ -288,7 +291,10 @@ int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
 {
 	int err;
 
-	BUG_ON(!uctx);
+	if (unlikely(!uctx)) {
+		BUG();
+		return -EINVAL;
+	}
 
 	err = selinux_xfrm_sec_ctx_alloc(ctxp, uctx, 0);
 	if (err == 0)
@@ -356,7 +362,10 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uct
 {
 	int err;
 
-	BUG_ON(!x);
+	if (unlikely(!x)) {
+		BUG();
+		return -EINVAL;
+	}
 
 	err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, secid);
 	if (err == 0)


--
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] 14+ messages in thread

* [PATCH 2/3] SELinux: call capabilities code directory
  2009-02-09 21:37 [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Eric Paris
@ 2009-02-09 21:37 ` Eric Paris
  2009-02-10 14:06   ` Stephen Smalley
  2009-02-09 21:37 ` [PATCH 3/3] SELinux: better printk when file with invalid label found Eric Paris
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Eric Paris @ 2009-02-09 21:37 UTC (permalink / raw)
  To: selinux; +Cc: sds, jmorris

For cleanliness and efficiency remove all calls to secondary-> and instead
call capabilities code directly.  capabilities are the only module that
selinux stacks with and so the code should not indicate that other stacking
might be possible.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 security/selinux/hooks.c |   28 ++++++++++++++--------------
 1 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6e6847d..e2bdb28 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1864,7 +1864,7 @@ static int selinux_ptrace_may_access(struct task_struct *child,
 {
 	int rc;
 
-	rc = secondary_ops->ptrace_may_access(child, mode);
+	rc = cap_ptrace_may_access(child, mode);
 	if (rc)
 		return rc;
 
@@ -1881,7 +1881,7 @@ static int selinux_ptrace_traceme(struct task_struct *parent)
 {
 	int rc;
 
-	rc = secondary_ops->ptrace_traceme(parent);
+	rc = cap_ptrace_traceme(parent);
 	if (rc)
 		return rc;
 
@@ -1897,7 +1897,7 @@ static int selinux_capget(struct task_struct *target, kernel_cap_t *effective,
 	if (error)
 		return error;
 
-	return secondary_ops->capget(target, effective, inheritable, permitted);
+	return cap_capget(target, effective, inheritable, permitted);
 }
 
 static int selinux_capset(struct cred *new, const struct cred *old,
@@ -1907,7 +1907,7 @@ static int selinux_capset(struct cred *new, const struct cred *old,
 {
 	int error;
 
-	error = secondary_ops->capset(new, old,
+	error = cap_capset(new, old,
 				      effective, inheritable, permitted);
 	if (error)
 		return error;
@@ -1930,7 +1930,7 @@ static int selinux_capable(struct task_struct *tsk, const struct cred *cred,
 {
 	int rc;
 
-	rc = secondary_ops->capable(tsk, cred, cap, audit);
+	rc = cap_capable(tsk, cred, cap, audit);
 	if (rc)
 		return rc;
 
@@ -2056,7 +2056,7 @@ static int selinux_syslog(int type)
 {
 	int rc;
 
-	rc = secondary_ops->syslog(type);
+	rc = cap_syslog(type);
 	if (rc)
 		return rc;
 
@@ -2087,7 +2087,7 @@ static int selinux_syslog(int type)
  * mapping. 0 means there is enough memory for the allocation to
  * succeed and -ENOMEM implies there is not.
  *
- * Note that secondary_ops->capable and task_has_perm_noaudit return 0
+ * Note that cap_capable and task_has_perm_noaudit return 0
  * if the capability is granted, but __vm_enough_memory requires 1 if
  * the capability is granted.
  *
@@ -2117,7 +2117,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
 	struct inode *inode = bprm->file->f_path.dentry->d_inode;
 	int rc;
 
-	rc = secondary_ops->bprm_set_creds(bprm);
+	rc = cap_bprm_set_creds(bprm);
 	if (rc)
 		return rc;
 
@@ -2234,7 +2234,7 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
 					PROCESS__NOATSECURE, NULL);
 	}
 
-	return (atsecure || secondary_ops->bprm_secureexec(bprm));
+	return (atsecure || cap_bprm_secureexec(bprm));
 }
 
 extern struct vfsmount *selinuxfs_mount;
@@ -3335,7 +3335,7 @@ static int selinux_task_setnice(struct task_struct *p, int nice)
 {
 	int rc;
 
-	rc = secondary_ops->task_setnice(p, nice);
+	rc = cap_task_setnice(p, nice);
 	if (rc)
 		return rc;
 
@@ -3346,7 +3346,7 @@ static int selinux_task_setioprio(struct task_struct *p, int ioprio)
 {
 	int rc;
 
-	rc = secondary_ops->task_setioprio(p, ioprio);
+	rc = cap_task_setioprio(p, ioprio);
 	if (rc)
 		return rc;
 
@@ -3376,7 +3376,7 @@ static int selinux_task_setscheduler(struct task_struct *p, int policy, struct s
 {
 	int rc;
 
-	rc = secondary_ops->task_setscheduler(p, policy, lp);
+	rc = cap_task_setscheduler(p, policy, lp);
 	if (rc)
 		return rc;
 
@@ -4634,7 +4634,7 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
 {
 	int err;
 
-	err = secondary_ops->netlink_send(sk, skb);
+	err = cap_netlink_send(sk, skb);
 	if (err)
 		return err;
 
@@ -4649,7 +4649,7 @@ static int selinux_netlink_recv(struct sk_buff *skb, int capability)
 	int err;
 	struct avc_audit_data ad;
 
-	err = secondary_ops->netlink_recv(skb, capability);
+	err = cap_netlink_recv(skb, capability);
 	if (err)
 		return err;
 


--
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] 14+ messages in thread

* [PATCH 3/3] SELinux: better printk when file with invalid label found
  2009-02-09 21:37 [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Eric Paris
  2009-02-09 21:37 ` [PATCH 2/3] SELinux: call capabilities code directory Eric Paris
@ 2009-02-09 21:37 ` Eric Paris
  2009-02-10 14:14   ` Stephen Smalley
  2009-02-10 14:00 ` [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Stephen Smalley
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 14+ messages in thread
From: Eric Paris @ 2009-02-09 21:37 UTC (permalink / raw)
  To: selinux; +Cc: sds, jmorris

Currently when an inode is read into the kernel with an invalid label
string (can often happen with removable media) we output a string like:

SELinux: inode_doinit_with_dentry:  context_to_sid([SOME INVALID LABEL])
returned -22 dor dev=[blah] ino=[blah]

Which is all but incomprehensible to all but a couple of us.  Instead, on
EINVAL only, I plan to output a much more user friendly string and I plan to
ratelimit the printk since many of these could be generated very rapidly.

Signed-off-by: Eric Paris <eparis@redhat.com>
---

 security/selinux/hooks.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index e2bdb28..7fe870d 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1335,10 +1335,19 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
 							     sbsec->def_sid,
 							     GFP_NOFS);
 			if (rc) {
-				printk(KERN_WARNING "SELinux: %s:  context_to_sid(%s) "
-				       "returned %d for dev=%s ino=%ld\n",
-				       __func__, context, -rc,
-				       inode->i_sb->s_id, inode->i_ino);
+				char *dev = inode->i_sb->s_id;
+				unsigned long ino = inode->i_ino;
+
+				if (rc == -EINVAL) {
+					if (printk_ratelimit())
+						printk(KERN_NOTICE "SELinux: inode=%lu on dev=%s was found to have an invalid "
+							"context=%s.  This indicates you may need to relabel the inode or the "
+							"filesystem in question.\n", ino, dev, context);
+				} else {
+					printk(KERN_WARNING "SELinux: %s:  context_to_sid(%s) "
+					       "returned %d for dev=%s ino=%ld\n",
+					       __func__, context, -rc, dev, ino);
+				}
 				kfree(context);
 				/* Leave with the unlabeled SID */
 				rc = 0;


--
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] 14+ messages in thread

* Re: [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG
  2009-02-09 21:37 [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Eric Paris
  2009-02-09 21:37 ` [PATCH 2/3] SELinux: call capabilities code directory Eric Paris
  2009-02-09 21:37 ` [PATCH 3/3] SELinux: better printk when file with invalid label found Eric Paris
@ 2009-02-10 14:00 ` Stephen Smalley
  2009-02-10 14:39   ` Eric Paris
  2009-02-10 16:37 ` Paul Moore
  2009-02-12 22:56 ` James Morris
  4 siblings, 1 reply; 14+ messages in thread
From: Stephen Smalley @ 2009-02-10 14:00 UTC (permalink / raw)
  To: Eric Paris; +Cc: selinux, jmorris

On Mon, 2009-02-09 at 16:37 -0500, Eric Paris wrote:
> If CONFIG_BUG is not set places in the code where BUG is called will not
> end execution.  Look for places where this might result is system problems
> and keep the system running.
> 
> Signed-off-by: Eric Paris <eparis@redhat.com>
> ---
> 
>  kernel/capability.c            |    1 +
>  security/selinux/avc.c         |   13 +++++++++++--
>  security/selinux/hooks.c       |    9 ++++++++-
>  security/selinux/netnode.c     |    3 +++
>  security/selinux/ss/ebitmap.h  |   15 ++++++++++++---
>  security/selinux/ss/services.c |   38 +++++++++++++++++++++++++++++++-------
>  security/selinux/xfrm.c        |   15 ++++++++++++---
>  7 files changed, 78 insertions(+), 16 deletions(-)
> 
<snip>
> diff --git a/security/selinux/avc.c b/security/selinux/avc.c
> index eb41f43..c22db1e 100644
> --- a/security/selinux/avc.c
> +++ b/security/selinux/avc.c
> @@ -202,6 +202,7 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
>  {
>  	int rc;
>  	char *scontext;
> +	const char *class_string;
>  	u32 scontext_len;
>  
>  	rc = security_sid_to_context(ssid, &scontext, &scontext_len);
> @@ -220,8 +221,16 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
>  		kfree(scontext);
>  	}
>  
> -	BUG_ON(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass]);
> -	audit_log_format(ab, " tclass=%s", class_to_string[tclass]);
> +	if (unlikely(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass])) {
> +		class_string = "unknown";
> +		if (tclass >= ARRAY_SIZE(class_to_string))
> +			BUG();
> +		else
> +			BUG();

Reduce that if statement to just BUG().
A possible alternative to logging the "unknown" string would be to log
the value of tclass; that would provide more information for debugging.

> +	} else {
> +		class_string = class_to_string[tclass];
> +	}
> +	audit_log_format(ab, " tclass=%s", class_string);
>  }
>  
>  /**
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index ae5bb64..6e6847d 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -995,7 +995,11 @@ static int superblock_doinit(struct super_block *sb, void *data)
>  	if (!data)
>  		goto out;
>  
> -	BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA);
> +	if (unlikely(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)) {
> +		BUG();
> +		rc = -EINVAL;
> +		goto out_err;

Why out_err vs. out?  No allocation yet, right?  Or alternatively, if
all calls to security_init_mnt_opts() should be balanced with calls to
security_free_mnt_opts(), why don't we goto out_err in the prior error
path?

> @@ -1500,6 +1505,8 @@ static int task_has_capability(struct task_struct *tsk,
>  		printk(KERN_ERR
>  		       "SELinux:  out of range capability %d\n", cap);
>  		BUG();
> +		/* should I audit somehow? */
> +		return -EPERM;

I think the printk KERN_ERR suffices, or turn it into a audit_log
AUDIT_SELINUX_ERR call.

> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index c65e4fe..cfb0769 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -120,16 +120,25 @@ static int constraint_expr_eval(struct context *scontext,
>  	for (e = cexpr; e; e = e->next) {
>  		switch (e->expr_type) {
>  		case CEXPR_NOT:
> -			BUG_ON(sp < 0);
> +			if (unlikely(sp < 0)) {
> +				BUG();
> +				return 0;
> +			}

General question:  Should we in fact be panic'ing in these cases where
we cannot return a value that will in fact abort the computation and
guarantee that the operation will not proceed?  Same applies to the
ebitmap code.  Just returning 0 (false) doesn't necessarily mean that we
won't grant a permission, as the result may get negated.

-- 
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] 14+ messages in thread

* Re: [PATCH 2/3] SELinux: call capabilities code directory
  2009-02-09 21:37 ` [PATCH 2/3] SELinux: call capabilities code directory Eric Paris
@ 2009-02-10 14:06   ` Stephen Smalley
  2009-02-10 14:30     ` Eric Paris
  0 siblings, 1 reply; 14+ messages in thread
From: Stephen Smalley @ 2009-02-10 14:06 UTC (permalink / raw)
  To: Eric Paris; +Cc: selinux, jmorris

On Mon, 2009-02-09 at 16:37 -0500, Eric Paris wrote:
> For cleanliness and efficiency remove all calls to secondary-> and instead
> call capabilities code directly.  capabilities are the only module that
> selinux stacks with and so the code should not indicate that other stacking
> might be possible.
> 
> Signed-off-by: Eric Paris <eparis@redhat.com>
> ---
> 
>  security/selinux/hooks.c |   28 ++++++++++++++--------------
>  1 files changed, 14 insertions(+), 14 deletions(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index 6e6847d..e2bdb28 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -2087,7 +2087,7 @@ static int selinux_syslog(int type)
>   * mapping. 0 means there is enough memory for the allocation to
>   * succeed and -ENOMEM implies there is not.
>   *
> - * Note that secondary_ops->capable and task_has_perm_noaudit return 0
> + * Note that cap_capable and task_has_perm_noaudit return 0

This part of the comment is a bit out of date - at this point we are
just calling selinux_capable(...SECURITY_CAP_NOAUDIT) rather than
separately calling cap_capable() and task_has_perm_noaudit().

>   * if the capability is granted, but __vm_enough_memory requires 1 if
>   * the capability is granted.
>   *

-- 
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] 14+ messages in thread

* Re: [PATCH 3/3] SELinux: better printk when file with invalid label found
  2009-02-09 21:37 ` [PATCH 3/3] SELinux: better printk when file with invalid label found Eric Paris
@ 2009-02-10 14:14   ` Stephen Smalley
  2009-02-10 14:30     ` Eric Paris
  0 siblings, 1 reply; 14+ messages in thread
From: Stephen Smalley @ 2009-02-10 14:14 UTC (permalink / raw)
  To: Eric Paris; +Cc: selinux, jmorris

On Mon, 2009-02-09 at 16:37 -0500, Eric Paris wrote:
> Currently when an inode is read into the kernel with an invalid label
> string (can often happen with removable media) we output a string like:
> 
> SELinux: inode_doinit_with_dentry:  context_to_sid([SOME INVALID LABEL])
> returned -22 dor dev=[blah] ino=[blah]
> 
> Which is all but incomprehensible to all but a couple of us.  Instead, on
> EINVAL only, I plan to output a much more user friendly string and I plan to
> ratelimit the printk since many of these could be generated very rapidly.
> 
> Signed-off-by: Eric Paris <eparis@redhat.com>

You could likely further drop the function name in all cases, and maybe
even the error code (is there no strerror() equivalent in the kernel?).


> ---
> 
>  security/selinux/hooks.c |   17 +++++++++++++----
>  1 files changed, 13 insertions(+), 4 deletions(-)
> 
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index e2bdb28..7fe870d 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -1335,10 +1335,19 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent
>  							     sbsec->def_sid,
>  							     GFP_NOFS);
>  			if (rc) {
> -				printk(KERN_WARNING "SELinux: %s:  context_to_sid(%s) "
> -				       "returned %d for dev=%s ino=%ld\n",
> -				       __func__, context, -rc,
> -				       inode->i_sb->s_id, inode->i_ino);
> +				char *dev = inode->i_sb->s_id;
> +				unsigned long ino = inode->i_ino;
> +
> +				if (rc == -EINVAL) {
> +					if (printk_ratelimit())
> +						printk(KERN_NOTICE "SELinux: inode=%lu on dev=%s was found to have an invalid "
> +							"context=%s.  This indicates you may need to relabel the inode or the "
> +							"filesystem in question.\n", ino, dev, context);
> +				} else {
> +					printk(KERN_WARNING "SELinux: %s:  context_to_sid(%s) "
> +					       "returned %d for dev=%s ino=%ld\n",
> +					       __func__, context, -rc, dev, ino);
> +				}
>  				kfree(context);
>  				/* Leave with the unlabeled SID */
>  				rc = 0;
-- 
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] 14+ messages in thread

* Re: [PATCH 3/3] SELinux: better printk when file with invalid label found
  2009-02-10 14:14   ` Stephen Smalley
@ 2009-02-10 14:30     ` Eric Paris
  2009-02-10 14:59       ` Stephen Smalley
  0 siblings, 1 reply; 14+ messages in thread
From: Eric Paris @ 2009-02-10 14:30 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux, jmorris

On Tue, 2009-02-10 at 09:14 -0500, Stephen Smalley wrote:
> On Mon, 2009-02-09 at 16:37 -0500, Eric Paris wrote:
> > Currently when an inode is read into the kernel with an invalid label
> > string (can often happen with removable media) we output a string like:
> > 
> > SELinux: inode_doinit_with_dentry:  context_to_sid([SOME INVALID LABEL])
> > returned -22 dor dev=[blah] ino=[blah]
> > 
> > Which is all but incomprehensible to all but a couple of us.  Instead, on
> > EINVAL only, I plan to output a much more user friendly string and I plan to
> > ratelimit the printk since many of these could be generated very rapidly.
> > 
> > Signed-off-by: Eric Paris <eparis@redhat.com>
> 
> You could likely further drop the function name in all cases, and maybe
> even the error code (is there no strerror() equivalent in the kernel?).

I'd say that anyone getting the other message needs to report it to a
developer and I kinda like return codes, function names, and everything
else that normal users consider cryptic.  It really shouldn't be popping
out, so I hoped to leave it as is.

If you really want me to simply that one as well, do you have a text
suggestion?  If not, I'll leave this patch as is.

-Eric



--
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] 14+ messages in thread

* Re: [PATCH 2/3] SELinux: call capabilities code directory
  2009-02-10 14:06   ` Stephen Smalley
@ 2009-02-10 14:30     ` Eric Paris
  0 siblings, 0 replies; 14+ messages in thread
From: Eric Paris @ 2009-02-10 14:30 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux, jmorris

On Tue, 2009-02-10 at 09:06 -0500, Stephen Smalley wrote:
> On Mon, 2009-02-09 at 16:37 -0500, Eric Paris wrote:
> > For cleanliness and efficiency remove all calls to secondary-> and instead
> > call capabilities code directly.  capabilities are the only module that
> > selinux stacks with and so the code should not indicate that other stacking
> > might be possible.
> > 
> > Signed-off-by: Eric Paris <eparis@redhat.com>
> > ---
> > 
> >  security/selinux/hooks.c |   28 ++++++++++++++--------------
> >  1 files changed, 14 insertions(+), 14 deletions(-)
> > 
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index 6e6847d..e2bdb28 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> > @@ -2087,7 +2087,7 @@ static int selinux_syslog(int type)
> >   * mapping. 0 means there is enough memory for the allocation to
> >   * succeed and -ENOMEM implies there is not.
> >   *
> > - * Note that secondary_ops->capable and task_has_perm_noaudit return 0
> > + * Note that cap_capable and task_has_perm_noaudit return 0
> 
> This part of the comment is a bit out of date - at this point we are
> just calling selinux_capable(...SECURITY_CAP_NOAUDIT) rather than
> separately calling cap_capable() and task_has_perm_noaudit().

version 2 will redo the comment completely.


--
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] 14+ messages in thread

* Re: [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG
  2009-02-10 14:00 ` [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Stephen Smalley
@ 2009-02-10 14:39   ` Eric Paris
  2009-02-10 14:52     ` James Morris
  0 siblings, 1 reply; 14+ messages in thread
From: Eric Paris @ 2009-02-10 14:39 UTC (permalink / raw)
  To: Stephen Smalley; +Cc: selinux, jmorris

On Tue, 2009-02-10 at 09:00 -0500, Stephen Smalley wrote:
> On Mon, 2009-02-09 at 16:37 -0500, Eric Paris wrote:
> > If CONFIG_BUG is not set places in the code where BUG is called will not
> > end execution.  Look for places where this might result is system problems
> > and keep the system running.
> > 
> > Signed-off-by: Eric Paris <eparis@redhat.com>
> > ---
> > 
> >  kernel/capability.c            |    1 +
> >  security/selinux/avc.c         |   13 +++++++++++--
> >  security/selinux/hooks.c       |    9 ++++++++-
> >  security/selinux/netnode.c     |    3 +++
> >  security/selinux/ss/ebitmap.h  |   15 ++++++++++++---
> >  security/selinux/ss/services.c |   38 +++++++++++++++++++++++++++++++-------
> >  security/selinux/xfrm.c        |   15 ++++++++++++---
> >  7 files changed, 78 insertions(+), 16 deletions(-)
> > 
> <snip>
> > diff --git a/security/selinux/avc.c b/security/selinux/avc.c
> > index eb41f43..c22db1e 100644
> > --- a/security/selinux/avc.c
> > +++ b/security/selinux/avc.c
> > @@ -202,6 +202,7 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
> >  {
> >  	int rc;
> >  	char *scontext;
> > +	const char *class_string;
> >  	u32 scontext_len;
> >  
> >  	rc = security_sid_to_context(ssid, &scontext, &scontext_len);
> > @@ -220,8 +221,16 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
> >  		kfree(scontext);
> >  	}
> >  
> > -	BUG_ON(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass]);
> > -	audit_log_format(ab, " tclass=%s", class_to_string[tclass]);
> > +	if (unlikely(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass])) {
> > +		class_string = "unknown";
> > +		if (tclass >= ARRAY_SIZE(class_to_string))
> > +			BUG();
> > +		else
> > +			BUG();
> 
> Reduce that if statement to just BUG().
> A possible alternative to logging the "unknown" string would be to log
> the value of tclass; that would provide more information for debugging.

Took a second to remember why I did that.  I don't like BUG_ON(A || B)
since you don't know which it was.  If I output the value of tclass
before I BUG, maybe in a printk I'd be happy.  I look at this section
again.

> 
> > +	} else {
> > +		class_string = class_to_string[tclass];
> > +	}
> > +	audit_log_format(ab, " tclass=%s", class_string);
> >  }
> >  
> >  /**
> > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> > index ae5bb64..6e6847d 100644
> > --- a/security/selinux/hooks.c
> > +++ b/security/selinux/hooks.c
> > @@ -995,7 +995,11 @@ static int superblock_doinit(struct super_block *sb, void *data)
> >  	if (!data)
> >  		goto out;
> >  
> > -	BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA);
> > +	if (unlikely(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)) {
> > +		BUG();
> > +		rc = -EINVAL;
> > +		goto out_err;
> 
> Why out_err vs. out?  No allocation yet, right?  Or alternatively, if
> all calls to security_init_mnt_opts() should be balanced with calls to
> security_free_mnt_opts(), why don't we goto out_err in the prior error
> path?

Will look.

> > @@ -1500,6 +1505,8 @@ static int task_has_capability(struct task_struct *tsk,
> >  		printk(KERN_ERR
> >  		       "SELinux:  out of range capability %d\n", cap);
> >  		BUG();
> > +		/* should I audit somehow? */
> > +		return -EPERM;
> 
> I think the printk KERN_ERR suffices, or turn it into a audit_log
> AUDIT_SELINUX_ERR call.

Ok.

> > diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> > index c65e4fe..cfb0769 100644
> > --- a/security/selinux/ss/services.c
> > +++ b/security/selinux/ss/services.c
> > @@ -120,16 +120,25 @@ static int constraint_expr_eval(struct context *scontext,
> >  	for (e = cexpr; e; e = e->next) {
> >  		switch (e->expr_type) {
> >  		case CEXPR_NOT:
> > -			BUG_ON(sp < 0);
> > +			if (unlikely(sp < 0)) {
> > +				BUG();
> > +				return 0;
> > +			}
> 
> General question:  Should we in fact be panic'ing in these cases where
> we cannot return a value that will in fact abort the computation and
> guarantee that the operation will not proceed?  Same applies to the
> ebitmap code.  Just returning 0 (false) doesn't necessarily mean that we
> won't grant a permission, as the result may get negated.

James?


--
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] 14+ messages in thread

* Re: [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG
  2009-02-10 14:39   ` Eric Paris
@ 2009-02-10 14:52     ` James Morris
  2009-02-10 15:05       ` Stephen Smalley
  0 siblings, 1 reply; 14+ messages in thread
From: James Morris @ 2009-02-10 14:52 UTC (permalink / raw)
  To: Eric Paris; +Cc: Stephen Smalley, selinux

On Tue, 10 Feb 2009, Eric Paris wrote:

> > > +++ b/security/selinux/ss/services.c
> > > @@ -120,16 +120,25 @@ static int constraint_expr_eval(struct context *scontext,
> > >  	for (e = cexpr; e; e = e->next) {
> > >  		switch (e->expr_type) {
> > >  		case CEXPR_NOT:
> > > -			BUG_ON(sp < 0);
> > > +			if (unlikely(sp < 0)) {
> > > +				BUG();
> > > +				return 0;
> > > +			}
> > 
> > General question:  Should we in fact be panic'ing in these cases where
> > we cannot return a value that will in fact abort the computation and
> > guarantee that the operation will not proceed?  Same applies to the
> > ebitmap code.  Just returning 0 (false) doesn't necessarily mean that we
> > won't grant a permission, as the result may get negated.
> 
> James?

Perhaps panic() in enforcing mode, otherwise print a warning.


- James
-- 
James Morris
<jmorris@namei.org>

--
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] 14+ messages in thread

* Re: [PATCH 3/3] SELinux: better printk when file with invalid label found
  2009-02-10 14:30     ` Eric Paris
@ 2009-02-10 14:59       ` Stephen Smalley
  0 siblings, 0 replies; 14+ messages in thread
From: Stephen Smalley @ 2009-02-10 14:59 UTC (permalink / raw)
  To: Eric Paris; +Cc: selinux, jmorris

On Tue, 2009-02-10 at 09:30 -0500, Eric Paris wrote:
> On Tue, 2009-02-10 at 09:14 -0500, Stephen Smalley wrote:
> > On Mon, 2009-02-09 at 16:37 -0500, Eric Paris wrote:
> > > Currently when an inode is read into the kernel with an invalid label
> > > string (can often happen with removable media) we output a string like:
> > > 
> > > SELinux: inode_doinit_with_dentry:  context_to_sid([SOME INVALID LABEL])
> > > returned -22 dor dev=[blah] ino=[blah]
> > > 
> > > Which is all but incomprehensible to all but a couple of us.  Instead, on
> > > EINVAL only, I plan to output a much more user friendly string and I plan to
> > > ratelimit the printk since many of these could be generated very rapidly.
> > > 
> > > Signed-off-by: Eric Paris <eparis@redhat.com>
> > 
> > You could likely further drop the function name in all cases, and maybe
> > even the error code (is there no strerror() equivalent in the kernel?).
> 
> I'd say that anyone getting the other message needs to report it to a
> developer and I kinda like return codes, function names, and everything
> else that normal users consider cryptic.  It really shouldn't be popping
> out, so I hoped to leave it as is.
> 
> If you really want me to simply that one as well, do you have a text
> suggestion?  If not, I'll leave this patch as is.

Shrug.  That's fine.

-- 
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] 14+ messages in thread

* Re: [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG
  2009-02-10 14:52     ` James Morris
@ 2009-02-10 15:05       ` Stephen Smalley
  0 siblings, 0 replies; 14+ messages in thread
From: Stephen Smalley @ 2009-02-10 15:05 UTC (permalink / raw)
  To: James Morris; +Cc: Eric Paris, selinux

On Wed, 2009-02-11 at 01:52 +1100, James Morris wrote:
> On Tue, 10 Feb 2009, Eric Paris wrote:
> 
> > > > +++ b/security/selinux/ss/services.c
> > > > @@ -120,16 +120,25 @@ static int constraint_expr_eval(struct context *scontext,
> > > >  	for (e = cexpr; e; e = e->next) {
> > > >  		switch (e->expr_type) {
> > > >  		case CEXPR_NOT:
> > > > -			BUG_ON(sp < 0);
> > > > +			if (unlikely(sp < 0)) {
> > > > +				BUG();
> > > > +				return 0;
> > > > +			}
> > > 
> > > General question:  Should we in fact be panic'ing in these cases where
> > > we cannot return a value that will in fact abort the computation and
> > > guarantee that the operation will not proceed?  Same applies to the
> > > ebitmap code.  Just returning 0 (false) doesn't necessarily mean that we
> > > won't grant a permission, as the result may get negated.
> > 
> > James?
> 
> Perhaps panic() in enforcing mode, otherwise print a warning.

Yuck.

These are cases where we were already fine with an undefined opcode from
BUG() happening in the usual CONFIG_BUG=y case, so I'd think they could
be made unconditional panic() calls.

-- 
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] 14+ messages in thread

* Re: [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG
  2009-02-09 21:37 [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Eric Paris
                   ` (2 preceding siblings ...)
  2009-02-10 14:00 ` [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Stephen Smalley
@ 2009-02-10 16:37 ` Paul Moore
  2009-02-12 22:56 ` James Morris
  4 siblings, 0 replies; 14+ messages in thread
From: Paul Moore @ 2009-02-10 16:37 UTC (permalink / raw)
  To: Eric Paris; +Cc: selinux, sds, jmorris

On Monday 09 February 2009 04:37:14 pm Eric Paris wrote:
> If CONFIG_BUG is not set places in the code where BUG is called will not
> end execution.  Look for places where this might result is system problems
> and keep the system running.
>
> Signed-off-by: Eric Paris <eparis@redhat.com>

...

> diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
> index 7100072..e002d5a 100644
> --- a/security/selinux/netnode.c
> +++ b/security/selinux/netnode.c

...

> @@ -240,6 +242,7 @@ static int sel_netnode_sid_slow(void *addr, u16 family,
> u32 *sid) break;
>  	default:
>  		BUG();
> +		ret = -EINVAL;
>  	}
>  	if (ret != 0)
>  		goto out;

I'm just being picky here, but how about EPROTONOSUPPORT instead of EINVAL 
here?  Otherwise it looks good to me.

-- 
paul moore
linux @ 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] 14+ messages in thread

* Re: [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG
  2009-02-09 21:37 [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Eric Paris
                   ` (3 preceding siblings ...)
  2009-02-10 16:37 ` Paul Moore
@ 2009-02-12 22:56 ` James Morris
  4 siblings, 0 replies; 14+ messages in thread
From: James Morris @ 2009-02-12 22:56 UTC (permalink / raw)
  To: Eric Paris; +Cc: selinux, sds

On Mon, 9 Feb 2009, Eric Paris wrote:

> If CONFIG_BUG is not set places in the code where BUG is called will not
> end execution.  Look for places where this might result is system problems
> and keep the system running.

I wonder if we should make SELinux depend on CONFIG_BUG ?

This is pointlessly ugly, and I can't see why you'd disable CONFIG_BUG 
when running SELinux.


> Signed-off-by: Eric Paris <eparis@redhat.com>
> ---
> 
>  kernel/capability.c            |    1 +
>  security/selinux/avc.c         |   13 +++++++++++--
>  security/selinux/hooks.c       |    9 ++++++++-
>  security/selinux/netnode.c     |    3 +++
>  security/selinux/ss/ebitmap.h  |   15 ++++++++++++---
>  security/selinux/ss/services.c |   38 +++++++++++++++++++++++++++++++-------
>  security/selinux/xfrm.c        |   15 ++++++++++++---
>  7 files changed, 78 insertions(+), 16 deletions(-)
> 
> diff --git a/kernel/capability.c b/kernel/capability.c
> index 4e17041..e8bec6a 100644
> --- a/kernel/capability.c
> +++ b/kernel/capability.c
> @@ -304,6 +304,7 @@ int capable(int cap)
>  	if (unlikely(!cap_valid(cap))) {
>  		printk(KERN_CRIT "capable() called with invalid cap=%u\n", cap);
>  		BUG();
> +		return 0;
>  	}
>  
>  	if (security_capable(cap) == 0) {
> diff --git a/security/selinux/avc.c b/security/selinux/avc.c
> index eb41f43..c22db1e 100644
> --- a/security/selinux/avc.c
> +++ b/security/selinux/avc.c
> @@ -202,6 +202,7 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
>  {
>  	int rc;
>  	char *scontext;
> +	const char *class_string;
>  	u32 scontext_len;
>  
>  	rc = security_sid_to_context(ssid, &scontext, &scontext_len);
> @@ -220,8 +221,16 @@ static void avc_dump_query(struct audit_buffer *ab, u32 ssid, u32 tsid, u16 tcla
>  		kfree(scontext);
>  	}
>  
> -	BUG_ON(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass]);
> -	audit_log_format(ab, " tclass=%s", class_to_string[tclass]);
> +	if (unlikely(tclass >= ARRAY_SIZE(class_to_string) || !class_to_string[tclass])) {
> +		class_string = "unknown";
> +		if (tclass >= ARRAY_SIZE(class_to_string))
> +			BUG();
> +		else
> +			BUG();
> +	} else {
> +		class_string = class_to_string[tclass];
> +	}
> +	audit_log_format(ab, " tclass=%s", class_string);
>  }
>  
>  /**
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index ae5bb64..6e6847d 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -995,7 +995,11 @@ static int superblock_doinit(struct super_block *sb, void *data)
>  	if (!data)
>  		goto out;
>  
> -	BUG_ON(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA);
> +	if (unlikely(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)) {
> +		BUG();
> +		rc = -EINVAL;
> +		goto out_err;
> +	}
>  
>  	rc = selinux_parse_opts_str(options, &opts);
>  	if (rc)
> @@ -1042,6 +1046,7 @@ static void selinux_write_opts(struct seq_file *m,
>  			continue;
>  		default:
>  			BUG();
> +			continue;
>  		};
>  		/* we need a comma before each option */
>  		seq_putc(m, ',');
> @@ -1500,6 +1505,8 @@ static int task_has_capability(struct task_struct *tsk,
>  		printk(KERN_ERR
>  		       "SELinux:  out of range capability %d\n", cap);
>  		BUG();
> +		/* should I audit somehow? */
> +		return -EPERM;
>  	}
>  
>  	rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
> diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
> index 7100072..e002d5a 100644
> --- a/security/selinux/netnode.c
> +++ b/security/selinux/netnode.c
> @@ -140,6 +140,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
>  		break;
>  	default:
>  		BUG();
> +		return NULL;
>  	}
>  
>  	list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
> @@ -180,6 +181,7 @@ static void sel_netnode_insert(struct sel_netnode *node)
>  		break;
>  	default:
>  		BUG();
> +		return;
>  	}
>  
>  	INIT_RCU_HEAD(&node->rcu);
> @@ -240,6 +242,7 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid)
>  		break;
>  	default:
>  		BUG();
> +		ret = -EINVAL;
>  	}
>  	if (ret != 0)
>  		goto out;
> diff --git a/security/selinux/ss/ebitmap.h b/security/selinux/ss/ebitmap.h
> index f283b43..425f8b8 100644
> --- a/security/selinux/ss/ebitmap.h
> +++ b/security/selinux/ss/ebitmap.h
> @@ -85,7 +85,10 @@ static inline int ebitmap_node_get_bit(struct ebitmap_node *n,
>  	unsigned int index = EBITMAP_NODE_INDEX(n, bit);
>  	unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
>  
> -	BUG_ON(index >= EBITMAP_UNIT_NUMS);
> +	if (unlikely((index >= EBITMAP_UNIT_NUMS))) {
> +		BUG();
> +		return 0;
> +	}
>  	if ((n->maps[index] & (EBITMAP_BIT << ofs)))
>  		return 1;
>  	return 0;
> @@ -97,7 +100,10 @@ static inline void ebitmap_node_set_bit(struct ebitmap_node *n,
>  	unsigned int index = EBITMAP_NODE_INDEX(n, bit);
>  	unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
>  
> -	BUG_ON(index >= EBITMAP_UNIT_NUMS);
> +	if (unlikely((index >= EBITMAP_UNIT_NUMS))) {
> +		BUG();
> +		return;
> +	}
>  	n->maps[index] |= (EBITMAP_BIT << ofs);
>  }
>  
> @@ -107,7 +113,10 @@ static inline void ebitmap_node_clr_bit(struct ebitmap_node *n,
>  	unsigned int index = EBITMAP_NODE_INDEX(n, bit);
>  	unsigned int ofs = EBITMAP_NODE_OFFSET(n, bit);
>  
> -	BUG_ON(index >= EBITMAP_UNIT_NUMS);
> +	if (unlikely((index >= EBITMAP_UNIT_NUMS))) {
> +		BUG();
> +		return;
> +	}
>  	n->maps[index] &= ~(EBITMAP_BIT << ofs);
>  }
>  
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index c65e4fe..cfb0769 100644
> --- a/security/selinux/ss/services.c
> +++ b/security/selinux/ss/services.c
> @@ -120,16 +120,25 @@ static int constraint_expr_eval(struct context *scontext,
>  	for (e = cexpr; e; e = e->next) {
>  		switch (e->expr_type) {
>  		case CEXPR_NOT:
> -			BUG_ON(sp < 0);
> +			if (unlikely(sp < 0)) {
> +				BUG();
> +				return 0;
> +			}
>  			s[sp] = !s[sp];
>  			break;
>  		case CEXPR_AND:
> -			BUG_ON(sp < 1);
> +			if (unlikely(sp < 1)) {
> +				BUG();
> +				return 0;
> +			}
>  			sp--;
>  			s[sp] &= s[sp+1];
>  			break;
>  		case CEXPR_OR:
> -			BUG_ON(sp < 1);
> +			if (unlikely(sp < 1)) {
> +				BUG();
> +				return 0;
> +			}
>  			sp--;
>  			s[sp] |= s[sp+1];
>  			break;
> @@ -541,7 +550,11 @@ int security_permissive_sid(u32 sid)
>  	read_lock(&policy_rwlock);
>  
>  	context = sidtab_search(&sidtab, sid);
> -	BUG_ON(!context);
> +	if (unlikely(!context)) {
> +		BUG();
> +		rc = 0;
> +		goto out;
> +	}
>  
>  	type = context->type;
>  	/*
> @@ -550,6 +563,7 @@ int security_permissive_sid(u32 sid)
>  	 */
>  	rc = ebitmap_get_bit(&policydb.permissive_map, type);
>  
> +out:
>  	read_unlock(&policy_rwlock);
>  	return rc;
>  }
> @@ -697,7 +711,11 @@ int security_bounded_transition(u32 old_sid, u32 new_sid)
>  	index = new_context->type;
>  	while (true) {
>  		type = policydb.type_val_to_struct[index - 1];
> -		BUG_ON(!type);
> +		if (unlikely(!type)) {
> +			BUG();
> +			rc = -EPERM;
> +			goto out;
> +		}
>  
>  		/* not bounded anymore */
>  		if (!type->bounds) {
> @@ -1381,7 +1399,10 @@ static int validate_classes(struct policydb *p)
>  			continue;
>  		pol_class = p->p_class_val_to_name[class_val-1];
>  		cladatum = hashtab_search(p->p_classes.table, pol_class);
> -		BUG_ON(!cladatum);
> +		if (unlikely(!cladatum)) {
> +			BUG();
> +			return -EINVAL;
> +		}
>  		perms = &cladatum->permissions;
>  		nprim = 1 << (perms->nprim - 1);
>  		if (perm_val > nprim) {
> @@ -1416,7 +1437,10 @@ static int validate_classes(struct policydb *p)
>  			continue;
>  		pol_class = p->p_class_val_to_name[class_val-1];
>  		cladatum = hashtab_search(p->p_classes.table, pol_class);
> -		BUG_ON(!cladatum);
> +		if (unlikely(!cladatum)) {
> +			BUG();
> +			return -EINVAL;
> +		}
>  		if (!cladatum->comdatum) {
>  			printk(KERN_ERR
>  			       "SELinux:  class %s should have an inherits clause but does not\n",
> diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
> index c0eb720..22413ec 100644
> --- a/security/selinux/xfrm.c
> +++ b/security/selinux/xfrm.c
> @@ -202,7 +202,10 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp,
>  	char *ctx_str = NULL;
>  	u32 str_len;
>  
> -	BUG_ON(uctx && sid);
> +	if (unlikely(ctx && sid)) {
> +		BUG();
> +		return -EINVAL;
> +	}
>  
>  	if (!uctx)
>  		goto not_from_user;
> @@ -288,7 +291,10 @@ int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp,
>  {
>  	int err;
>  
> -	BUG_ON(!uctx);
> +	if (unlikely(!uctx)) {
> +		BUG();
> +		return -EINVAL;
> +	}
>  
>  	err = selinux_xfrm_sec_ctx_alloc(ctxp, uctx, 0);
>  	if (err == 0)
> @@ -356,7 +362,10 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uct
>  {
>  	int err;
>  
> -	BUG_ON(!x);
> +	if (unlikely(!x)) {
> +		BUG();
> +		return -EINVAL;
> +	}
>  
>  	err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, secid);
>  	if (err == 0)
> 

-- 
James Morris
<jmorris@namei.org>

--
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] 14+ messages in thread

end of thread, other threads:[~2009-02-12 22:56 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-09 21:37 [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Eric Paris
2009-02-09 21:37 ` [PATCH 2/3] SELinux: call capabilities code directory Eric Paris
2009-02-10 14:06   ` Stephen Smalley
2009-02-10 14:30     ` Eric Paris
2009-02-09 21:37 ` [PATCH 3/3] SELinux: better printk when file with invalid label found Eric Paris
2009-02-10 14:14   ` Stephen Smalley
2009-02-10 14:30     ` Eric Paris
2009-02-10 14:59       ` Stephen Smalley
2009-02-10 14:00 ` [PATCH 1/3] SELinux: fix selinux to safely handle any bugs even when not CONFIG_BUG Stephen Smalley
2009-02-10 14:39   ` Eric Paris
2009-02-10 14:52     ` James Morris
2009-02-10 15:05       ` Stephen Smalley
2009-02-10 16:37 ` Paul Moore
2009-02-12 22:56 ` James Morris

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.