From 2efb36a4f80e51f850ad09a7dc63c6f6226b3181 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 16 Jan 2012 11:34:50 -0800 Subject: [PATCH] 3.2-stable patches added patches: fsnotify-don-t-bug-in-fsnotify_destroy_mark.patch ftrace-fix-unregister-ftrace_ops-accounting.patch kconfig-streamline-config.pl-fix-parsing-makefile-with-variables.patch kconfig-streamline-config.pl-simplify-backslash-line-concatination.patch nfsd4-fix-lockowner-matching.patch nfsd-fix-oops-when-parsing-a-0-length-export.patch recordmcount-fix-handling-of-elf64-big-endian-objects.patch svcrpc-avoid-memory-corruption-on-pool-shutdown.patch svcrpc-destroy-server-sockets-all-at-once.patch svcrpc-fix-double-free-on-shutdown-of-nfsd-after-changing-pool-mode.patch unused-iocbs-in-a-batch-should-not-be-accounted-as-active.patch uvcvideo-fix-integer-overflow-in-uvc_ioctl_ctrl_map.patch v4l-dvb-v4l2-ioctl-integer-overflow-in-video_usercopy.patch x86-uv-update-boot-messages-for-sgi-uv2-platform.patch --- ...y-don-t-bug-in-fsnotify_destroy_mark.patch | 59 +++++ ...fix-unregister-ftrace_ops-accounting.patch | 225 ++++++++++++++++++ ...-fix-parsing-makefile-with-variables.patch | 95 ++++++++ ...implify-backslash-line-concatination.patch | 65 +++++ ...-oops-when-parsing-a-0-length-export.patch | 80 +++++++ queue-3.2/nfsd4-fix-lockowner-matching.patch | 57 +++++ ...handling-of-elf64-big-endian-objects.patch | 43 ++++ queue-3.2/series | 14 ++ ...d-memory-corruption-on-pool-shutdown.patch | 152 ++++++++++++ ...c-destroy-server-sockets-all-at-once.patch | 79 ++++++ ...own-of-nfsd-after-changing-pool-mode.patch | 57 +++++ ...ch-should-not-be-accounted-as-active.patch | 68 ++++++ ...teger-overflow-in-uvc_ioctl_ctrl_map.patch | 57 +++++ ...l-integer-overflow-in-video_usercopy.patch | 49 ++++ ...e-boot-messages-for-sgi-uv2-platform.patch | 42 ++++ 15 files changed, 1142 insertions(+) create mode 100644 queue-3.2/fsnotify-don-t-bug-in-fsnotify_destroy_mark.patch create mode 100644 queue-3.2/ftrace-fix-unregister-ftrace_ops-accounting.patch create mode 100644 queue-3.2/kconfig-streamline-config.pl-fix-parsing-makefile-with-variables.patch create mode 100644 queue-3.2/kconfig-streamline-config.pl-simplify-backslash-line-concatination.patch create mode 100644 queue-3.2/nfsd-fix-oops-when-parsing-a-0-length-export.patch create mode 100644 queue-3.2/nfsd4-fix-lockowner-matching.patch create mode 100644 queue-3.2/recordmcount-fix-handling-of-elf64-big-endian-objects.patch create mode 100644 queue-3.2/svcrpc-avoid-memory-corruption-on-pool-shutdown.patch create mode 100644 queue-3.2/svcrpc-destroy-server-sockets-all-at-once.patch create mode 100644 queue-3.2/svcrpc-fix-double-free-on-shutdown-of-nfsd-after-changing-pool-mode.patch create mode 100644 queue-3.2/unused-iocbs-in-a-batch-should-not-be-accounted-as-active.patch create mode 100644 queue-3.2/uvcvideo-fix-integer-overflow-in-uvc_ioctl_ctrl_map.patch create mode 100644 queue-3.2/v4l-dvb-v4l2-ioctl-integer-overflow-in-video_usercopy.patch create mode 100644 queue-3.2/x86-uv-update-boot-messages-for-sgi-uv2-platform.patch diff --git a/queue-3.2/fsnotify-don-t-bug-in-fsnotify_destroy_mark.patch b/queue-3.2/fsnotify-don-t-bug-in-fsnotify_destroy_mark.patch new file mode 100644 index 00000000000..2a2ee769a24 --- /dev/null +++ b/queue-3.2/fsnotify-don-t-bug-in-fsnotify_destroy_mark.patch @@ -0,0 +1,59 @@ +From fed474857efbed79cd390d0aee224231ca718f63 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Thu, 12 Jan 2012 17:59:46 +0100 +Subject: fsnotify: don't BUG in fsnotify_destroy_mark() + +From: Miklos Szeredi + +commit fed474857efbed79cd390d0aee224231ca718f63 upstream. + +Removing the parent of a watched file results in "kernel BUG at +fs/notify/mark.c:139". + +To reproduce + + add "-w /tmp/audit/dir/watched_file" to audit.rules + rm -rf /tmp/audit/dir + +This is caused by fsnotify_destroy_mark() being called without an +extra reference taken by the caller. + +Reported by Francesco Cosoleto here: + + https://bugzilla.novell.com/show_bug.cgi?id=689860 + +Fix by removing the BUG_ON and adding a comment about not accessing mark after +the iput. + +Signed-off-by: Miklos Szeredi +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/notify/mark.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/fs/notify/mark.c ++++ b/fs/notify/mark.c +@@ -135,9 +135,6 @@ void fsnotify_destroy_mark(struct fsnoti + + mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE; + +- /* 1 from caller and 1 for being on i_list/g_list */ +- BUG_ON(atomic_read(&mark->refcnt) < 2); +- + spin_lock(&group->mark_lock); + + if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) { +@@ -182,6 +179,11 @@ void fsnotify_destroy_mark(struct fsnoti + iput(inode); + + /* ++ * We don't necessarily have a ref on mark from caller so the above iput ++ * may have already destroyed it. Don't touch from now on. ++ */ ++ ++ /* + * it's possible that this group tried to destroy itself, but this + * this mark was simultaneously being freed by inode. If that's the + * case, we finish freeing the group here. diff --git a/queue-3.2/ftrace-fix-unregister-ftrace_ops-accounting.patch b/queue-3.2/ftrace-fix-unregister-ftrace_ops-accounting.patch new file mode 100644 index 00000000000..fc578a15824 --- /dev/null +++ b/queue-3.2/ftrace-fix-unregister-ftrace_ops-accounting.patch @@ -0,0 +1,225 @@ +From 30fb6aa74011dcf595f306ca2727254d708b786e Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Mon, 5 Dec 2011 18:22:48 +0100 +Subject: ftrace: Fix unregister ftrace_ops accounting + +From: Jiri Olsa + +commit 30fb6aa74011dcf595f306ca2727254d708b786e upstream. + +Multiple users of the function tracer can register their functions +with the ftrace_ops structure. The accounting within ftrace will +update the counter on each function record that is being traced. +When the ftrace_ops filtering adds or removes functions, the +function records will be updated accordingly if the ftrace_ops is +still registered. + +When a ftrace_ops is removed, the counter of the function records, +that the ftrace_ops traces, are decremented. When they reach zero +the functions that they represent are modified to stop calling the +mcount code. + +When changes are made, the code is updated via stop_machine() with +a command passed to the function to tell it what to do. There is an +ENABLE and DISABLE command that tells the called function to enable +or disable the functions. But the ENABLE is really a misnomer as it +should just update the records, as records that have been enabled +and now have a count of zero should be disabled. + +The DISABLE command is used to disable all functions regardless of +their counter values. This is the big off switch and is not the +complement of the ENABLE command. + +To make matters worse, when a ftrace_ops is unregistered and there +is another ftrace_ops registered, neither the DISABLE nor the +ENABLE command are set when calling into the stop_machine() function +and the records will not be updated to match their counter. A command +is passed to that function that will update the mcount code to call +the registered callback directly if it is the only one left. This +means that the ftrace_ops that is still registered will have its callback +called by all functions that have been set for it as well as the ftrace_ops +that was just unregistered. + +Here's a way to trigger this bug. Compile the kernel with +CONFIG_FUNCTION_PROFILER set and with CONFIG_FUNCTION_GRAPH not set: + + CONFIG_FUNCTION_PROFILER=y + # CONFIG_FUNCTION_GRAPH is not set + +This will force the function profiler to use the function tracer instead +of the function graph tracer. + + # cd /sys/kernel/debug/tracing + # echo schedule > set_ftrace_filter + # echo function > current_tracer + # cat set_ftrace_filter + schedule + # cat trace + # tracer: nop + # + # entries-in-buffer/entries-written: 692/68108025 #P:4 + # + # _-----=> irqs-off + # / _----=> need-resched + # | / _---=> hardirq/softirq + # || / _--=> preempt-depth + # ||| / delay + # TASK-PID CPU# |||| TIMESTAMP FUNCTION + # | | | |||| | | + kworker/0:2-909 [000] .... 531.235574: schedule <-worker_thread + -0 [001] .N.. 531.235575: schedule <-cpu_idle + kworker/0:2-909 [000] .... 531.235597: schedule <-worker_thread + sshd-2563 [001] .... 531.235647: schedule <-schedule_hrtimeout_range_clock + + # echo 1 > function_profile_enabled + # echo 0 > function_porfile_enabled + # cat set_ftrace_filter + schedule + # cat trace + # tracer: function + # + # entries-in-buffer/entries-written: 159701/118821262 #P:4 + # + # _-----=> irqs-off + # / _----=> need-resched + # | / _---=> hardirq/softirq + # || / _--=> preempt-depth + # ||| / delay + # TASK-PID CPU# |||| TIMESTAMP FUNCTION + # | | | |||| | | + -0 [002] ...1 604.870655: local_touch_nmi <-cpu_idle + -0 [002] d..1 604.870655: enter_idle <-cpu_idle + -0 [002] d..1 604.870656: atomic_notifier_call_chain <-enter_idle + -0 [002] d..1 604.870656: __atomic_notifier_call_chain <-atomic_notifier_call_chain + +The same problem could have happened with the trace_probe_ops, +but they are modified with the set_frace_filter file which does the +update at closure of the file. + +The simple solution is to change ENABLE to UPDATE and call it every +time an ftrace_ops is unregistered. + +Link: http://lkml.kernel.org/r/1323105776-26961-3-git-send-email-jolsa@redhat.com + +Signed-off-by: Jiri Olsa +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ftrace.c | 27 +++++++++++++-------------- + 1 file changed, 13 insertions(+), 14 deletions(-) + +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -948,7 +948,7 @@ struct ftrace_func_probe { + }; + + enum { +- FTRACE_ENABLE_CALLS = (1 << 0), ++ FTRACE_UPDATE_CALLS = (1 << 0), + FTRACE_DISABLE_CALLS = (1 << 1), + FTRACE_UPDATE_TRACE_FUNC = (1 << 2), + FTRACE_START_FUNC_RET = (1 << 3), +@@ -1519,7 +1519,7 @@ int ftrace_text_reserved(void *start, vo + + + static int +-__ftrace_replace_code(struct dyn_ftrace *rec, int enable) ++__ftrace_replace_code(struct dyn_ftrace *rec, int update) + { + unsigned long ftrace_addr; + unsigned long flag = 0UL; +@@ -1527,17 +1527,17 @@ __ftrace_replace_code(struct dyn_ftrace + ftrace_addr = (unsigned long)FTRACE_ADDR; + + /* +- * If we are enabling tracing: ++ * If we are updating calls: + * + * If the record has a ref count, then we need to enable it + * because someone is using it. + * + * Otherwise we make sure its disabled. + * +- * If we are disabling tracing, then disable all records that ++ * If we are disabling calls, then disable all records that + * are enabled. + */ +- if (enable && (rec->flags & ~FTRACE_FL_MASK)) ++ if (update && (rec->flags & ~FTRACE_FL_MASK)) + flag = FTRACE_FL_ENABLED; + + /* If the state of this record hasn't changed, then do nothing */ +@@ -1553,7 +1553,7 @@ __ftrace_replace_code(struct dyn_ftrace + return ftrace_make_nop(NULL, rec, ftrace_addr); + } + +-static void ftrace_replace_code(int enable) ++static void ftrace_replace_code(int update) + { + struct dyn_ftrace *rec; + struct ftrace_page *pg; +@@ -1567,7 +1567,7 @@ static void ftrace_replace_code(int enab + if (rec->flags & FTRACE_FL_FREE) + continue; + +- failed = __ftrace_replace_code(rec, enable); ++ failed = __ftrace_replace_code(rec, update); + if (failed) { + ftrace_bug(failed, rec->ip); + /* Stop processing */ +@@ -1623,7 +1623,7 @@ static int __ftrace_modify_code(void *da + */ + function_trace_stop++; + +- if (*command & FTRACE_ENABLE_CALLS) ++ if (*command & FTRACE_UPDATE_CALLS) + ftrace_replace_code(1); + else if (*command & FTRACE_DISABLE_CALLS) + ftrace_replace_code(0); +@@ -1691,7 +1691,7 @@ static int ftrace_startup(struct ftrace_ + return -ENODEV; + + ftrace_start_up++; +- command |= FTRACE_ENABLE_CALLS; ++ command |= FTRACE_UPDATE_CALLS; + + /* ops marked global share the filter hashes */ + if (ops->flags & FTRACE_OPS_FL_GLOBAL) { +@@ -1743,8 +1743,7 @@ static void ftrace_shutdown(struct ftrac + if (ops != &global_ops || !global_start_up) + ops->flags &= ~FTRACE_OPS_FL_ENABLED; + +- if (!ftrace_start_up) +- command |= FTRACE_DISABLE_CALLS; ++ command |= FTRACE_UPDATE_CALLS; + + if (saved_ftrace_func != ftrace_trace_function) { + saved_ftrace_func = ftrace_trace_function; +@@ -1766,7 +1765,7 @@ static void ftrace_startup_sysctl(void) + saved_ftrace_func = NULL; + /* ftrace_start_up is true if we want ftrace running */ + if (ftrace_start_up) +- ftrace_run_update_code(FTRACE_ENABLE_CALLS); ++ ftrace_run_update_code(FTRACE_UPDATE_CALLS); + } + + static void ftrace_shutdown_sysctl(void) +@@ -2919,7 +2918,7 @@ ftrace_set_regex(struct ftrace_ops *ops, + ret = ftrace_hash_move(ops, enable, orig_hash, hash); + if (!ret && ops->flags & FTRACE_OPS_FL_ENABLED + && ftrace_enabled) +- ftrace_run_update_code(FTRACE_ENABLE_CALLS); ++ ftrace_run_update_code(FTRACE_UPDATE_CALLS); + + mutex_unlock(&ftrace_lock); + +@@ -3107,7 +3106,7 @@ ftrace_regex_release(struct inode *inode + orig_hash, iter->hash); + if (!ret && (iter->ops->flags & FTRACE_OPS_FL_ENABLED) + && ftrace_enabled) +- ftrace_run_update_code(FTRACE_ENABLE_CALLS); ++ ftrace_run_update_code(FTRACE_UPDATE_CALLS); + + mutex_unlock(&ftrace_lock); + } diff --git a/queue-3.2/kconfig-streamline-config.pl-fix-parsing-makefile-with-variables.patch b/queue-3.2/kconfig-streamline-config.pl-fix-parsing-makefile-with-variables.patch new file mode 100644 index 00000000000..4d0f968d5d2 --- /dev/null +++ b/queue-3.2/kconfig-streamline-config.pl-fix-parsing-makefile-with-variables.patch @@ -0,0 +1,95 @@ +From 364212fddaaa60c5a64f67a0f5624ad996ecc8a0 Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Fri, 13 Jan 2012 17:53:40 -0500 +Subject: kconfig/streamline-config.pl: Fix parsing Makefile with variables + +From: Steven Rostedt + +commit 364212fddaaa60c5a64f67a0f5624ad996ecc8a0 upstream. + +Thomas Lange reported that when he did a 'make localmodconfig', his +config was missing the brcmsmac driver, even though he had the module +loaded. + +Looking into this, I found the file: +drivers/net/wireless/brcm80211/brcmsmac/Makefile +had the following in the Makefile: + +MODULEPFX := brcmsmac + +obj-$(CONFIG_BRCMSMAC) += $(MODULEPFX).o + +The way streamline-config.pl works, is parsing all the + obj-$(CONFIG_FOO) += foo.o +lines to find that CONFIG_FOO belongs to the module foo.ko. + +But in this case, the brcmsmac.o was not used, but a variable in its place. + +By changing streamline-config.pl to remember defined variables in Makefiles +and substituting them when they are used in the obj-X lines, allows +Thomas (and others) to have their brcmsmac module stay configured +when it is loaded and running "make localmodconfig". + +Reported-by: Thomas Lange +Tested-by: Thomas Lange +Cc: Arend van Spriel +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + scripts/kconfig/streamline_config.pl | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +--- a/scripts/kconfig/streamline_config.pl ++++ b/scripts/kconfig/streamline_config.pl +@@ -250,10 +250,33 @@ if ($kconfig) { + read_kconfig($kconfig); + } + ++sub convert_vars { ++ my ($line, %vars) = @_; ++ ++ my $process = ""; ++ ++ while ($line =~ s/^(.*?)(\$\((.*?)\))//) { ++ my $start = $1; ++ my $variable = $2; ++ my $var = $3; ++ ++ if (defined($vars{$var})) { ++ $process .= $start . $vars{$var}; ++ } else { ++ $process .= $start . $variable; ++ } ++ } ++ ++ $process .= $line; ++ ++ return $process; ++} ++ + # Read all Makefiles to map the configs to the objects + foreach my $makefile (@makefiles) { + + my $line = ""; ++ my %make_vars; + + open(MIN,$makefile) || die "Can't open $makefile"; + while () { +@@ -270,10 +293,16 @@ foreach my $makefile (@makefiles) { + + my $objs; + ++ $_ = convert_vars($_, %make_vars); ++ + # collect objects after obj-$(CONFIG_FOO_BAR) + if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) { + $var = $1; + $objs = $2; ++ ++ # check if variables are set ++ } elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) { ++ $make_vars{$1} = $2; + } + if (defined($objs)) { + foreach my $obj (split /\s+/,$objs) { diff --git a/queue-3.2/kconfig-streamline-config.pl-simplify-backslash-line-concatination.patch b/queue-3.2/kconfig-streamline-config.pl-simplify-backslash-line-concatination.patch new file mode 100644 index 00000000000..09d05cbd7c9 --- /dev/null +++ b/queue-3.2/kconfig-streamline-config.pl-simplify-backslash-line-concatination.patch @@ -0,0 +1,65 @@ +From d060d963e88f3e990cec2fe5214de49de9a49eca Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Fri, 13 Jan 2012 17:50:39 -0500 +Subject: kconfig/streamline-config.pl: Simplify backslash line concatination + +From: Steven Rostedt + +commit d060d963e88f3e990cec2fe5214de49de9a49eca upstream. + +Simplify the way lines ending with backslashes (continuation) in Makefiles +is parsed. This is needed to implement a necessary fix. + +Tested-by: Thomas Lange +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + scripts/kconfig/streamline_config.pl | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +--- a/scripts/kconfig/streamline_config.pl ++++ b/scripts/kconfig/streamline_config.pl +@@ -253,17 +253,22 @@ if ($kconfig) { + # Read all Makefiles to map the configs to the objects + foreach my $makefile (@makefiles) { + +- my $cont = 0; ++ my $line = ""; + + open(MIN,$makefile) || die "Can't open $makefile"; + while () { +- my $objs; +- +- # is this a line after a line with a backslash? +- if ($cont && /(\S.*)$/) { +- $objs = $1; ++ # if this line ends with a backslash, continue ++ chomp; ++ if (/^(.*)\\$/) { ++ $line .= $1; ++ next; + } +- $cont = 0; ++ ++ $line .= $_; ++ $_ = $line; ++ $line = ""; ++ ++ my $objs; + + # collect objects after obj-$(CONFIG_FOO_BAR) + if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) { +@@ -271,12 +276,6 @@ foreach my $makefile (@makefiles) { + $objs = $2; + } + if (defined($objs)) { +- # test if the line ends with a backslash +- if ($objs =~ m,(.*)\\$,) { +- $objs = $1; +- $cont = 1; +- } +- + foreach my $obj (split /\s+/,$objs) { + $obj =~ s/-/_/g; + if ($obj =~ /(.*)\.o$/) { diff --git a/queue-3.2/nfsd-fix-oops-when-parsing-a-0-length-export.patch b/queue-3.2/nfsd-fix-oops-when-parsing-a-0-length-export.patch new file mode 100644 index 00000000000..23770dc9c31 --- /dev/null +++ b/queue-3.2/nfsd-fix-oops-when-parsing-a-0-length-export.patch @@ -0,0 +1,80 @@ +From b2ea70afade7080360ac55c4e64ff7a5fafdb67b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 18 Nov 2011 12:14:49 +0200 +Subject: nfsd: Fix oops when parsing a 0 length export + +From: Sasha Levin + +commit b2ea70afade7080360ac55c4e64ff7a5fafdb67b upstream. + +expkey_parse() oopses when handling a 0 length export. This is easily +triggerable from usermode by writing 0 bytes into +'/proc/[proc id]/net/rpc/nfsd.fh/channel'. + +Below is the log: + +[ 1402.286893] BUG: unable to handle kernel paging request at ffff880077c49fff +[ 1402.287632] IP: [] expkey_parse+0x28/0x2e1 +[ 1402.287632] PGD 2206063 PUD 1fdfd067 PMD 1ffbc067 PTE 8000000077c49160 +[ 1402.287632] Oops: 0000 [#1] PREEMPT SMP DEBUG_PAGEALLOC +[ 1402.287632] CPU 1 +[ 1402.287632] Pid: 20198, comm: trinity Not tainted 3.2.0-rc2-sasha-00058-gc65cd37 #6 +[ 1402.287632] RIP: 0010:[] [] expkey_parse+0x28/0x2e1 +[ 1402.287632] RSP: 0018:ffff880077f0fd68 EFLAGS: 00010292 +[ 1402.287632] RAX: ffff880077c49fff RBX: 00000000ffffffea RCX: 0000000001043400 +[ 1402.287632] RDX: 0000000000000000 RSI: ffff880077c4a000 RDI: ffffffff82283de0 +[ 1402.287632] RBP: ffff880077f0fe18 R08: 0000000000000001 R09: ffff880000000000 +[ 1402.287632] R10: 0000000000000000 R11: 0000000000000001 R12: ffff880077c4a000 +[ 1402.287632] R13: ffffffff82283de0 R14: 0000000001043400 R15: ffffffff82283de0 +[ 1402.287632] FS: 00007f25fec3f700(0000) GS:ffff88007d400000(0000) knlGS:0000000000000000 +[ 1402.287632] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +[ 1402.287632] CR2: ffff880077c49fff CR3: 0000000077e1d000 CR4: 00000000000406e0 +[ 1402.287632] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[ 1402.287632] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +[ 1402.287632] Process trinity (pid: 20198, threadinfo ffff880077f0e000, task ffff880077db17b0) +[ 1402.287632] Stack: +[ 1402.287632] ffff880077db17b0 ffff880077c4a000 ffff880077f0fdb8 ffffffff810b411e +[ 1402.287632] ffff880000000000 ffff880077db17b0 ffff880077c4a000 ffffffff82283de0 +[ 1402.287632] 0000000001043400 ffffffff82283de0 ffff880077f0fde8 ffffffff81111f63 +[ 1402.287632] Call Trace: +[ 1402.287632] [] ? lock_release+0x1af/0x1bc +[ 1402.287632] [] ? might_fault+0x97/0x9e +[ 1402.287632] [] ? might_fault+0x4e/0x9e +[ 1402.287632] [] cache_do_downcall+0x3e/0x4f +[ 1402.287632] [] cache_write.clone.16+0xbb/0x130 +[ 1402.287632] [] ? cache_write_pipefs+0x1a/0x1a +[ 1402.287632] [] cache_write_procfs+0x19/0x1b +[ 1402.287632] [] proc_reg_write+0x8e/0xad +[ 1402.287632] [] vfs_write+0xaa/0xfd +[ 1402.287632] [] ? fget_light+0x35/0x9e +[ 1402.287632] [] sys_write+0x48/0x6f +[ 1402.287632] [] system_call_fastpath+0x16/0x1b +[ 1402.287632] Code: c0 c9 c3 55 48 63 d2 48 89 e5 48 8d 44 32 ff 41 57 41 56 41 55 41 54 53 bb ea ff ff ff 48 81 ec 88 00 00 00 48 89 b5 58 ff ff ff +[ 1402.287632] 38 0a 0f 85 89 02 00 00 c6 00 00 48 8b 3d 44 4a e5 01 48 85 +[ 1402.287632] RIP [] expkey_parse+0x28/0x2e1 +[ 1402.287632] RSP +[ 1402.287632] CR2: ffff880077c49fff +[ 1402.287632] ---[ end trace 368ef53ff773a5e3 ]--- + +Cc: "J. Bruce Fields" +Cc: Neil Brown +Cc: linux-nfs@vger.kernel.org +Signed-off-by: Sasha Levin +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/export.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfsd/export.c ++++ b/fs/nfsd/export.c +@@ -87,7 +87,7 @@ static int expkey_parse(struct cache_det + struct svc_expkey key; + struct svc_expkey *ek = NULL; + +- if (mesg[mlen-1] != '\n') ++ if (mlen < 1 || mesg[mlen-1] != '\n') + return -EINVAL; + mesg[mlen-1] = 0; + diff --git a/queue-3.2/nfsd4-fix-lockowner-matching.patch b/queue-3.2/nfsd4-fix-lockowner-matching.patch new file mode 100644 index 00000000000..ceac28172b9 --- /dev/null +++ b/queue-3.2/nfsd4-fix-lockowner-matching.patch @@ -0,0 +1,57 @@ +From b93d87c19821ba7d3ee11557403d782e541071ad Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Mon, 7 Nov 2011 16:37:57 -0500 +Subject: nfsd4: fix lockowner matching + +From: "J. Bruce Fields" + +commit b93d87c19821ba7d3ee11557403d782e541071ad upstream. + +Lockowners are looked up by file as well as by owner, but we were +forgetting to do a comparison on the file. This could cause an +incorrect result from lockt. + +(Note looking up the inode from the lockowner is pretty awkward here. +The data structures need fixing.) + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfsd/nfs4state.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -3809,16 +3809,29 @@ nevermind: + deny->ld_type = NFS4_WRITE_LT; + } + ++static bool same_lockowner_ino(struct nfs4_lockowner *lo, struct inode *inode, clientid_t *clid, struct xdr_netobj *owner) ++{ ++ struct nfs4_ol_stateid *lst; ++ ++ if (!same_owner_str(&lo->lo_owner, owner, clid)) ++ return false; ++ lst = list_first_entry(&lo->lo_owner.so_stateids, ++ struct nfs4_ol_stateid, st_perstateowner); ++ return lst->st_file->fi_inode == inode; ++} ++ + static struct nfs4_lockowner * + find_lockowner_str(struct inode *inode, clientid_t *clid, + struct xdr_netobj *owner) + { + unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner); ++ struct nfs4_lockowner *lo; + struct nfs4_stateowner *op; + + list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) { +- if (same_owner_str(op, owner, clid)) +- return lockowner(op); ++ lo = lockowner(op); ++ if (same_lockowner_ino(lo, inode, clid, owner)) ++ return lo; + } + return NULL; + } diff --git a/queue-3.2/recordmcount-fix-handling-of-elf64-big-endian-objects.patch b/queue-3.2/recordmcount-fix-handling-of-elf64-big-endian-objects.patch new file mode 100644 index 00000000000..051f845180c --- /dev/null +++ b/queue-3.2/recordmcount-fix-handling-of-elf64-big-endian-objects.patch @@ -0,0 +1,43 @@ +From 2e885057b7f75035f0b85e02f737891482815a81 Mon Sep 17 00:00:00 2001 +From: David Daney +Date: Mon, 19 Dec 2011 17:42:42 -0800 +Subject: recordmcount: Fix handling of elf64 big-endian objects. + +From: David Daney + +commit 2e885057b7f75035f0b85e02f737891482815a81 upstream. + +In ELF64, the sh_flags field is 64-bits wide. recordmcount was +erroneously treating it as a 32-bit wide field. For little endian +objects this works because the flags of interest (SHF_EXECINSTR) +reside in the lower 32 bits of the word, and you get the same result +with either a 32-bit or 64-bit read. Big endian objects on the +other hand do not work at all with this error. + +The fix: Correctly treat sh_flags as 64-bits wide in elf64 objects. + +The symptom I observed was that my +__start_mcount_loc..__stop_mcount_loc was empty even though ftrace +function tracing was enabled. + +Link: http://lkml.kernel.org/r/1324345362-12230-1-git-send-email-ddaney.cavm@gmail.com + +Signed-off-by: David Daney +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + scripts/recordmcount.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/scripts/recordmcount.h ++++ b/scripts/recordmcount.h +@@ -462,7 +462,7 @@ __has_rel_mcount(Elf_Shdr const *const r + succeed_file(); + } + if (w(txthdr->sh_type) != SHT_PROGBITS || +- !(w(txthdr->sh_flags) & SHF_EXECINSTR)) ++ !(_w(txthdr->sh_flags) & SHF_EXECINSTR)) + return NULL; + return txtname; + } diff --git a/queue-3.2/series b/queue-3.2/series index 273a5217a91..f42e94c8037 100644 --- a/queue-3.2/series +++ b/queue-3.2/series @@ -58,3 +58,17 @@ i2c-fix-error-value-returned-by-several-bus-drivers.patch mmc-core-fix-voltage-select-in-ddr-mode.patch mmc-sdhci-fix-tuning-timer-incorrect-setting-when-suspending-host.patch mmc-sd-fix-sdr12-timing-regression.patch +v4l-dvb-v4l2-ioctl-integer-overflow-in-video_usercopy.patch +unused-iocbs-in-a-batch-should-not-be-accounted-as-active.patch +ftrace-fix-unregister-ftrace_ops-accounting.patch +kconfig-streamline-config.pl-simplify-backslash-line-concatination.patch +kconfig-streamline-config.pl-fix-parsing-makefile-with-variables.patch +svcrpc-fix-double-free-on-shutdown-of-nfsd-after-changing-pool-mode.patch +svcrpc-destroy-server-sockets-all-at-once.patch +svcrpc-avoid-memory-corruption-on-pool-shutdown.patch +nfsd4-fix-lockowner-matching.patch +nfsd-fix-oops-when-parsing-a-0-length-export.patch +fsnotify-don-t-bug-in-fsnotify_destroy_mark.patch +x86-uv-update-boot-messages-for-sgi-uv2-platform.patch +recordmcount-fix-handling-of-elf64-big-endian-objects.patch +uvcvideo-fix-integer-overflow-in-uvc_ioctl_ctrl_map.patch diff --git a/queue-3.2/svcrpc-avoid-memory-corruption-on-pool-shutdown.patch b/queue-3.2/svcrpc-avoid-memory-corruption-on-pool-shutdown.patch new file mode 100644 index 00000000000..b6b0598c862 --- /dev/null +++ b/queue-3.2/svcrpc-avoid-memory-corruption-on-pool-shutdown.patch @@ -0,0 +1,152 @@ +From b4f36f88b3ee7cf26bf0be84e6c7fc15f84dcb71 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Tue, 29 Nov 2011 17:00:26 -0500 +Subject: svcrpc: avoid memory-corruption on pool shutdown + +From: "J. Bruce Fields" + +commit b4f36f88b3ee7cf26bf0be84e6c7fc15f84dcb71 upstream. + +Socket callbacks use svc_xprt_enqueue() to add an xprt to a +pool->sp_sockets list. In normal operation a server thread will later +come along and take the xprt off that list. On shutdown, after all the +threads have exited, we instead manually walk the sv_tempsocks and +sv_permsocks lists to find all the xprt's and delete them. + +So the sp_sockets lists don't really matter any more. As a result, +we've mostly just ignored them and hoped they would go away. + +Which has gotten us into trouble; witness for example ebc63e531cc6 +"svcrpc: fix list-corrupting race on nfsd shutdown", the result of Ben +Greear noticing that a still-running svc_xprt_enqueue() could re-add an +xprt to an sp_sockets list just before it was deleted. The fix was to +remove it from the list at the end of svc_delete_xprt(). But that only +made corruption less likely--I can see nothing that prevents a +svc_xprt_enqueue() from adding another xprt to the list at the same +moment that we're removing this xprt from the list. In fact, despite +the earlier xpo_detach(), I don't even see what guarantees that +svc_xprt_enqueue() couldn't still be running on this xprt. + +So, instead, note that svc_xprt_enqueue() essentially does: + lock sp_lock + if XPT_BUSY unset + add to sp_sockets + unlock sp_lock + +So, if we do: + + set XPT_BUSY on every xprt. + Empty every sp_sockets list, under the sp_socks locks. + +Then we're left knowing that the sp_sockets lists are all empty and will +stay that way, since any svc_xprt_enqueue() will check XPT_BUSY under +the sp_lock and see it set. + +And *then* we can continue deleting the xprt's. + +(Thanks to Jeff Layton for being correctly suspicious of this code....) + +Cc: Ben Greear +Cc: Jeff Layton +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/svc.c | 10 +++++++++- + net/sunrpc/svc_xprt.c | 48 +++++++++++++++++++++++++++++------------------- + 2 files changed, 38 insertions(+), 20 deletions(-) + +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -530,7 +530,15 @@ svc_destroy(struct svc_serv *serv) + printk("svc_destroy: no threads for serv=%p!\n", serv); + + del_timer_sync(&serv->sv_temptimer); +- ++ /* ++ * The set of xprts (contained in the sv_tempsocks and ++ * sv_permsocks lists) is now constant, since it is modified ++ * only by accepting new sockets (done by service threads in ++ * svc_recv) or aging old ones (done by sv_temptimer), or ++ * configuration changes (excluded by whatever locking the ++ * caller is using--nfsd_mutex in the case of nfsd). So it's ++ * safe to traverse those lists and shut everything down: ++ */ + svc_close_all(serv); + + if (serv->sv_shutdown) +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -893,14 +893,7 @@ void svc_delete_xprt(struct svc_xprt *xp + spin_lock_bh(&serv->sv_lock); + if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags)) + list_del_init(&xprt->xpt_list); +- /* +- * The only time we're called while xpt_ready is still on a list +- * is while the list itself is about to be destroyed (in +- * svc_destroy). BUT svc_xprt_enqueue could still be attempting +- * to add new entries to the sp_sockets list, so we can't leave +- * a freed xprt on it. +- */ +- list_del_init(&xprt->xpt_ready); ++ BUG_ON(!list_empty(&xprt->xpt_ready)); + if (test_bit(XPT_TEMP, &xprt->xpt_flags)) + serv->sv_tmpcnt--; + spin_unlock_bh(&serv->sv_lock); +@@ -931,28 +924,45 @@ EXPORT_SYMBOL_GPL(svc_close_xprt); + static void svc_close_list(struct list_head *xprt_list) + { + struct svc_xprt *xprt; +- struct svc_xprt *tmp; + +- /* +- * The server is shutting down, and no more threads are running. +- * svc_xprt_enqueue() might still be running, but at worst it +- * will re-add the xprt to sp_sockets, which will soon get +- * freed. So we don't bother with any more locking, and don't +- * leave the close to the (nonexistent) server threads: +- */ +- list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { ++ list_for_each_entry(xprt, xprt_list, xpt_list) { + set_bit(XPT_CLOSE, &xprt->xpt_flags); +- svc_delete_xprt(xprt); ++ set_bit(XPT_BUSY, &xprt->xpt_flags); + } + } + + void svc_close_all(struct svc_serv *serv) + { ++ struct svc_pool *pool; ++ struct svc_xprt *xprt; ++ struct svc_xprt *tmp; ++ int i; ++ + svc_close_list(&serv->sv_tempsocks); + svc_close_list(&serv->sv_permsocks); ++ ++ for (i = 0; i < serv->sv_nrpools; i++) { ++ pool = &serv->sv_pools[i]; ++ ++ spin_lock_bh(&pool->sp_lock); ++ while (!list_empty(&pool->sp_sockets)) { ++ xprt = list_first_entry(&pool->sp_sockets, struct svc_xprt, xpt_ready); ++ list_del_init(&xprt->xpt_ready); ++ } ++ spin_unlock_bh(&pool->sp_lock); ++ } ++ /* ++ * At this point the sp_sockets lists will stay empty, since ++ * svc_enqueue will not add new entries without taking the ++ * sp_lock and checking XPT_BUSY. ++ */ ++ list_for_each_entry_safe(xprt, tmp, &serv->sv_tempsocks, xpt_list) ++ svc_delete_xprt(xprt); ++ list_for_each_entry_safe(xprt, tmp, &serv->sv_permsocks, xpt_list) ++ svc_delete_xprt(xprt); ++ + BUG_ON(!list_empty(&serv->sv_permsocks)); + BUG_ON(!list_empty(&serv->sv_tempsocks)); +- + } + + /* diff --git a/queue-3.2/svcrpc-destroy-server-sockets-all-at-once.patch b/queue-3.2/svcrpc-destroy-server-sockets-all-at-once.patch new file mode 100644 index 00000000000..35dbfc1507a --- /dev/null +++ b/queue-3.2/svcrpc-destroy-server-sockets-all-at-once.patch @@ -0,0 +1,79 @@ +From 2fefb8a09e7ed251ae8996e0c69066e74c5aa560 Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Tue, 29 Nov 2011 11:35:35 -0500 +Subject: svcrpc: destroy server sockets all at once + +From: "J. Bruce Fields" + +commit 2fefb8a09e7ed251ae8996e0c69066e74c5aa560 upstream. + +There's no reason I can see that we need to call sv_shutdown between +closing the two lists of sockets. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/sunrpc/svcsock.h | 2 +- + net/sunrpc/svc.c | 7 +------ + net/sunrpc/svc_xprt.c | 11 ++++++++++- + 3 files changed, 12 insertions(+), 8 deletions(-) + +--- a/include/linux/sunrpc/svcsock.h ++++ b/include/linux/sunrpc/svcsock.h +@@ -34,7 +34,7 @@ struct svc_sock { + /* + * Function prototypes. + */ +-void svc_close_all(struct list_head *); ++void svc_close_all(struct svc_serv *); + int svc_recv(struct svc_rqst *, long); + int svc_send(struct svc_rqst *); + void svc_drop(struct svc_rqst *); +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -531,16 +531,11 @@ svc_destroy(struct svc_serv *serv) + + del_timer_sync(&serv->sv_temptimer); + +- svc_close_all(&serv->sv_tempsocks); ++ svc_close_all(serv); + + if (serv->sv_shutdown) + serv->sv_shutdown(serv); + +- svc_close_all(&serv->sv_permsocks); +- +- BUG_ON(!list_empty(&serv->sv_permsocks)); +- BUG_ON(!list_empty(&serv->sv_tempsocks)); +- + cache_clean_deferred(serv); + + if (svc_serv_is_pooled(serv)) +--- a/net/sunrpc/svc_xprt.c ++++ b/net/sunrpc/svc_xprt.c +@@ -928,7 +928,7 @@ void svc_close_xprt(struct svc_xprt *xpr + } + EXPORT_SYMBOL_GPL(svc_close_xprt); + +-void svc_close_all(struct list_head *xprt_list) ++static void svc_close_list(struct list_head *xprt_list) + { + struct svc_xprt *xprt; + struct svc_xprt *tmp; +@@ -946,6 +946,15 @@ void svc_close_all(struct list_head *xpr + } + } + ++void svc_close_all(struct svc_serv *serv) ++{ ++ svc_close_list(&serv->sv_tempsocks); ++ svc_close_list(&serv->sv_permsocks); ++ BUG_ON(!list_empty(&serv->sv_permsocks)); ++ BUG_ON(!list_empty(&serv->sv_tempsocks)); ++ ++} ++ + /* + * Handle defer and revisit of requests + */ diff --git a/queue-3.2/svcrpc-fix-double-free-on-shutdown-of-nfsd-after-changing-pool-mode.patch b/queue-3.2/svcrpc-fix-double-free-on-shutdown-of-nfsd-after-changing-pool-mode.patch new file mode 100644 index 00000000000..edd02c4b466 --- /dev/null +++ b/queue-3.2/svcrpc-fix-double-free-on-shutdown-of-nfsd-after-changing-pool-mode.patch @@ -0,0 +1,57 @@ +From 61c8504c428edcebf23b97775a129c5b393a302b Mon Sep 17 00:00:00 2001 +From: "J. Bruce Fields" +Date: Thu, 22 Dec 2011 18:22:49 -0700 +Subject: svcrpc: fix double-free on shutdown of nfsd after changing pool mode + +From: "J. Bruce Fields" + +commit 61c8504c428edcebf23b97775a129c5b393a302b upstream. + +The pool_to and to_pool fields of the global svc_pool_map are freed on +shutdown, but are initialized in nfsd startup only in the +SVC_POOL_PERCPU and SVC_POOL_PERNODE cases. + +They *are* initialized to zero on kernel startup. So as long as you use +only SVC_POOL_GLOBAL (the default), this will never be a problem. + +You're also OK if you only ever use SVC_POOL_PERCPU or SVC_POOL_PERNODE. + +However, the following sequence events leads to a double-free: + + 1. set SVC_POOL_PERCPU or SVC_POOL_PERNODE + 2. start nfsd: both fields are initialized. + 3. shutdown nfsd: both fields are freed. + 4. set SVC_POOL_GLOBAL + 5. start nfsd: the fields are left untouched. + 6. shutdown nfsd: now we try to free them again. + +Step 4 is actually unnecessary, since (for some bizarre reason), nfsd +automatically resets the pool mode to SVC_POOL_GLOBAL on shutdown. + +Signed-off-by: J. Bruce Fields +Signed-off-by: Greg Kroah-Hartman + +--- + net/sunrpc/svc.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -167,6 +167,7 @@ svc_pool_map_alloc_arrays(struct svc_poo + + fail_free: + kfree(m->to_pool); ++ m->to_pool = NULL; + fail: + return -ENOMEM; + } +@@ -287,7 +288,9 @@ svc_pool_map_put(void) + if (!--m->count) { + m->mode = SVC_POOL_DEFAULT; + kfree(m->to_pool); ++ m->to_pool = NULL; + kfree(m->pool_to); ++ m->pool_to = NULL; + m->npools = 0; + } + diff --git a/queue-3.2/unused-iocbs-in-a-batch-should-not-be-accounted-as-active.patch b/queue-3.2/unused-iocbs-in-a-batch-should-not-be-accounted-as-active.patch new file mode 100644 index 00000000000..b2da1d061a9 --- /dev/null +++ b/queue-3.2/unused-iocbs-in-a-batch-should-not-be-accounted-as-active.patch @@ -0,0 +1,68 @@ +From 69e4747ee9727d660b88d7e1efe0f4afcb35db1b Mon Sep 17 00:00:00 2001 +From: Gleb Natapov +Date: Sun, 8 Jan 2012 17:07:28 +0200 +Subject: Unused iocbs in a batch should not be accounted as active. + +From: Gleb Natapov + +commit 69e4747ee9727d660b88d7e1efe0f4afcb35db1b upstream. + +Since commit 080d676de095 ("aio: allocate kiocbs in batches") iocbs are +allocated in a batch during processing of first iocbs. All iocbs in a +batch are automatically added to ctx->active_reqs list and accounted in +ctx->reqs_active. + +If one (not the last one) of iocbs submitted by an user fails, further +iocbs are not processed, but they are still present in ctx->active_reqs +and accounted in ctx->reqs_active. This causes process to stuck in a D +state in wait_for_all_aios() on exit since ctx->reqs_active will never +go down to zero. Furthermore since kiocb_batch_free() frees iocb +without removing it from active_reqs list the list become corrupted +which may cause oops. + +Fix this by removing iocb from ctx->active_reqs and updating +ctx->reqs_active in kiocb_batch_free(). + +Signed-off-by: Gleb Natapov +Reviewed-by: Jeff Moyer +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/aio.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/fs/aio.c ++++ b/fs/aio.c +@@ -476,14 +476,21 @@ static void kiocb_batch_init(struct kioc + batch->count = total; + } + +-static void kiocb_batch_free(struct kiocb_batch *batch) ++static void kiocb_batch_free(struct kioctx *ctx, struct kiocb_batch *batch) + { + struct kiocb *req, *n; + ++ if (list_empty(&batch->head)) ++ return; ++ ++ spin_lock_irq(&ctx->ctx_lock); + list_for_each_entry_safe(req, n, &batch->head, ki_batch) { + list_del(&req->ki_batch); ++ list_del(&req->ki_list); + kmem_cache_free(kiocb_cachep, req); ++ ctx->reqs_active--; + } ++ spin_unlock_irq(&ctx->ctx_lock); + } + + /* +@@ -1742,7 +1749,7 @@ long do_io_submit(aio_context_t ctx_id, + } + blk_finish_plug(&plug); + +- kiocb_batch_free(&batch); ++ kiocb_batch_free(ctx, &batch); + put_ioctx(ctx); + return i ? i : ret; + } diff --git a/queue-3.2/uvcvideo-fix-integer-overflow-in-uvc_ioctl_ctrl_map.patch b/queue-3.2/uvcvideo-fix-integer-overflow-in-uvc_ioctl_ctrl_map.patch new file mode 100644 index 00000000000..080fc01defd --- /dev/null +++ b/queue-3.2/uvcvideo-fix-integer-overflow-in-uvc_ioctl_ctrl_map.patch @@ -0,0 +1,57 @@ +From 806e23e95f94a27ee445022d724060b9b45cb64a Mon Sep 17 00:00:00 2001 +From: Haogang Chen +Date: Tue, 29 Nov 2011 18:32:25 -0300 +Subject: [media] uvcvideo: Fix integer overflow in uvc_ioctl_ctrl_map() + +From: Haogang Chen + +commit 806e23e95f94a27ee445022d724060b9b45cb64a upstream. + +There is a potential integer overflow in uvc_ioctl_ctrl_map(). When a +large xmap->menu_count is passed from the userspace, the subsequent call +to kmalloc() will allocate a buffer smaller than expected. +map->menu_count and map->menu_info would later be used in a loop (e.g. +in uvc_query_v4l2_ctrl), which leads to out-of-bound access. + +The patch checks the ioctl argument and returns -EINVAL for zero or too +large values in xmap->menu_count. + +Signed-off-by: Haogang Chen +[laurent.pinchart@ideasonboard.com Prevent excessive memory consumption] +Signed-off-by: Laurent Pinchart +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/video/uvc/uvc_v4l2.c | 9 +++++++++ + drivers/media/video/uvc/uvcvideo.h | 1 + + 2 files changed, 10 insertions(+) + +--- a/drivers/media/video/uvc/uvc_v4l2.c ++++ b/drivers/media/video/uvc/uvc_v4l2.c +@@ -58,6 +58,15 @@ static int uvc_ioctl_ctrl_map(struct uvc + break; + + case V4L2_CTRL_TYPE_MENU: ++ /* Prevent excessive memory consumption, as well as integer ++ * overflows. ++ */ ++ if (xmap->menu_count == 0 || ++ xmap->menu_count > UVC_MAX_CONTROL_MENU_ENTRIES) { ++ ret = -EINVAL; ++ goto done; ++ } ++ + size = xmap->menu_count * sizeof(*map->menu_info); + map->menu_info = kmalloc(size, GFP_KERNEL); + if (map->menu_info == NULL) { +--- a/drivers/media/video/uvc/uvcvideo.h ++++ b/drivers/media/video/uvc/uvcvideo.h +@@ -113,6 +113,7 @@ + + /* Maximum allowed number of control mappings per device */ + #define UVC_MAX_CONTROL_MAPPINGS 1024 ++#define UVC_MAX_CONTROL_MENU_ENTRIES 32 + + /* Devices quirks */ + #define UVC_QUIRK_STATUS_INTERVAL 0x00000001 diff --git a/queue-3.2/v4l-dvb-v4l2-ioctl-integer-overflow-in-video_usercopy.patch b/queue-3.2/v4l-dvb-v4l2-ioctl-integer-overflow-in-video_usercopy.patch new file mode 100644 index 00000000000..611a0f158ae --- /dev/null +++ b/queue-3.2/v4l-dvb-v4l2-ioctl-integer-overflow-in-video_usercopy.patch @@ -0,0 +1,49 @@ +From 6c06108be53ca5e94d8b0e93883d534dd9079646 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 5 Jan 2012 02:27:57 -0300 +Subject: [media] V4L/DVB: v4l2-ioctl: integer overflow in video_usercopy() + +From: Dan Carpenter + +commit 6c06108be53ca5e94d8b0e93883d534dd9079646 upstream. + +If ctrls->count is too high the multiplication could overflow and +array_size would be lower than expected. Mauro and Hans Verkuil +suggested that we cap it at 1024. That comes from the maximum +number of controls with lots of room for expantion. + +$ grep V4L2_CID include/linux/videodev2.h | wc -l +211 + +Signed-off-by: Dan Carpenter +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/video/v4l2-ioctl.c | 4 ++++ + include/linux/videodev2.h | 1 + + 2 files changed, 5 insertions(+) + +--- a/drivers/media/video/v4l2-ioctl.c ++++ b/drivers/media/video/v4l2-ioctl.c +@@ -2226,6 +2226,10 @@ static int check_array_args(unsigned int + struct v4l2_ext_controls *ctrls = parg; + + if (ctrls->count != 0) { ++ if (ctrls->count > V4L2_CID_MAX_CTRLS) { ++ ret = -EINVAL; ++ break; ++ } + *user_ptr = (void __user *)ctrls->controls; + *kernel_ptr = (void *)&ctrls->controls; + *array_size = sizeof(struct v4l2_ext_control) +--- a/include/linux/videodev2.h ++++ b/include/linux/videodev2.h +@@ -1131,6 +1131,7 @@ struct v4l2_querymenu { + #define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000 + + /* User-class control IDs defined by V4L2 */ ++#define V4L2_CID_MAX_CTRLS 1024 + #define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900) + #define V4L2_CID_USER_BASE V4L2_CID_BASE + /* IDs reserved for driver specific controls */ diff --git a/queue-3.2/x86-uv-update-boot-messages-for-sgi-uv2-platform.patch b/queue-3.2/x86-uv-update-boot-messages-for-sgi-uv2-platform.patch new file mode 100644 index 00000000000..df3ae3f8885 --- /dev/null +++ b/queue-3.2/x86-uv-update-boot-messages-for-sgi-uv2-platform.patch @@ -0,0 +1,42 @@ +From da517a08ac5913cd80ce3507cddd00f2a091b13c Mon Sep 17 00:00:00 2001 +From: Jack Steiner +Date: Fri, 6 Jan 2012 13:19:00 -0600 +Subject: x86, UV: Update Boot messages for SGI UV2 platform + +From: Jack Steiner + +commit da517a08ac5913cd80ce3507cddd00f2a091b13c upstream. + +SGI UV systems print a message during boot: + + UV: Found blades + +Due to packaging changes, the blade count is not accurate for +on the next generation of the platform. This patch corrects the +count. + +Signed-off-by: Jack Steiner +Link: http://lkml.kernel.org/r/20120106191900.GA19772@sgi.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/apic/x2apic_uv_x.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/apic/x2apic_uv_x.c ++++ b/arch/x86/kernel/apic/x2apic_uv_x.c +@@ -769,7 +769,12 @@ void __init uv_system_init(void) + for(i = 0; i < UVH_NODE_PRESENT_TABLE_DEPTH; i++) + uv_possible_blades += + hweight64(uv_read_local_mmr( UVH_NODE_PRESENT_TABLE + i * 8)); +- printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades()); ++ ++ /* uv_num_possible_blades() is really the hub count */ ++ printk(KERN_INFO "UV: Found %d blades, %d hubs\n", ++ is_uv1_hub() ? uv_num_possible_blades() : ++ (uv_num_possible_blades() + 1) / 2, ++ uv_num_possible_blades()); + + bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); + uv_blade_info = kzalloc(bytes, GFP_KERNEL); -- 2.47.3