From: Greg Kroah-Hartman Date: Mon, 19 Mar 2012 20:00:56 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.26~44 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=92c66184b08b8911bc32bd1fa5639195e8d634f9;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: afs-read-of-file-returns-ebadmsg.patch afs-remote-abort-can-cause-bug-in-rxrpc-code.patch nilfs2-fix-null-pointer-dereference-in-nilfs_load_super_block.patch perf-tools-incorrect-use-of-snprintf-results-in-segv.patch --- diff --git a/queue-3.0/afs-read-of-file-returns-ebadmsg.patch b/queue-3.0/afs-read-of-file-returns-ebadmsg.patch new file mode 100644 index 00000000000..e70010179c4 --- /dev/null +++ b/queue-3.0/afs-read-of-file-returns-ebadmsg.patch @@ -0,0 +1,54 @@ +From 2c724fb92732c0b2a5629eb8af74e82eb62ac947 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Fri, 16 Mar 2012 10:28:07 +0000 +Subject: afs: Read of file returns EBADMSG + +From: Anton Blanchard + +commit 2c724fb92732c0b2a5629eb8af74e82eb62ac947 upstream. + +A read of a large file on an afs mount failed: + +# cat junk.file > /dev/null +cat: junk.file: Bad message + +Looking at the trace, call->offset wrapped since it is only an +unsigned short. In afs_extract_data: + + _enter("{%u},{%zu},%d,,%zu", call->offset, len, last, count); +... + + if (call->offset < count) { + if (last) { + _leave(" = -EBADMSG [%d < %zu]", call->offset, count); + return -EBADMSG; + } + +Which matches the trace: + +[cat ] ==> afs_extract_data({65132},{524},1,,65536) +[cat ] <== afs_extract_data() = -EBADMSG [0 < 65536] + +call->offset went from 65132 to 0. Fix this by making call->offset an +unsigned int. + +Signed-off-by: Anton Blanchard +Signed-off-by: David Howells +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/internal.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/afs/internal.h ++++ b/fs/afs/internal.h +@@ -109,7 +109,7 @@ struct afs_call { + unsigned reply_size; /* current size of reply */ + unsigned first_offset; /* offset into mapping[first] */ + unsigned last_to; /* amount of mapping[last] */ +- unsigned short offset; /* offset into received data store */ ++ unsigned offset; /* offset into received data store */ + unsigned char unmarshall; /* unmarshalling phase */ + bool incoming; /* T if incoming call */ + bool send_pages; /* T if data from mapping should be sent */ diff --git a/queue-3.0/afs-remote-abort-can-cause-bug-in-rxrpc-code.patch b/queue-3.0/afs-remote-abort-can-cause-bug-in-rxrpc-code.patch new file mode 100644 index 00000000000..4f9848b56de --- /dev/null +++ b/queue-3.0/afs-remote-abort-can-cause-bug-in-rxrpc-code.patch @@ -0,0 +1,66 @@ +From c0173863528a8c9212c53e080d63a1aaae5ef4f4 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Fri, 16 Mar 2012 10:28:19 +0000 +Subject: afs: Remote abort can cause BUG in rxrpc code + +From: Anton Blanchard + +commit c0173863528a8c9212c53e080d63a1aaae5ef4f4 upstream. + +When writing files to afs I sometimes hit a BUG: + +kernel BUG at fs/afs/rxrpc.c:179! + +With a backtrace of: + + afs_free_call + afs_make_call + afs_fs_store_data + afs_vnode_store_data + afs_write_back_from_locked_page + afs_writepages_region + afs_writepages + +The cause is: + + ASSERT(skb_queue_empty(&call->rx_queue)); + +Looking at a tcpdump of the session the abort happens because we +are exceeding our disk quota: + + rx abort fs reply store-data error diskquota exceeded (32) + +So the abort error is valid. We hit the BUG because we haven't +freed all the resources for the call. + +By freeing any skbs in call->rx_queue before calling afs_free_call +we avoid hitting leaking memory and avoid hitting the BUG. + +Signed-off-by: Anton Blanchard +Signed-off-by: David Howells +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/afs/rxrpc.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/afs/rxrpc.c ++++ b/fs/afs/rxrpc.c +@@ -314,6 +314,7 @@ int afs_make_call(struct in_addr *addr, + struct msghdr msg; + struct kvec iov[1]; + int ret; ++ struct sk_buff *skb; + + _enter("%x,{%d},", addr->s_addr, ntohs(call->port)); + +@@ -380,6 +381,8 @@ int afs_make_call(struct in_addr *addr, + + error_do_abort: + rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT); ++ while ((skb = skb_dequeue(&call->rx_queue))) ++ afs_free_skb(skb); + rxrpc_kernel_end_call(rxcall); + call->rxcall = NULL; + error_kill_call: diff --git a/queue-3.0/nilfs2-fix-null-pointer-dereference-in-nilfs_load_super_block.patch b/queue-3.0/nilfs2-fix-null-pointer-dereference-in-nilfs_load_super_block.patch new file mode 100644 index 00000000000..eff2c4403e6 --- /dev/null +++ b/queue-3.0/nilfs2-fix-null-pointer-dereference-in-nilfs_load_super_block.patch @@ -0,0 +1,59 @@ +From d7178c79d9b7c5518f9943188091a75fc6ce0675 Mon Sep 17 00:00:00 2001 +From: Ryusuke Konishi +Date: Fri, 16 Mar 2012 17:08:39 -0700 +Subject: nilfs2: fix NULL pointer dereference in nilfs_load_super_block() + +From: Ryusuke Konishi + +commit d7178c79d9b7c5518f9943188091a75fc6ce0675 upstream. + +According to the report from Slicky Devil, nilfs caused kernel oops at +nilfs_load_super_block function during mount after he shrank the +partition without resizing the filesystem: + + BUG: unable to handle kernel NULL pointer dereference at 00000048 + IP: [] nilfs_load_super_block+0x17e/0x280 [nilfs2] + *pde = 00000000 + Oops: 0000 [#1] PREEMPT SMP + ... + Call Trace: + [] init_nilfs+0x4b/0x2e0 [nilfs2] + [] nilfs_mount+0x447/0x5b0 [nilfs2] + [] mount_fs+0x36/0x180 + [] vfs_kern_mount+0x51/0xa0 + [] do_kern_mount+0x3e/0xe0 + [] do_mount+0x169/0x700 + [] sys_mount+0x6b/0xa0 + [] sysenter_do_call+0x12/0x28 + Code: 53 18 8b 43 20 89 4b 18 8b 4b 24 89 53 1c 89 43 24 89 4b 20 8b 43 + 20 c7 43 2c 00 00 00 00 23 75 e8 8b 50 68 89 53 28 8b 54 b3 20 <8b> 72 + 48 8b 7a 4c 8b 55 08 89 b3 84 00 00 00 89 bb 88 00 00 00 + EIP: [] nilfs_load_super_block+0x17e/0x280 [nilfs2] SS:ESP 0068:ca9bbdcc + CR2: 0000000000000048 + +This turned out due to a defect in an error path which runs if the +calculated location of the secondary super block was invalid. + +This patch fixes it and eliminates the reported oops. + +Reported-by: Slicky Devil +Signed-off-by: Ryusuke Konishi +Tested-by: Slicky Devil +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nilfs2/the_nilfs.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/nilfs2/the_nilfs.c ++++ b/fs/nilfs2/the_nilfs.c +@@ -515,6 +515,7 @@ static int nilfs_load_super_block(struct + brelse(sbh[1]); + sbh[1] = NULL; + sbp[1] = NULL; ++ valid[1] = 0; + swp = 0; + } + if (!valid[swp]) { diff --git a/queue-3.0/perf-tools-incorrect-use-of-snprintf-results-in-segv.patch b/queue-3.0/perf-tools-incorrect-use-of-snprintf-results-in-segv.patch new file mode 100644 index 00000000000..046246b9f5f --- /dev/null +++ b/queue-3.0/perf-tools-incorrect-use-of-snprintf-results-in-segv.patch @@ -0,0 +1,64 @@ +From b832796caa1fda8516464a003c8c7cc547bc20c2 Mon Sep 17 00:00:00 2001 +From: Anton Blanchard +Date: Wed, 7 Mar 2012 11:42:49 +1100 +Subject: perf tools: Incorrect use of snprintf results in SEGV + +From: Anton Blanchard + +commit b832796caa1fda8516464a003c8c7cc547bc20c2 upstream. + +I have a workload where perf top scribbles over the stack and we SEGV. +What makes it interesting is that an snprintf is causing this. + +The workload is a c++ gem that has method names over 3000 characters +long, but snprintf is designed to avoid overrunning buffers. So what +went wrong? + +The problem is we assume snprintf returns the number of characters +written: + + ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", self->level); +... + ret += repsep_snprintf(bf + ret, size - ret, "%s", self->ms.sym->name); + +Unfortunately this is not how snprintf works. snprintf returns the +number of characters that would have been written if there was enough +space. In the above case, if the first snprintf returns a value larger +than size, we pass a negative size into the second snprintf and happily +scribble over the stack. If you have 3000 character c++ methods thats a +lot of stack to trample. + +This patch fixes repsep_snprintf by clamping the value at size - 1 which +is the maximum snprintf can write before adding the NULL terminator. + +I get the sinking feeling that there are a lot of other uses of snprintf +that have this same bug, we should audit them all. + +Cc: David Ahern +Cc: Eric B Munson +Cc: Frederic Weisbecker +Cc: Ingo Molnar +Cc: Paul Mackerras +Cc: Peter Zijlstra +Cc: Yanmin Zhang +Link: http://lkml.kernel.org/r/20120307114249.44275ca3@kryten +Signed-off-by: Anton Blanchard +Signed-off-by: Arnaldo Carvalho de Melo +Signed-off-by: Greg Kroah-Hartman + +--- + tools/perf/util/sort.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/tools/perf/util/sort.c ++++ b/tools/perf/util/sort.c +@@ -122,6 +122,9 @@ static int repsep_snprintf(char *bf, siz + } + } + va_end(ap); ++ ++ if (n >= (int)size) ++ return size - 1; + return n; + } + diff --git a/queue-3.0/series b/queue-3.0/series new file mode 100644 index 00000000000..eba7aec8b1f --- /dev/null +++ b/queue-3.0/series @@ -0,0 +1,4 @@ +nilfs2-fix-null-pointer-dereference-in-nilfs_load_super_block.patch +afs-read-of-file-returns-ebadmsg.patch +afs-remote-abort-can-cause-bug-in-rxrpc-code.patch +perf-tools-incorrect-use-of-snprintf-results-in-segv.patch