rpms/kernel/F-11 kernel.spec, 1.1663, 1.1664 linux-2.6-debug-selinux-null-creds.patch, 1.3, 1.4

Chuck Ebbert cebbert at fedoraproject.org
Mon Jun 29 17:53:24 UTC 2009


Author: cebbert

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

Modified Files:
	kernel.spec linux-2.6-debug-selinux-null-creds.patch 
Log Message:
New debug patch for null selinux credentials (for bug #494067)


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-11/kernel.spec,v
retrieving revision 1.1663
retrieving revision 1.1664
diff -u -p -r1.1663 -r1.1664
--- kernel.spec	29 Jun 2009 06:15:34 -0000	1.1663
+++ kernel.spec	29 Jun 2009 17:52:54 -0000	1.1664
@@ -1270,7 +1270,7 @@ ApplyPatch linux-2.6-debug-taint-vm.patc
 ApplyPatch linux-2.6-debug-spinlock-taint.patch
 ApplyPatch linux-2.6-debug-vm-would-have-oomkilled.patch
 ApplyPatch linux-2.6-debug-always-inline-kzalloc.patch
-#ApplyPatch linux-2.6-debug-selinux-null-creds.patch
+ApplyPatch linux-2.6-debug-selinux-null-creds.patch
 
 #
 # PCI
@@ -2073,6 +2073,9 @@ fi
 # and build.
 
 %changelog
+* Mon Jun 29 2009 Chuck Ebbert <cebbert at redhat.com> 2.6.29.5-202
+- New debug patch for null selinux credentials (for bug #494067)
+
 * Mon Jun 26 2009 Ben Skeggs <bskeggs at redhat.com> 2.6.29.5-201
 - nouveau: bump timeout up a bit, some people hitting false hangs
 

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.3
retrieving revision 1.4
diff -u -p -r1.3 -r1.4
--- linux-2.6-debug-selinux-null-creds.patch	16 Jun 2009 19:05:14 -0000	1.3
+++ linux-2.6-debug-selinux-null-creds.patch	29 Jun 2009 17:52:54 -0000	1.4
@@ -19,19 +19,20 @@ credential struct has been previously re
 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 +--
+ fs/nfsd/vfs.c            |    2 
+ fs/open.c                |    2 
+ include/linux/cred.h     |   39 +++++++++
+ kernel/cred.c            |  192 +++++++++++++++++++++++++++++++++++++++++++++-
+ kernel/exit.c            |    4 +
+ kernel/fork.c            |    6 -
  kernel/kmod.c            |    1 
- lib/Kconfig.debug        |   15 ++++++
- security/selinux/hooks.c |    6 ++-
- 8 files changed, 162 insertions(+), 12 deletions(-)
+ lib/Kconfig.debug        |   15 ++++
+ security/selinux/hooks.c |    6 +
+ 9 files changed, 255 insertions(+), 12 deletions(-)
 
 
 diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
-index 99f8357..494e310 100644
+index 4145083..53f4eb0 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,
@@ -44,10 +45,10 @@ index 99f8357..494e310 100644
  	 * 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
+index dd98e80..1d31325 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,
+@@ -957,6 +957,8 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
  	int error;
  	struct file *f;
  
@@ -57,7 +58,7 @@ index 5c27f96..6069333 100644
  	 * 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
+index 4fa9996..5f39a20 100644
 --- a/include/linux/cred.h
 +++ b/include/linux/cred.h
 @@ -114,6 +114,9 @@ struct thread_group_cred {
@@ -78,7 +79,7 @@ index 4fa9996..2bdd6ce 100644
  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);
+@@ -157,6 +161,38 @@ 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);
@@ -105,15 +106,19 @@ index 4fa9996..2bdd6ce 100644
 +		__validate_creds((cred), __FILE__, __LINE__);	\
 +} while(0)
 +
++extern void validate_creds_for_do_exit(struct task_struct *);
 +#else
 +static inline void validate_creds(const struct cred *cred)
 +{
 +}
