rpms/kernel/F-11 config-debug, 1.25, 1.26 config-generic, 1.283, 1.284 config-nodebug, 1.34, 1.35 kernel.spec, 1.1650, 1.1651 linux-2.6-debug-selinux-null-creds.patch, 1.2, 1.3

Chuck Ebbert cebbert at fedoraproject.org
Tue Jun 16 19:05:45 UTC 2009


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-11
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv1416

Modified Files:
	config-debug config-generic config-nodebug kernel.spec 
	linux-2.6-debug-selinux-null-creds.patch 
Log Message:
New debug patch for bug #494067, now enabled for non-debug kernels too.


Index: config-debug
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/config-debug,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -p -r1.25 -r1.26
--- config-debug	8 Jun 2009 21:44:30 -0000	1.25
+++ config-debug	16 Jun 2009 19:05:14 -0000	1.26
@@ -50,5 +50,3 @@ CONFIG_DEBUG_NOTIFIERS=y
 CONFIG_DMA_API_DEBUG=y
 
 CONFIG_MMIOTRACE=y
-
-CONFIG_SECURITY_SELINUX_DEBUG_NULL=y


Index: config-generic
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/config-generic,v
retrieving revision 1.283
retrieving revision 1.284
diff -u -p -r1.283 -r1.284
--- config-generic	13 Jun 2009 02:07:58 -0000	1.283
+++ config-generic	16 Jun 2009 19:05:14 -0000	1.284
@@ -3860,3 +3860,7 @@ CONFIG_FCOE=m
 # CONFIG_CRASH is not set
 
 CONFIG_MMC_VIA_SDMMC=m
+
+# for bug #494067
+CONFIG_DEBUG_CREDENTIALS=y
+


Index: config-nodebug
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/config-nodebug,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -p -r1.34 -r1.35
--- config-nodebug	8 Jun 2009 21:44:30 -0000	1.34
+++ config-nodebug	16 Jun 2009 19:05:14 -0000	1.35
@@ -49,5 +49,3 @@ CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
 # CONFIG_DMA_API_DEBUG is not set
 
 # CONFIG_MMIOTRACE is not set
-
-# CONFIG_SECURITY_SELINUX_DEBUG_NULL is not set


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/kernel.spec,v
retrieving revision 1.1650
retrieving revision 1.1651
diff -u -p -r1.1650 -r1.1651
--- kernel.spec	16 Jun 2009 18:00:54 -0000	1.1650
+++ kernel.spec	16 Jun 2009 19:05:14 -0000	1.1651
@@ -2058,6 +2058,9 @@ fi
 # and build.
 
 %changelog
+* Tue Jun 16 2009 Chuck Ebbert <cebbert at redhat.com> 2.6.29.5-189
+- New debug patch for bug #494067, now enabled for non-debug kernels too.
+
 * Tue Jun 16 2009 Chuck Ebbert <cebbert at redhat.com> 2.6.29.5-188
 - Avoid lockup on OOM with /dev/zero
 

linux-2.6-debug-selinux-null-creds.patch:

Index: linux-2.6-debug-selinux-null-creds.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/linux-2.6-debug-selinux-null-creds.patch,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -p -r1.2 -r1.3
--- linux-2.6-debug-selinux-null-creds.patch	8 Jun 2009 21:51:38 -0000	1.2
+++ linux-2.6-debug-selinux-null-creds.patch	16 Jun 2009 19:05:14 -0000	1.3
@@ -1,116 +1,472 @@
---- work-2.6.29.4.orig/kernel/cred.c
-+++ work-2.6.29.4/kernel/cred.c
-@@ -157,6 +157,9 @@ struct cred *prepare_creds(void)
+From: David Howells <dhowells at redhat.com>
+Subject: [PATCH] CRED: Add some configurable debugging
+
+Add a config option (CONFIG_DEBUG_CREDENTIALS) to turn on some debug checking
+for credential management.  The additional code keeps track of the number of
+pointers from task_structs to any given cred struct, and checks to see that
+this number never exceeds the usage count of the cred struct (which includes
+all references, not just those from task_structs).
+
+Furthermore, if SELinux is enabled, the code also checks that the security
+pointer in the cred struct is never seen to be invalid.
+
+This attempts to catch the bug whereby inode_has_perm() faults in an nfsd
+kernel thread on seeing cred->security be a NULL pointer (it appears that the
+credential struct has been previously released):
+
+	http://www.kerneloops.org/oops.php?number=252883
+
+Signed-off-by: David Howells <dhowells at redhat.com>
+---
+
+ fs/nfsd/vfs.c            |    2 +
+ fs/open.c                |    2 +
+ include/linux/cred.h     |   35 +++++++++++++++
+ kernel/cred.c            |  107 +++++++++++++++++++++++++++++++++++++++++++---
+ kernel/fork.c            |    6 +--
+ kernel/kmod.c            |    1 
+ lib/Kconfig.debug        |   15 ++++++
+ security/selinux/hooks.c |    6 ++-
+ 8 files changed, 162 insertions(+), 12 deletions(-)
+
+
+diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
+index 99f8357..494e310 100644
+--- a/fs/nfsd/vfs.c
++++ b/fs/nfsd/vfs.c
+@@ -685,6 +685,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
+ 	__be32		err;
+ 	int		host_err;
+ 
++	validate_creds(cred);
++
+ 	/*
+ 	 * If we get here, then the client has already done an "open",
+ 	 * and (hopefully) checked permission - so allow OWNER_OVERRIDE
+diff --git a/fs/open.c b/fs/open.c
+index 5c27f96..6069333 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -959,6 +959,8 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
+ 	int error;
+ 	struct file *f;
+ 
++	validate_creds(cred);
++
+ 	/*
+ 	 * We must always pass in a valid mount pointer.   Historically
+ 	 * callers got away with not passing it, but we must enforce this at
+diff --git a/include/linux/cred.h b/include/linux/cred.h
+index 4fa9996..2bdd6ce 100644
+--- a/include/linux/cred.h
++++ b/include/linux/cred.h
+@@ -114,6 +114,9 @@ struct thread_group_cred {
+  */
+ struct cred {
+ 	atomic_t	usage;
++#ifdef CONFIG_DEBUG_CREDENTIALS
++	atomic_t	subscribers;	/* number of processes subscribed */
++#endif
+ 	uid_t		uid;		/* real UID of the task */
+ 	gid_t		gid;		/* real GID of the task */
+ 	uid_t		suid;		/* saved UID of the task */
+@@ -143,6 +146,7 @@ struct cred {
+ };
+ 
+ extern void __put_cred(struct cred *);
++extern void exit_creds(struct task_struct *);
+ extern int copy_creds(struct task_struct *, unsigned long);
+ extern struct cred *prepare_creds(void);
+ extern struct cred *prepare_exec_creds(void);
+@@ -157,6 +161,34 @@ extern int set_security_override(struct cred *, u32);
+ extern int set_security_override_from_ctx(struct cred *, const char *);
+ extern int set_create_files_as(struct cred *, struct inode *);
+ extern void __init cred_init(void);
++extern void __validate_creds(const struct cred *, const char *, unsigned);
++
++/*
++ * check for validity of credentials
++ */
++#ifdef CONFIG_DEBUG_CREDENTIALS
++static inline bool creds_are_invalid(const struct cred *cred)
++{
++	if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers))
++		return true;
++#ifdef CONFIG_SECURITY_SELINUX
++	if ((unsigned long) cred->security < PAGE_SIZE)
++		return true;
++#endif
++	return false;
++}
++
++#define validate_creds(cred)					\
++do {								\
++	if (unlikely(creds_are_invalid((cred))))		\
++		__validate_creds((cred), __FILE__, __LINE__);	\
++} while(0)
++
++#else
++static inline void validate_creds(const struct cred *cred)
++{
++}
++#endif
+ 
+ /**
+  * get_new_cred - Get a reference on a new set of credentials
+@@ -186,6 +218,7 @@ static inline struct cred *get_new_cred(struct cred *cred)
+  */
+ static inline const struct cred *get_cred(const struct cred *cred)
+ {
++	validate_creds(cred);
+ 	return get_new_cred((struct cred *) cred);
+ }
+ 
+@@ -204,7 +237,7 @@ static inline void put_cred(const struct cred *_cred)
+ {
+ 	struct cred *cred = (struct cred *) _cred;
+ 
+-	BUG_ON(atomic_read(&(cred)->usage) <= 0);
++	validate_creds(cred);
+ 	if (atomic_dec_and_test(&(cred)->usage))
+ 		__put_cred(cred);
+ }
+diff --git a/kernel/cred.c b/kernel/cred.c
+index 1bb4d7e..67f32cd 100644
+--- a/kernel/cred.c
++++ b/kernel/cred.c
+@@ -36,6 +36,9 @@ static struct thread_group_cred init_tgcred = {
+  */
+ struct cred init_cred = {
+ 	.usage			= ATOMIC_INIT(4),
++#ifdef CONFIG_DEBUG_CREDENTIALS
++	.subscribers		= ATOMIC_INIT(2),
++#endif
+ 	.securebits		= SECUREBITS_DEFAULT,
+ 	.cap_inheritable	= CAP_INIT_INH_SET,
+ 	.cap_permitted		= CAP_FULL_SET,
+@@ -48,6 +51,22 @@ struct cred init_cred = {
+ #endif
+ };
+ 
++static inline void set_cred_subscribers(struct cred *cred, int n)
++{
++#ifdef CONFIG_DEBUG_CREDENTIALS
++	atomic_set(&cred->subscribers, n);
++#endif
++}
++
++static inline void alter_cred_subscribers(const struct cred *_cred, int n)
++{
++#ifdef CONFIG_DEBUG_CREDENTIALS
++	struct cred *cred = (struct cred *) _cred;
++
++	atomic_add(n, &cred->subscribers);
++#endif
++}
++
+ /*
+  * Dispose of the shared task group credentials
+  */
+@@ -85,9 +104,17 @@ static void put_cred_rcu(struct rcu_head *rcu)
+ {
+ 	struct cred *cred = container_of(rcu, struct cred, rcu);
+ 
++#ifdef CONFIG_DEBUG_CREDENTIALS
++	if (atomic_read(&cred->usage) != 0 ||
++	    atomic_read(&cred->subscribers) != 0)
++		panic("CRED: put_cred_rcu() sees %p with usage %d, subscr %d\n",
++		      cred, atomic_read(&cred->usage),
++		      atomic_read(&cred->subscribers));
++#else
+ 	if (atomic_read(&cred->usage) != 0)
+ 		panic("CRED: put_cred_rcu() sees %p with usage %d\n",
+ 		      cred, atomic_read(&cred->usage));
++#endif
+ 
+ 	security_cred_free(cred);
+ 	key_put(cred->thread_keyring);
+@@ -107,11 +134,28 @@ static void put_cred_rcu(struct rcu_head *rcu)
+ void __put_cred(struct cred *cred)
+ {
+ 	BUG_ON(atomic_read(&cred->usage) != 0);
++#ifdef CONFIG_DEBUG_CREDENTIALS
++	BUG_ON(atomic_read(&cred->subscribers) != 0);
++#endif
+ 
+ 	call_rcu(&cred->rcu, put_cred_rcu);
+ }
+ EXPORT_SYMBOL(__put_cred);
+ 
++/*
++ * Clean up a task's credentials when it exits
++ */
++void exit_creds(struct task_struct *tsk)
++{
++	validate_creds(tsk->real_cred);
++	alter_cred_subscribers(tsk->real_cred, -1);
++	put_cred(tsk->real_cred);
++
++	validate_creds(tsk->cred);
++	alter_cred_subscribers(tsk->cred, -1);
++	put_cred(tsk->cred);
++}
++
+ /**
+  * prepare_creds - Prepare a new set of credentials for modification
+  *
+@@ -132,7 +176,17 @@ struct cred *prepare_creds(void)
+ 	const struct cred *old;
+ 	struct cred *new;
+ 
+-	BUG_ON(atomic_read(&task->real_cred->usage) < 1);
++#ifdef CONFIG_DEBUG_CREDENTIALS
++	if (task->cred != task->real_cred) {
++		BUG_ON(atomic_read(&task->real_cred->subscribers) < 1);
++		BUG_ON(atomic_read(&task->cred->subscribers) < 1);
++		validate_creds(task->real_cred);
++		validate_creds(task->cred);
++	} else {
++		BUG_ON(atomic_read(&task->cred->subscribers) < 2);
++		validate_creds(task->cred);
++	}
++#endif
+ 
+ 	new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
+ 	if (!new)
+@@ -142,6 +196,7 @@ struct cred *prepare_creds(void)
+ 	memcpy(new, old, sizeof(struct cred));
+ 
+ 	atomic_set(&new->usage, 1);
++	set_cred_subscribers(new, 0);
+ 	get_group_info(new->group_info);
+ 	get_uid(new->user);
+ 
+@@ -157,6 +212,7 @@ struct cred *prepare_creds(void)
  
  	if (security_prepare_creds(new, old, GFP_KERNEL) < 0)
  		goto error;
-+#if defined(CONFIG_SECURITY_SELINUX) && defined(CONFIG_SECURITY_SELINUX_DEBUG_NULL)
-+	WARN_ON((unsigned long)new->security < 8);
-+#endif
++	validate_creds(new);
  	return new;
  
  error:
-@@ -250,6 +253,9 @@ struct cred *prepare_usermodehelper_cred
+@@ -232,6 +288,7 @@ struct cred *prepare_usermodehelper_creds(void)
+ 	memcpy(new, &init_cred, sizeof(struct cred));
+ 
+ 	atomic_set(&new->usage, 1);
++	set_cred_subscribers(new, 0);
+ 	get_group_info(new->group_info);
+ 	get_uid(new->user);
+ 
+@@ -250,6 +307,7 @@ struct cred *prepare_usermodehelper_creds(void)
  #endif
  	if (security_prepare_creds(new, &init_cred, GFP_ATOMIC) < 0)
  		goto error;
-+#if defined(CONFIG_SECURITY_SELINUX) && defined(CONFIG_SECURITY_SELINUX_DEBUG_NULL)
-+	WARN_ON((unsigned long)new->security < 8);
-+#endif
++	validate_creds(new);
  
  	BUG_ON(atomic_read(&new->usage) != 1);
  	return new;
-@@ -331,6 +337,9 @@ int copy_creds(struct task_struct *p, un
+@@ -330,7 +388,9 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
+ #endif
  
  	atomic_inc(&new->user->processes);
++	alter_cred_subscribers(new, 2);
  	p->cred = p->real_cred = get_cred(new);
-+#if defined(CONFIG_SECURITY_SELINUX) && defined(CONFIG_SECURITY_SELINUX_DEBUG_NULL)
-+	WARN_ON((unsigned long)new->security < 8);
-+#endif
++	validate_creds(new);
  	return 0;
  
  error_put:
-@@ -360,6 +369,9 @@ int commit_creds(struct cred *new)
- 	BUG_ON(task->cred != task->real_cred);
- 	BUG_ON(atomic_read(&task->real_cred->usage) < 2);
- 	BUG_ON(atomic_read(&new->usage) < 1);
-+#if defined(CONFIG_SECURITY_SELINUX) && defined(CONFIG_SECURITY_SELINUX_DEBUG_NULL)
-+	WARN_ON((unsigned long)new->security < 8);
+@@ -355,13 +415,16 @@ error_put:
+ int commit_creds(struct cred *new)
+ {
+ 	struct task_struct *task = current;
+-	const struct cred *old;
++	const struct cred *old = task->real_cred;
+ 
+-	BUG_ON(task->cred != task->real_cred);
+-	BUG_ON(atomic_read(&task->real_cred->usage) < 2);
++	BUG_ON(task->cred != old);
++#ifdef CONFIG_DEBUG_CREDENTIALS
++	BUG_ON(atomic_read(&old->subscribers) < 2);
++	validate_creds(old);
++	validate_creds(new);
 +#endif
+ 	BUG_ON(atomic_read(&new->usage) < 1);
  
- 	old = task->real_cred;
+-	old = task->real_cred;
  	security_commit_creds(new, old);
-@@ -444,6 +456,10 @@ const struct cred *override_creds(const 
+ 
+ 	get_cred(new); /* we will require a ref for the subj creds too */
+@@ -390,12 +453,14 @@ int commit_creds(struct cred *new)
+ 	 *   cheaply with the new uid cache, so if it matters
+ 	 *   we should be checking for it.  -DaveM
+ 	 */
++	alter_cred_subscribers(new, 2);
+ 	if (new->user != old->user)
+ 		atomic_inc(&new->user->processes);
+ 	rcu_assign_pointer(task->real_cred, new);
+ 	rcu_assign_pointer(task->cred, new);
+ 	if (new->user != old->user)
+ 		atomic_dec(&old->user->processes);
++	alter_cred_subscribers(old, -2);
+ 
+ 	sched_switch_user(task);
+ 
+@@ -428,6 +493,9 @@ EXPORT_SYMBOL(commit_creds);
+  */
+ void abort_creds(struct cred *new)
+ {
++#ifdef CONFIG_DEBUG_CREDENTIALS
++	BUG_ON(atomic_read(&new->subscribers) != 0);
++#endif
+ 	BUG_ON(atomic_read(&new->usage) < 1);
+ 	put_cred(new);
+ }
+@@ -444,7 +512,12 @@ const struct cred *override_creds(const struct cred *new)
  {
  	const struct cred *old = current->cred;
  
-+#if defined(CONFIG_SECURITY_SELINUX) && defined(CONFIG_SECURITY_SELINUX_DEBUG_NULL)
-+	WARN_ON((unsigned long)old->security < 8);
-+	WARN_ON((unsigned long)new->security < 8);
-+#endif
- 	rcu_assign_pointer(current->cred, get_cred(new));
+-	rcu_assign_pointer(current->cred, get_cred(new));
++	validate_creds(old);
++	validate_creds(new);
++	get_cred(new);
++	alter_cred_subscribers(new, 1);
++	rcu_assign_pointer(current->cred, new);
++	alter_cred_subscribers(old, -1);
  	return old;
  }
-@@ -460,6 +476,10 @@ void revert_creds(const struct cred *old
+ EXPORT_SYMBOL(override_creds);
+@@ -460,7 +533,11 @@ void revert_creds(const struct cred *old)
  {
  	const struct cred *override = current->cred;
  
-+#if defined(CONFIG_SECURITY_SELINUX) && defined(CONFIG_SECURITY_SELINUX_DEBUG_NULL)
-+	WARN_ON((unsigned long)old->security < 8);
-+	WARN_ON((unsigned long)override->security < 8);
-+#endif
++	validate_creds(old);
++	validate_creds(override);
++	alter_cred_subscribers(old, 1);
  	rcu_assign_pointer(current->cred, old);
++	alter_cred_subscribers(override, -1);
  	put_cred(override);
  }
-@@ -507,6 +527,10 @@ struct cred *prepare_kernel_cred(struct 
+ EXPORT_SYMBOL(revert_creds);
+@@ -507,6 +584,8 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
  	else
  		old = get_cred(&init_cred);
  
-+#if defined(CONFIG_SECURITY_SELINUX) && defined(CONFIG_SECURITY_SELINUX_DEBUG_NULL)
-+	WARN_ON((unsigned long)old->security < 8);
-+#endif
++	validate_creds(old);
 +
  	*new = *old;
  	get_uid(new->user);
  	get_group_info(new->group_info);
-@@ -527,6 +551,9 @@ struct cred *prepare_kernel_cred(struct 
+@@ -526,7 +605,9 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
+ 		goto error;
  
  	atomic_set(&new->usage, 1);
++	set_cred_subscribers(new, 0);
  	put_cred(old);
-+#if defined(CONFIG_SECURITY_SELINUX) && defined(CONFIG_SECURITY_SELINUX_DEBUG_NULL)
-+	WARN_ON((unsigned long)new->security < 8);
-+#endif
++	validate_creds(new);
  	return new;
  
  error:
---- work-2.6.29.4.orig/security/selinux/hooks.c
-+++ work-2.6.29.4/security/selinux/hooks.c
-@@ -3239,7 +3239,11 @@ static int selinux_task_create(unsigned 
+@@ -589,3 +670,17 @@ int set_create_files_as(struct cred *new, struct inode *inode)
+ 	return security_kernel_create_files_as(new, inode);
+ }
+ EXPORT_SYMBOL(set_create_files_as);
++
++/*
++ * report use of invalid credentials
++ */
++void __validate_creds(const struct cred *cred, const char *file, unsigned line)
++{
++#ifdef CONFIG_SECURITY_SELINUX
++	if (unlikely((unsigned long) cred->security < PAGE_SIZE)) {
++		printk(KERN_ERR "ERROR: cred->security is %p\n", cred->security);
++		BUG();
++	}
++#endif
++}
++EXPORT_SYMBOL(__validate_creds);
+diff --git a/kernel/fork.c b/kernel/fork.c
+index 4430eb1..7cb5612 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -153,8 +153,7 @@ void __put_task_struct(struct task_struct *tsk)
+ 	WARN_ON(atomic_read(&tsk->usage));
+ 	WARN_ON(tsk == current);
+ 
+-	put_cred(tsk->real_cred);
+-	put_cred(tsk->cred);
++	exit_creds(tsk);
+ 	delayacct_tsk_free(tsk);
+ 
+ 	if (!profile_handoff_task(tsk))
+@@ -1308,8 +1307,7 @@ bad_fork_cleanup_put_domain:
+ 	module_put(task_thread_info(p)->exec_domain->module);
+ bad_fork_cleanup_count:
+ 	atomic_dec(&p->cred->user->processes);
+-	put_cred(p->real_cred);
+-	put_cred(p->cred);
++	exit_creds(p);
+ bad_fork_free:
+ 	free_task(p);
+ fork_out:
+diff --git a/kernel/kmod.c b/kernel/kmod.c
+index 7e95bed..f9b597f 100644
+--- a/kernel/kmod.c
++++ b/kernel/kmod.c
+@@ -463,6 +463,7 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info,
+ 	int retval = 0;
+ 
+ 	BUG_ON(atomic_read(&sub_info->cred->usage) != 1);
++	validate_creds(sub_info->cred);
+ 
+ 	helper_lock();
+ 	if (sub_info->path[0] == '\0')
+diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
+index 2d32cdf..a185231 100644
+--- a/lib/Kconfig.debug
++++ b/lib/Kconfig.debug
+@@ -650,6 +650,21 @@ config DEBUG_NOTIFIERS
+ 	  This is a relatively cheap check but if you care about maximum
+ 	  performance, say N.
+ 
++config DEBUG_CREDENTIALS
++	bool "Debug credential management"
++	depends on DEBUG_KERNEL
++	help
++	  Enable this to turn on some debug checking for credential
++	  management.  The additional code keeps track of the number of
++	  pointers from task_structs to any given cred struct, and checks to
++	  see that this number never exceeds the usage count of the cred
++	  struct.
++
++	  Furthermore, if SELinux is enabled, this also checks that the
++	  security pointer in the cred struct is never seen to be invalid.
++
++	  If unsure, say N.
++
+ #
+ # Select this config option from the architecture Kconfig, if it
+ # it is preferred to always offer frame pointers as a config
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
+index 15c2a08..9272dee 100644
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -1530,6 +1530,8 @@ static int inode_has_perm(const struct cred *cred,
+ 	struct avc_audit_data ad;
+ 	u32 sid;
+ 
++	validate_creds(cred);
++
+ 	if (unlikely(IS_PRIVATE(inode)))
+ 		return 0;
+ 
+@@ -3212,7 +3214,9 @@ static int selinux_task_create(unsigned long clone_flags)
  static void selinux_cred_free(struct cred *cred)
  {
  	struct task_security_struct *tsec = cred->security;
-+#if defined(CONFIG_SECURITY_SELINUX_DEBUG_NULL)
+-	cred->security = NULL;
++
++	BUG_ON((unsigned long) cred->security < PAGE_SIZE);
 +	cred->security = (void *) 0x7UL;
-+#else
- 	cred->security = NULL;
-+#endif
  	kfree(tsec);
  }
  
---- work-2.6.29.4.orig/security/selinux/Kconfig
-+++ work-2.6.29.4/security/selinux/Kconfig
-@@ -8,6 +8,14 @@ config SECURITY_SELINUX
- 	  You will also need a policy configuration and a labeled filesystem.
- 	  If you are unsure how to answer this question, answer N.
- 
-+config SECURITY_SELINUX_DEBUG_NULL
-+	bool "Debug NULL credentials"
-+	depends on SECURITY_SELINUX
-+	default n
-+	help
-+	  This adds debugging for null security credentials
-+	  If you are unsure how to answer this question, answer N.
-+
- config SECURITY_SELINUX_BOOTPARAM
- 	bool "NSA SELinux boot parameter"
- 	depends on SECURITY_SELINUX




More information about the fedora-extras-commits mailing list