summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Ebbert <cebbert@redhat.com>2010-09-14 23:58:35 -0400
committerChuck Ebbert <cebbert@redhat.com>2010-09-14 23:58:35 -0400
commita4789adb03fc9fb271f4c70906467ac2b92bf8ed (patch)
tree5cac2fc742b7e9d9eadca7736abe6456b3cfb137
parent463440bed26968abc08d54576d7dcf878236a519 (diff)
downloaddom0-kernel-a4789adb03fc9fb271f4c70906467ac2b92bf8ed.tar.gz
dom0-kernel-a4789adb03fc9fb271f4c70906467ac2b92bf8ed.tar.xz
dom0-kernel-a4789adb03fc9fb271f4c70906467ac2b92bf8ed.zip
Fix three CVEs:
CVE-2010-3080: /dev/sequencer open failure is not handled correctly CVE-2010-2960: keyctl_session_to_parent NULL deref system crash CVE-2010-3079: ftrace NULL pointer dereference
-rw-r--r--alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch53
-rw-r--r--kernel.spec22
-rw-r--r--keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch52
-rw-r--r--keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch64
-rw-r--r--tracing-do-not-allow-llseek-to-set_ftrace_filter.patch51
5 files changed, 242 insertions, 0 deletions
diff --git a/alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch b/alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
new file mode 100644
index 0000000..73e65ec
--- /dev/null
+++ b/alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
@@ -0,0 +1,53 @@
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 6 Sep 2010 07:13:45 +0000 (+0200)
+Subject: ALSA: seq/oss - Fix double-free at error path of snd_seq_oss_open()
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=27f7ad53829f79e799a253285318bff79ece15bd
+
+ALSA: seq/oss - Fix double-free at error path of snd_seq_oss_open()
+
+The error handling in snd_seq_oss_open() has several bad codes that
+do dereferecing released pointers and double-free of kmalloc'ed data.
+The object dp is release in free_devinfo() that is called via
+private_free callback. The rest shouldn't touch this object any more.
+
+The patch changes delete_port() to call kfree() in any case, and gets
+rid of unnecessary calls of destructors in snd_seq_oss_open().
+
+Fixes CVE-2010-3080.
+
+Reported-and-tested-by: Tavis Ormandy <taviso@cmpxchg8b.com>
+Cc: <stable@kernel.org>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+---
+
+diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
+index 6857122..69cd7b3 100644
+--- a/sound/core/seq/oss/seq_oss_init.c
++++ b/sound/core/seq/oss/seq_oss_init.c
+@@ -281,13 +281,10 @@ snd_seq_oss_open(struct file *file, int level)
+ return 0;
+
+ _error:
+- snd_seq_oss_writeq_delete(dp->writeq);
+- snd_seq_oss_readq_delete(dp->readq);
+ snd_seq_oss_synth_cleanup(dp);
+ snd_seq_oss_midi_cleanup(dp);
+- delete_port(dp);
+ delete_seq_queue(dp->queue);
+- kfree(dp);
++ delete_port(dp);
+
+ return rc;
+ }
+@@ -350,8 +347,10 @@ create_port(struct seq_oss_devinfo *dp)
+ static int
+ delete_port(struct seq_oss_devinfo *dp)
+ {
+- if (dp->port < 0)
++ if (dp->port < 0) {
++ kfree(dp);
+ return 0;
++ }
+
+ debug_printk(("delete_port %i\n", dp->port));
+ return snd_seq_event_port_detach(dp->cseq, dp->port);
diff --git a/kernel.spec b/kernel.spec
index 5bcb905..a7b0070 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -852,6 +852,14 @@ Patch14210: execve-improve-interactivity-with-large-arguments.patch
Patch14211: execve-make-responsive-to-sigkill-with-large-arguments.patch
Patch14212: setup_arg_pages-diagnose-excessive-argument-size.patch
+# CVE-2010-3080
+Patch14220: alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
+# CVE-2010-2960
+Patch14230: keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
+Patch14231: keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
+# CVE-2010-3079
+Patch14240: tracing-do-not-allow-llseek-to-set_ftrace_filter.patch
+
# ==============================================================================
%endif
@@ -1576,6 +1584,14 @@ ApplyPatch execve-improve-interactivity-with-large-arguments.patch
ApplyPatch execve-make-responsive-to-sigkill-with-large-arguments.patch
ApplyPatch setup_arg_pages-diagnose-excessive-argument-size.patch
+# CVE-2010-3080
+ApplyPatch alsa-seq-oss-fix-double-free-at-error-path-of-snd_seq_oss_open.patch
+# CVE-2010-2960
+ApplyPatch keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
+ApplyPatch keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
+# CVE-2010-3079
+ApplyPatch tracing-do-not-allow-llseek-to-set_ftrace_filter.patch
+
# END OF PATCH APPLICATIONS ====================================================
%endif
@@ -2229,6 +2245,12 @@ fi
%changelog
* Tue Sep 14 2010 Chuck Ebbert <cebbert@redhat.com> 2.6.32.21-168
+- Fix three CVEs:
+ CVE-2010-3080: /dev/sequencer open failure is not handled correctly
+ CVE-2010-2960: keyctl_session_to_parent NULL deref system crash
+ CVE-2010-3079: ftrace NULL pointer dereference
+
+* Tue Sep 14 2010 Chuck Ebbert <cebbert@redhat.com>
- Mitigate DOS with large argument lists.
* Tue Sep 14 2010 Kyle McMartin <kyle@redhat.com>
diff --git a/keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch b/keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
new file mode 100644
index 0000000..fb62519
--- /dev/null
+++ b/keys-fix-bug-in-keyctl_session_to_parent-if-parent-has-no-session-keyring.patch
@@ -0,0 +1,52 @@
+From: David Howells <dhowells@redhat.com>
+Date: Fri, 10 Sep 2010 08:59:51 +0000 (+0100)
+Subject: KEYS: Fix bug in keyctl_session_to_parent() if parent has no session keyring
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=3d96406c7da1ed5811ea52a3b0905f4f0e295376
+
+KEYS: Fix bug in keyctl_session_to_parent() if parent has no session keyring
+
+Fix a bug in keyctl_session_to_parent() whereby it tries to check the ownership
+of the parent process's session keyring whether or not the parent has a session
+keyring [CVE-2010-2960].
+
+This results in the following oops:
+
+ BUG: unable to handle kernel NULL pointer dereference at 00000000000000a0
+ IP: [<ffffffff811ae4dd>] keyctl_session_to_parent+0x251/0x443
+ ...
+ Call Trace:
+ [<ffffffff811ae2f3>] ? keyctl_session_to_parent+0x67/0x443
+ [<ffffffff8109d286>] ? __do_fault+0x24b/0x3d0
+ [<ffffffff811af98c>] sys_keyctl+0xb4/0xb8
+ [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b
+
+if the parent process has no session keyring.
+
+If the system is using pam_keyinit then it mostly protected against this as all
+processes derived from a login will have inherited the session keyring created
+by pam_keyinit during the log in procedure.
+
+To test this, pam_keyinit calls need to be commented out in /etc/pam.d/.
+
+Reported-by: Tavis Ormandy <taviso@cmpxchg8b.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Tavis Ormandy <taviso@cmpxchg8b.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+[ 2.6.32 backport ]
+
+diff a/security/keys/keyctl.c b/security/keys/keyctl.c
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -1291,7 +1291,8 @@ long keyctl_session_to_parent(void)
+ goto not_permitted;
+
+ /* the keyrings must have the same UID */
+- if (pcred ->tgcred->session_keyring->uid != mycred->euid ||
++ if ((pcred->tgcred->session_keyring &&
++ pcred->tgcred->session_keyring->uid != mycred->euid) ||
+ mycred->tgcred->session_keyring->uid != mycred->euid)
+ goto not_permitted;
+
+
diff --git a/keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch b/keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
new file mode 100644
index 0000000..5318f7e
--- /dev/null
+++ b/keys-fix-rcu-no-lock-warning-in-keyctl_session_to_parent.patch
@@ -0,0 +1,64 @@
+From: David Howells <dhowells@redhat.com>
+Date: Fri, 10 Sep 2010 08:59:46 +0000 (+0100)
+Subject: KEYS: Fix RCU no-lock warning in keyctl_session_to_parent()
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9d1ac65a9698513d00e5608d93fca0c53f536c14
+
+KEYS: Fix RCU no-lock warning in keyctl_session_to_parent()
+
+There's an protected access to the parent process's credentials in the middle
+of keyctl_session_to_parent(). This results in the following RCU warning:
+
+ ===================================================
+ [ INFO: suspicious rcu_dereference_check() usage. ]
+ ---------------------------------------------------
+ security/keys/keyctl.c:1291 invoked rcu_dereference_check() without protection!
+
+ other info that might help us debug this:
+
+ rcu_scheduler_active = 1, debug_locks = 0
+ 1 lock held by keyctl-session-/2137:
+ #0: (tasklist_lock){.+.+..}, at: [<ffffffff811ae2ec>] keyctl_session_to_parent+0x60/0x236
+
+ stack backtrace:
+ Pid: 2137, comm: keyctl-session- Not tainted 2.6.36-rc2-cachefs+ #1
+ Call Trace:
+ [<ffffffff8105606a>] lockdep_rcu_dereference+0xaa/0xb3
+ [<ffffffff811ae379>] keyctl_session_to_parent+0xed/0x236
+ [<ffffffff811af77e>] sys_keyctl+0xb4/0xb6
+ [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b
+
+The code should take the RCU read lock to make sure the parents credentials
+don't go away, even though it's holding a spinlock and has IRQ disabled.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
+index b2b0998..3868c67 100644
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -1272,6 +1272,7 @@ long keyctl_session_to_parent(void)
+ keyring_r = NULL;
+
+ me = current;
++ rcu_read_lock();
+ write_lock_irq(&tasklist_lock);
+
+ parent = me->real_parent;
+@@ -1319,6 +1320,7 @@ long keyctl_session_to_parent(void)
+ set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME);
+
+ write_unlock_irq(&tasklist_lock);
++ rcu_read_unlock();
+ if (oldcred)
+ put_cred(oldcred);
+ return 0;
+@@ -1327,6 +1329,7 @@ already_same:
+ ret = 0;
+ not_permitted:
+ write_unlock_irq(&tasklist_lock);
++ rcu_read_unlock();
+ put_cred(cred);
+ return ret;
+
diff --git a/tracing-do-not-allow-llseek-to-set_ftrace_filter.patch b/tracing-do-not-allow-llseek-to-set_ftrace_filter.patch
new file mode 100644
index 0000000..4bbae71
--- /dev/null
+++ b/tracing-do-not-allow-llseek-to-set_ftrace_filter.patch
@@ -0,0 +1,51 @@
+From: Steven Rostedt <srostedt@redhat.com>
+Date: Wed, 8 Sep 2010 15:20:37 +0000 (-0400)
+Subject: tracing: Do not allow llseek to set_ftrace_filter
+X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=9c55cb12c1c172e2d51e85fbb5a4796ca86b77e7
+
+tracing: Do not allow llseek to set_ftrace_filter
+
+Reading the file set_ftrace_filter does three things.
+
+1) shows whether or not filters are set for the function tracer
+2) shows what functions are set for the function tracer
+3) shows what triggers are set on any functions
+
+3 is independent from 1 and 2.
+
+The way this file currently works is that it is a state machine,
+and as you read it, it may change state. But this assumption breaks
+when you use lseek() on the file. The state machine gets out of sync
+and the t_show() may use the wrong pointer and cause a kernel oops.
+
+Luckily, this will only kill the app that does the lseek, but the app
+dies while holding a mutex. This prevents anyone else from using the
+set_ftrace_filter file (or any other function tracing file for that matter).
+
+A real fix for this is to rewrite the code, but that is too much for
+a -rc release or stable. This patch simply disables llseek on the
+set_ftrace_filter() file for now, and we can do the proper fix for the
+next major release.
+
+Reported-by: Robert Swiecki <swiecki@google.com>
+Cc: Chris Wright <chrisw@sous-sol.org>
+Cc: Tavis Ormandy <taviso@google.com>
+Cc: Eugene Teo <eugene@redhat.com>
+Cc: vendor-sec@lst.de
+Cc: <stable@kernel.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+---
+
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 7cb1f45..83a16e9 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -2416,7 +2416,7 @@ static const struct file_operations ftrace_filter_fops = {
+ .open = ftrace_filter_open,
+ .read = seq_read,
+ .write = ftrace_filter_write,
+- .llseek = ftrace_regex_lseek,
++ .llseek = no_llseek,
+ .release = ftrace_filter_release,
+ };
+