From a4789adb03fc9fb271f4c70906467ac2b92bf8ed Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Sep 15 2010 03:58:35 +0000 Subject: 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 --- 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 +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 +Cc: +Signed-off-by: Takashi Iwai +--- + +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 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 - Mitigate DOS with large argument lists. * Tue Sep 14 2010 Kyle McMartin 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 +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: [] keyctl_session_to_parent+0x251/0x443 + ... + Call Trace: + [] ? keyctl_session_to_parent+0x67/0x443 + [] ? __do_fault+0x24b/0x3d0 + [] sys_keyctl+0xb4/0xb8 + [] 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 +Signed-off-by: David Howells +Acked-by: Tavis Ormandy +Signed-off-by: Linus Torvalds +--- + +[ 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 +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: [] keyctl_session_to_parent+0x60/0x236 + + stack backtrace: + Pid: 2137, comm: keyctl-session- Not tainted 2.6.36-rc2-cachefs+ #1 + Call Trace: + [] lockdep_rcu_dereference+0xaa/0xb3 + [] keyctl_session_to_parent+0xed/0x236 + [] sys_keyctl+0xb4/0xb6 + [] 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 +Signed-off-by: Linus Torvalds +--- + +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 +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 +Cc: Chris Wright +Cc: Tavis Ormandy +Cc: Eugene Teo +Cc: vendor-sec@lst.de +Cc: +Signed-off-by: Steven Rostedt +--- + +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, + }; +