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