++static inline void validate_creds_for_do_exit(struct task_struct *tsk)
++{
++}
 +#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)
+@@ -186,6 +222,7 @@ static inline struct cred *get_new_cred(struct cred *cred)
   */
  static inline const struct cred *get_cred(const struct cred *cred)
  {
@@ -121,7 +126,7 @@ index 4fa9996..2bdd6ce 100644
  	return get_new_cred((struct cred *) cred);
  }
  
-@@ -204,7 +237,7 @@ static inline void put_cred(const struct cred *_cred)
+@@ -204,7 +241,7 @@ static inline void put_cred(const struct cred *_cred)
  {
  	struct cred *cred = (struct cred *) _cred;
  
@@ -131,10 +136,29 @@ index 4fa9996..2bdd6ce 100644
  		__put_cred(cred);
  }
 diff --git a/kernel/cred.c b/kernel/cred.c
-index 1bb4d7e..67f32cd 100644
+index 1bb4d7e..9b7b507 100644
 --- a/kernel/cred.c
 +++ b/kernel/cred.c
-@@ -36,6 +36,9 @@ static struct thread_group_cred init_tgcred = {
+@@ -18,6 +18,18 @@
+ #include <linux/cn_proc.h>
+ #include "cred-internals.h"
+ 
++#if 0
++#define kdebug(FMT, ...) \
++	printk(KERN_DEBUG "[%-5.5s%5u] " FMT "\n", current->comm, current->pid, ##__VA_ARGS__)
++#else
++static inline __attribute__((format(printf, 1, 2)))
++void no_printk(const char *fmt, ...)
++{
++}
++#define kdebug(FMT, ...) \
++	no_printk("[%-5.5s%5u] "FMT"\n", current->comm, current->pid, ##__VA_ARGS__)
++#endif
++
+ static struct kmem_cache *cred_jar;
+ 
+ /*
+@@ -36,6 +48,9 @@ static struct thread_group_cred init_tgcred = {
   */
  struct cred init_cred = {
  	.usage			= ATOMIC_INIT(4),
@@ -144,7 +168,7 @@ index 1bb4d7e..67f32cd 100644
  	.securebits		= SECUREBITS_DEFAULT,
  	.cap_inheritable	= CAP_INIT_INH_SET,
  	.cap_permitted		= CAP_FULL_SET,
-@@ -48,6 +51,22 @@ struct cred init_cred = {
+@@ -48,6 +63,22 @@ struct cred init_cred = {
  #endif
  };
  
@@ -167,10 +191,12 @@ index 1bb4d7e..67f32cd 100644
  /*
   * Dispose of the shared task group credentials
   */
-@@ -85,9 +104,17 @@ static void put_cred_rcu(struct rcu_head *rcu)
+@@ -85,9 +116,19 @@ static void put_cred_rcu(struct rcu_head *rcu)
  {
  	struct cred *cred = container_of(rcu, struct cred, rcu);
  
++	kdebug("put_cred_rcu(%p)", cred);
++
 +#ifdef CONFIG_DEBUG_CREDENTIALS
 +	if (atomic_read(&cred->usage) != 0 ||
 +	    atomic_read(&cred->subscribers) != 0)
@@ -185,13 +211,20 @@ index 1bb4d7e..67f32cd 100644
  
  	security_cred_free(cred);
  	key_put(cred->thread_keyring);
-@@ -107,11 +134,28 @@ static void put_cred_rcu(struct rcu_head *rcu)
+@@ -106,12 +147,45 @@ static void put_cred_rcu(struct rcu_head *rcu)
+  */
  void __put_cred(struct cred *cred)
  {
++	kdebug("__put_cred(%p{%d,%d})", cred,
++	       atomic_read(&cred->usage),
++	       atomic_read(&cred->subscribers));
++
  	BUG_ON(atomic_read(&cred->usage) != 0);
 +#ifdef CONFIG_DEBUG_CREDENTIALS
 +	BUG_ON(atomic_read(&cred->subscribers) != 0);
 +#endif
++	BUG_ON(cred == current->cred);
++	BUG_ON(cred == current->real_cred);
  
  	call_rcu(&cred->rcu, put_cred_rcu);
  }
@@ -202,19 +235,29 @@ index 1bb4d7e..67f32cd 100644
 + */
 +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);
++	struct cred *cred;
++
++	kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred,
++	       atomic_read(&tsk->cred->usage),
++	       atomic_read(&tsk->cred->subscribers));
++
++	cred = (struct cred *) tsk->real_cred;
++	tsk->real_cred = NULL;
++	validate_creds(cred);
++	alter_cred_subscribers(cred, -1);
++	put_cred(cred);
++
++	cred = (struct cred *) tsk->cred;
++	tsk->cred = NULL;
++	validate_creds(cred);
++	alter_cred_subscribers(cred, -1);
++	put_cred(cred);
 +}
 +
  /**
   * prepare_creds - Prepare a new set of credentials for modification
   *
-@@ -132,7 +176,17 @@ struct cred *prepare_creds(void)
+@@ -132,16 +206,29 @@ struct cred *prepare_creds(void)
  	const struct cred *old;
  	struct cred *new;
  
@@ -233,7 +276,11 @@ index 1bb4d7e..67f32cd 100644
  
  	new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
  	if (!new)
-@@ -142,6 +196,7 @@ struct cred *prepare_creds(void)
+ 		return NULL;
+ 
++	kdebug("prepare_creds() alloc %p", new);
++
+ 	old = task->cred;
  	memcpy(new, old, sizeof(struct cred));
  
  	atomic_set(&new->usage, 1);
@@ -241,7 +288,7 @@ index 1bb4d7e..67f32cd 100644
  	get_group_info(new->group_info);
  	get_uid(new->user);
  
-@@ -157,6 +212,7 @@ struct cred *prepare_creds(void)
+@@ -157,6 +244,7 @@ struct cred *prepare_creds(void)
  
  	if (security_prepare_creds(new, old, GFP_KERNEL) < 0)
  		goto error;
@@ -249,7 +296,12 @@ index 1bb4d7e..67f32cd 100644
  	return new;
  
  error:
-@@ -232,6 +288,7 @@ struct cred *prepare_usermodehelper_creds(void)
+@@ -229,9 +317,12 @@ struct cred *prepare_usermodehelper_creds(void)
+ 	if (!new)
+ 		return NULL;
+ 
++	kdebug("prepare_usermodehelper_creds() alloc %p", new);
++
  	memcpy(new, &init_cred, sizeof(struct cred));
  
  	atomic_set(&new->usage, 1);
@@ -257,7 +309,7 @@ index 1bb4d7e..67f32cd 100644
  	get_group_info(new->group_info);
  	get_uid(new->user);
  
-@@ -250,6 +307,7 @@ struct cred *prepare_usermodehelper_creds(void)
+@@ -250,6 +341,7 @@ struct cred *prepare_usermodehelper_creds(void)
  #endif
  	if (security_prepare_creds(new, &init_cred, GFP_ATOMIC) < 0)
  		goto error;
@@ -265,7 +317,18 @@ index 1bb4d7e..67f32cd 100644
  
  	BUG_ON(atomic_read(&new->usage) != 1);
  	return new;
-@@ -330,7 +388,9 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
+@@ -286,6 +378,10 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
+ 	    ) {
+ 		p->real_cred = get_cred(p->cred);
+ 		get_cred(p->cred);
++		alter_cred_subscribers(p->cred, 2);
++		kdebug("share_creds(%p{%d,%d})", p->cred,
++		       atomic_read(&p->cred->usage),
++		       atomic_read(&p->cred->subscribers));
+ 		atomic_inc(&p->cred->user->processes);
+ 		return 0;
+ 	}
+@@ -330,7 +426,9 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
  #endif
  
  	atomic_inc(&new->user->processes);
@@ -275,7 +338,7 @@ index 1bb4d7e..67f32cd 100644
  	return 0;
  
  error_put:
-@@ -355,13 +415,16 @@ error_put:
+@@ -355,13 +453,20 @@ error_put:
  int commit_creds(struct cred *new)
  {
  	struct task_struct *task = current;
@@ -284,6 +347,10 @@ index 1bb4d7e..67f32cd 100644
  
 -	BUG_ON(task->cred != task->real_cred);
 -	BUG_ON(atomic_read(&task->real_cred->usage) < 2);
++	kdebug("commit_creds(%p{%d,%d})", new,
++	       atomic_read(&new->usage),
++	       atomic_read(&new->subscribers));
++
 +	BUG_ON(task->cred != old);
 +#ifdef CONFIG_DEBUG_CREDENTIALS
 +	BUG_ON(atomic_read(&old->subscribers) < 2);
@@ -296,7 +363,7 @@ index 1bb4d7e..67f32cd 100644
  	security_commit_creds(new, old);
  
  	get_cred(new); /* we will require a ref for the subj creds too */
-@@ -390,12 +453,14 @@ int commit_creds(struct cred *new)
+@@ -390,12 +495,14 @@ int commit_creds(struct cred *new)
  	 *   cheaply with the new uid cache, so if it matters
  	 *   we should be checking for it.  -DaveM
  	 */
@@ -311,34 +378,50 @@ index 1bb4d7e..67f32cd 100644
  
  	sched_switch_user(task);
  
-@@ -428,6 +493,9 @@ EXPORT_SYMBOL(commit_creds);
+@@ -428,6 +535,13 @@ EXPORT_SYMBOL(commit_creds);
   */
  void abort_creds(struct cred *new)
  {
++	kdebug("abort_creds(%p{%d,%d})", new,
++	       atomic_read(&new->usage),
++	       atomic_read(&new->subscribers));
++
 +#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)
+@@ -444,7 +558,20 @@ const struct cred *override_creds(const struct cred *new)
  {
  	const struct cred *old = current->cred;
  
 -	rcu_assign_pointer(current->cred, get_cred(new));
++	kdebug("override_creds(%p{%d,%d})", new,
++	       atomic_read(&new->usage),
++	       atomic_read(&new->subscribers));
++
 +	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);
++
++	kdebug("override_creds() = %p{%d,%d}", old,
++	       atomic_read(&old->usage),
++	       atomic_read(&old->subscribers));
  	return old;
  }
  EXPORT_SYMBOL(override_creds);
-@@ -460,7 +533,11 @@ void revert_creds(const struct cred *old)
+@@ -460,7 +587,15 @@ void revert_creds(const struct cred *old)
  {
  	const struct cred *override = current->cred;
  
++	kdebug("revert_creds(%p{%d,%d})", old,
++	       atomic_read(&old->usage),
++	       atomic_read(&old->subscribers));
++
 +	validate_creds(old);
 +	validate_creds(override);
 +	alter_cred_subscribers(old, 1);
@@ -347,7 +430,14 @@ index 1bb4d7e..67f32cd 100644
  	put_cred(override);
  }
  EXPORT_SYMBOL(revert_creds);
-@@ -507,6 +584,8 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
+@@ -502,11 +637,15 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
+ 	if (!new)
+ 		return NULL;
+ 
++	kdebug("prepare_kernel_cred() alloc %p", new);
++
+ 	if (daemon)
+ 		old = get_task_cred(daemon);
  	else
  		old = get_cred(&init_cred);
  
@@ -356,7 +446,7 @@ index 1bb4d7e..67f32cd 100644
  	*new = *old;
  	get_uid(new->user);
  	get_group_info(new->group_info);
-@@ -526,7 +605,9 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
+@@ -526,7 +665,9 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
  		goto error;
  
  	atomic_set(&new->usage, 1);
@@ -366,7 +456,7 @@ index 1bb4d7e..67f32cd 100644
  	return new;
  
  error:
-@@ -589,3 +670,17 @@ int set_create_files_as(struct cred *new, struct inode *inode)
+@@ -589,3 +730,42 @@ 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);
@@ -374,6 +464,7 @@ index 1bb4d7e..67f32cd 100644
 +/*
 + * report use of invalid credentials
 + */
++#ifdef CONFIG_DEBUG_CREDENTIALS
 +void __validate_creds(const struct cred *cred, const char *file, unsigned line)
 +{
 +#ifdef CONFIG_SECURITY_SELINUX
@@ -384,8 +475,54 @@ index 1bb4d7e..67f32cd 100644
 +#endif
 +}
 +EXPORT_SYMBOL(__validate_creds);
++#endif
++
++/*
++ * check creds for do_exit()
++ */
++#ifdef CONFIG_DEBUG_CREDENTIALS
++void validate_creds_for_do_exit(struct task_struct *tsk)
++{
++	kdebug("validate_creds_for_do_exit(%p,%p{%d,%d})",
++	       tsk->real_cred, tsk->cred,
++	       atomic_read(&tsk->cred->usage),
++	       atomic_read(&tsk->cred->subscribers));
++
++	if ((tsk)->cred == (tsk)->real_cred) {
++		BUG_ON(atomic_read(&(tsk)->cred->subscribers) < 2);
++		validate_creds((tsk)->cred);
++	} else {
++		BUG_ON(atomic_read(&(tsk)->real_cred->subscribers) >= 1);
++		validate_creds((tsk)->real_cred);
++		BUG_ON(atomic_read(&(tsk)->cred->subscribers) < 1);
++		validate_creds((tsk)->cred);
++	}
++}
++#endif
+diff --git a/kernel/exit.c b/kernel/exit.c
+index 628d41f..e0df531 100644
+--- a/kernel/exit.c
++++ b/kernel/exit.c
+@@ -902,6 +902,8 @@ NORET_TYPE void do_exit(long code)
+ 
+ 	tracehook_report_exit(&code);
+ 
++	validate_creds_for_do_exit(tsk);
++
+ 	/*
+ 	 * We're taking recursive faults here in do_exit. Safest is to just
+ 	 * leave this task alone and wait for reboot.
+@@ -1010,6 +1012,8 @@ NORET_TYPE void do_exit(long code)
+ 	if (tsk->splice_pipe)
+ 		__free_pipe_info(tsk->splice_pipe);
+ 
++	validate_creds_for_do_exit(tsk);
++
+ 	preempt_disable();
+ 	/* causes final put_task_struct in finish_task_switch(). */
+ 	tsk->state = TASK_DEAD;
 diff --git a/kernel/fork.c b/kernel/fork.c
-index 4430eb1..7cb5612 100644
+index 467746b..fae2527 100644
 --- a/kernel/fork.c
 +++ b/kernel/fork.c
 @@ -153,8 +153,7 @@ void __put_task_struct(struct task_struct *tsk)
@@ -398,7 +535,7 @@ index 4430eb1..7cb5612 100644
  	delayacct_tsk_free(tsk);
  
  	if (!profile_handoff_task(tsk))
-@@ -1308,8 +1307,7 @@ bad_fork_cleanup_put_domain:
+@@ -1307,8 +1306,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);
@@ -421,10 +558,10 @@ index 7e95bed..f9b597f 100644
  	helper_lock();
  	if (sub_info->path[0] == '\0')
 diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
-index 2d32cdf..a185231 100644
+index 4c32b1a..244c3d8 100644
 --- a/lib/Kconfig.debug
 +++ b/lib/Kconfig.debug
-@@ -650,6 +650,21 @@ config DEBUG_NOTIFIERS
+@@ -641,6 +641,21 @@ config DEBUG_NOTIFIERS
  	  This is a relatively cheap check but if you care about maximum
  	  performance, say N.
  




More information about the fedora-extras-commits mailing list