1. 23 Mar, 2012 4 commits
    • Anton Blanchard's avatar
      perf tools: Incorrect use of snprintf results in SEGV · 2f54cf2c
      Anton Blanchard authored
      commit b832796c 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 <dsahern@gmail.com>
      Cc: Eric B Munson <emunson@mgebm.net>
      Cc: Frederic Weisbecker <fweisbec@gmail.com>
      Cc: Ingo Molnar <mingo@elte.hu>
      Cc: Paul Mackerras <paulus@samba.org>
      Cc: Peter Zijlstra <peterz@infradead.org>
      Cc: Yanmin Zhang <yanmin_zhang@linux.intel.com>
      Link: http://lkml.kernel.org/r/20120307114249.44275ca3@krytenSigned-off-by: default avatarAnton Blanchard <anton@samba.org>
      Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      2f54cf2c
    • Anton Blanchard's avatar
      afs: Remote abort can cause BUG in rxrpc code · 086b5909
      Anton Blanchard authored
      commit c0173863 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: default avatarAnton Blanchard <anton@samba.org>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      086b5909
    • Anton Blanchard's avatar
      afs: Read of file returns EBADMSG · 4376d075
      Anton Blanchard authored
      commit 2c724fb9 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: default avatarAnton Blanchard <anton@samba.org>
      Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      4376d075
    • Ryusuke Konishi's avatar
      nilfs2: fix NULL pointer dereference in nilfs_load_super_block() · f4565db7
      Ryusuke Konishi authored
      commit d7178c79 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: [<d0d7a08e>] nilfs_load_super_block+0x17e/0x280 [nilfs2]
       *pde = 00000000
       Oops: 0000 [#1] PREEMPT SMP
       ...
       Call Trace:
        [<d0d7a87b>] init_nilfs+0x4b/0x2e0 [nilfs2]
        [<d0d6f707>] nilfs_mount+0x447/0x5b0 [nilfs2]
        [<c0226636>] mount_fs+0x36/0x180
        [<c023d961>] vfs_kern_mount+0x51/0xa0
        [<c023ddae>] do_kern_mount+0x3e/0xe0
        [<c023f189>] do_mount+0x169/0x700
        [<c023fa9b>] sys_mount+0x6b/0xa0
        [<c04abd1f>] 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: [<d0d7a08e>] 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: default avatarSlicky Devil <slicky.dvl@gmail.com>
      Signed-off-by: default avatarRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
      Tested-by: default avatarSlicky Devil <slicky.dvl@gmail.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      f4565db7
  2. 19 Mar, 2012 36 commits