1. 03 4月, 2015 1 次提交
  2. 23 2月, 2015 2 次提交
    • A
      debugfs: leave freeing a symlink body until inode eviction · 0db59e59
      Al Viro 提交于
      As it is, we have debugfs_remove() racing with symlink traversals.
      Supply ->evict_inode() and do freeing there - inode will remain
      pinned until we are done with the symlink body.
      
      And rip the idiocy with checking if dentry is positive right after
      we'd verified debugfs_positive(), which is a stronger check...
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      0db59e59
    • D
      VFS: (Scripted) Convert S_ISLNK/DIR/REG(dentry->d_inode) to d_is_*(dentry) · e36cb0b8
      David Howells 提交于
      Convert the following where appropriate:
      
       (1) S_ISLNK(dentry->d_inode) to d_is_symlink(dentry).
      
       (2) S_ISREG(dentry->d_inode) to d_is_reg(dentry).
      
       (3) S_ISDIR(dentry->d_inode) to d_is_dir(dentry).  This is actually more
           complicated than it appears as some calls should be converted to
           d_can_lookup() instead.  The difference is whether the directory in
           question is a real dir with a ->lookup op or whether it's a fake dir with
           a ->d_automount op.
      
      In some circumstances, we can subsume checks for dentry->d_inode not being
      NULL into this, provided we the code isn't in a filesystem that expects
      d_inode to be NULL if the dirent really *is* negative (ie. if we're going to
      use d_inode() rather than d_backing_inode() to get the inode pointer).
      
      Note that the dentry type field may be set to something other than
      DCACHE_MISS_TYPE when d_inode is NULL in the case of unionmount, where the VFS
      manages the fall-through from a negative dentry to a lower layer.  In such a
      case, the dentry type of the negative union dentry is set to the same as the
      type of the lower dentry.
      
      However, if you know d_inode is not NULL at the call site, then you can use
      the d_is_xxx() functions even in a filesystem.
      
      There is one further complication: a 0,0 chardev dentry may be labelled
      DCACHE_WHITEOUT_TYPE rather than DCACHE_SPECIAL_TYPE.  Strictly, this was
      intended for special directory entry types that don't have attached inodes.
      
      The following perl+coccinelle script was used:
      
      use strict;
      
      my @callers;
      open($fd, 'git grep -l \'S_IS[A-Z].*->d_inode\' |') ||
          die "Can't grep for S_ISDIR and co. callers";
      @callers = <$fd>;
      close($fd);
      unless (@callers) {
          print "No matches\n";
          exit(0);
      }
      
      my @cocci = (
          '@@',
          'expression E;',
          '@@',
          '',
          '- S_ISLNK(E->d_inode->i_mode)',
          '+ d_is_symlink(E)',
          '',
          '@@',
          'expression E;',
          '@@',
          '',
          '- S_ISDIR(E->d_inode->i_mode)',
          '+ d_is_dir(E)',
          '',
          '@@',
          'expression E;',
          '@@',
          '',
          '- S_ISREG(E->d_inode->i_mode)',
          '+ d_is_reg(E)' );
      
      my $coccifile = "tmp.sp.cocci";
      open($fd, ">$coccifile") || die $coccifile;
      print($fd "$_\n") || die $coccifile foreach (@cocci);
      close($fd);
      
      foreach my $file (@callers) {
          chomp $file;
          print "Processing ", $file, "\n";
          system("spatch", "--sp-file", $coccifile, $file, "--in-place", "--no-show-diff") == 0 ||
      	die "spatch failed";
      }
      
      [AV: overlayfs parts skipped]
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      e36cb0b8
  3. 18 2月, 2015 1 次提交
  4. 26 1月, 2015 11 次提交
  5. 04 11月, 2014 1 次提交
  6. 10 7月, 2014 2 次提交
    • R
      fs: debugfs: remove trailing whitespace · 88e412ea
      Rahul Bedarkar 提交于
      fixes checkpatch.pl trailing whitespace errors
      Signed-off-by: NRahul Bedarkar <rahulbedarkar89@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      88e412ea
    • S
      debugfs: Fix corrupted loop in debugfs_remove_recursive · 485d4402
      Steven Rostedt 提交于
      [ I'm currently running my tests on it now, and so far, after a few
       hours it has yet to blow up. I'll run it for 24 hours which it never
       succeeded in the past. ]
      
      The tracing code has a way to make directories within the debugfs file
      system as well as deleting them using mkdir/rmdir in the instance
      directory. This is very limited in functionality, such as there is
      no renames, and the parent directory "instance" can not be modified.
      The tracing code creates the instance directory from the debugfs code
      and then replaces the dentry->d_inode->i_op with its own to allow
      for mkdir/rmdir to work.
      
      When these are called, the d_entry and inode locks need to be released
      to call the instance creation and deletion code. That code has its own
      accounting and locking to serialize everything to prevent multiple
      users from causing harm. As the parent "instance" directory can not
      be modified this simplifies things.
      
      I created a stress test that creates several threads that randomly
      creates and deletes directories thousands of times a second. The code
      stood up to this test and I submitted it a while ago.
      
      Recently I added a new test that adds readers to the mix. While the
      instance directories were being added and deleted, readers would read
      from these directories and even enable tracing within them. This test
      was able to trigger a bug:
      
       general protection fault: 0000 [#1] PREEMPT SMP
       Modules linked in: ...
       CPU: 3 PID: 17789 Comm: rmdir Tainted: G        W     3.15.0-rc2-test+ #41
       Hardware name: To Be Filled By O.E.M. To Be Filled By O.E.M./To be filled by O.E.M., BIOS SDBLI944.86P 05/08/2007
       task: ffff88003786ca60 ti: ffff880077018000 task.ti: ffff880077018000
       RIP: 0010:[<ffffffff811ed5eb>]  [<ffffffff811ed5eb>] debugfs_remove_recursive+0x1bd/0x367
       RSP: 0018:ffff880077019df8  EFLAGS: 00010246
       RAX: 0000000000000002 RBX: ffff88006f0fe490 RCX: 0000000000000000
       RDX: dead000000100058 RSI: 0000000000000246 RDI: ffff88003786d454
       RBP: ffff88006f0fe640 R08: 0000000000000628 R09: 0000000000000000
       R10: 0000000000000628 R11: ffff8800795110a0 R12: ffff88006f0fe640
       R13: ffff88006f0fe640 R14: ffffffff81817d0b R15: ffffffff818188b7
       FS:  00007ff13ae24700(0000) GS:ffff88007d580000(0000) knlGS:0000000000000000
       CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
       CR2: 0000003054ec7be0 CR3: 0000000076d51000 CR4: 00000000000007e0
       Stack:
        ffff88007a41ebe0 dead000000100058 00000000fffffffe ffff88006f0fe640
        0000000000000000 ffff88006f0fe678 ffff88007a41ebe0 ffff88003793a000
        00000000fffffffe ffffffff810bde82 ffff88006f0fe640 ffff88007a41eb28
       Call Trace:
        [<ffffffff810bde82>] ? instance_rmdir+0x15b/0x1de
        [<ffffffff81132e2d>] ? vfs_rmdir+0x80/0xd3
        [<ffffffff81132f51>] ? do_rmdir+0xd1/0x139
        [<ffffffff8124ad9e>] ? trace_hardirqs_on_thunk+0x3a/0x3c
        [<ffffffff814fea62>] ? system_call_fastpath+0x16/0x1b
       Code: fe ff ff 48 8d 75 30 48 89 df e8 c9 fd ff ff 85 c0 75 13 48 c7 c6 b8 cc d2 81 48 c7 c7 b0 cc d2 81 e8 8c 7a f5 ff 48 8b 54 24 08 <48> 8b 82 a8 00 00 00 48 89 d3 48 2d a8 00 00 00 48 89 44 24 08
       RIP  [<ffffffff811ed5eb>] debugfs_remove_recursive+0x1bd/0x367
        RSP <ffff880077019df8>
      
      It took a while, but every time it triggered, it was always in the
      same place:
      
      	list_for_each_entry_safe(child, next, &parent->d_subdirs, d_u.d_child) {
      
      Where the child->d_u.d_child seemed to be corrupted.  I added lots of
      trace_printk()s to see what was wrong, and sure enough, it was always
      the child's d_u.d_child field. I looked around to see what touches
      it and noticed that in __dentry_kill() which calls dentry_free():
      
      static void dentry_free(struct dentry *dentry)
      {
      	/* if dentry was never visible to RCU, immediate free is OK */
      	if (!(dentry->d_flags & DCACHE_RCUACCESS))
      		__d_free(&dentry->d_u.d_rcu);
      	else
      		call_rcu(&dentry->d_u.d_rcu, __d_free);
      }
      
      I also noticed that __dentry_kill() unlinks the child->d_u.child
      under the parent->d_lock spin_lock.
      
      Looking back at the loop in debugfs_remove_recursive() it never takes the
      parent->d_lock to do the list walk. Adding more tracing, I was able to
      prove this was the issue:
      
       ftrace-t-15385   1.... 246662024us : dentry_kill <ffffffff81138b91>: free ffff88006d573600
          rmdir-15409   2.... 246662024us : debugfs_remove_recursive <ffffffff811ec7e5>: child=ffff88006d573600 next=dead000000100058
      
      The dentry_kill freed ffff88006d573600 just as the remove recursive was walking
      it.
      
      In order to fix this, the list walk needs to be modified a bit to take
      the parent->d_lock. The safe version is no longer necessary, as every
      time we remove a child, the parent->d_lock must be released and the
      list walk must start over. Each time a child is removed, even though it
      may still be on the list, it should be skipped by the first check
      in the loop:
      
      		if (!debugfs_positive(child))
      			continue;
      
      Cc: stable@vger.kernel.org
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      485d4402
  7. 13 3月, 2014 1 次提交
    • T
      fs: push sync_filesystem() down to the file system's remount_fs() · 02b9984d
      Theodore Ts'o 提交于
      Previously, the no-op "mount -o mount /dev/xxx" operation when the
      file system is already mounted read-write causes an implied,
      unconditional syncfs().  This seems pretty stupid, and it's certainly
      documented or guaraunteed to do this, nor is it particularly useful,
      except in the case where the file system was mounted rw and is getting
      remounted read-only.
      
      However, it's possible that there might be some file systems that are
      actually depending on this behavior.  In most file systems, it's
      probably fine to only call sync_filesystem() when transitioning from
      read-write to read-only, and there are some file systems where this is
      not needed at all (for example, for a pseudo-filesystem or something
      like romfs).
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: linux-fsdevel@vger.kernel.org
      Cc: Christoph Hellwig <hch@infradead.org>
      Cc: Artem Bityutskiy <dedekind1@gmail.com>
      Cc: Adrian Hunter <adrian.hunter@intel.com>
      Cc: Evgeniy Dushistov <dushistov@mail.ru>
      Cc: Jan Kara <jack@suse.cz>
      Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
      Cc: Anders Larsen <al@alarsen.net>
      Cc: Phillip Lougher <phillip@squashfs.org.uk>
      Cc: Kees Cook <keescook@chromium.org>
      Cc: Mikulas Patocka <mikulas@artax.karlin.mff.cuni.cz>
      Cc: Petr Vandrovec <petr@vandrovec.name>
      Cc: xfs@oss.sgi.com
      Cc: linux-btrfs@vger.kernel.org
      Cc: linux-cifs@vger.kernel.org
      Cc: samba-technical@lists.samba.org
      Cc: codalist@coda.cs.cmu.edu
      Cc: linux-ext4@vger.kernel.org
      Cc: linux-f2fs-devel@lists.sourceforge.net
      Cc: fuse-devel@lists.sourceforge.net
      Cc: cluster-devel@redhat.com
      Cc: linux-mtd@lists.infradead.org
      Cc: jfs-discussion@lists.sourceforge.net
      Cc: linux-nfs@vger.kernel.org
      Cc: linux-nilfs@vger.kernel.org
      Cc: linux-ntfs-dev@lists.sourceforge.net
      Cc: ocfs2-devel@oss.oracle.com
      Cc: reiserfs-devel@vger.kernel.org
      02b9984d
  8. 19 2月, 2014 1 次提交
  9. 13 11月, 2013 1 次提交
  10. 01 8月, 2013 1 次提交
    • O
      debugfs: debugfs_remove_recursive() must not rely on list_empty(d_subdirs) · 776164c1
      Oleg Nesterov 提交于
      debugfs_remove_recursive() is wrong,
      
      1. it wrongly assumes that !list_empty(d_subdirs) means that this
         dir should be removed.
      
         This is not that bad by itself, but:
      
      2. if d_subdirs does not becomes empty after __debugfs_remove()
         it gives up and silently fails, it doesn't even try to remove
         other entries.
      
         However ->d_subdirs can be non-empty because it still has the
         already deleted !debugfs_positive() entries.
      
      3. simple_release_fs() is called even if __debugfs_remove() fails.
      
      Suppose we have
      
      	dir1/
      		dir2/
      			file2
      		file1
      
      and someone opens dir1/dir2/file2.
      
      Now, debugfs_remove_recursive(dir1/dir2) succeeds, and dir1/dir2 goes
      away.
      
      But debugfs_remove_recursive(dir1) silently fails and doesn't remove
      this directory. Because it tries to delete (the already deleted)
      dir1/dir2/file2 again and then fails due to "Avoid infinite loop"
      logic.
      
      Test-case:
      
      	#!/bin/sh
      
      	cd /sys/kernel/debug/tracing
      	echo 'p:probe/sigprocmask sigprocmask' >> kprobe_events
      	sleep 1000 < events/probe/sigprocmask/id &
      	echo -n >| kprobe_events
      
      	[ -d events/probe ] && echo "ERR!! failed to rm probe"
      
      And after that it is not possible to create another probe entry.
      
      With this patch debugfs_remove_recursive() skips !debugfs_positive()
      files although this is not strictly needed. The most important change
      is that it does not try to make ->d_subdirs empty, it simply scans
      the whole list(s) recursively and removes as much as possible.
      
      Link: http://lkml.kernel.org/r/20130726151256.GC19472@redhat.comAcked-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Signed-off-by: NOleg Nesterov <oleg@redhat.com>
      Signed-off-by: NSteven Rostedt <rostedt@goodmis.org>
      776164c1
  11. 04 3月, 2013 1 次提交
    • E
      fs: Limit sys_mount to only request filesystem modules. · 7f78e035
      Eric W. Biederman 提交于
      Modify the request_module to prefix the file system type with "fs-"
      and add aliases to all of the filesystems that can be built as modules
      to match.
      
      A common practice is to build all of the kernel code and leave code
      that is not commonly needed as modules, with the result that many
      users are exposed to any bug anywhere in the kernel.
      
      Looking for filesystems with a fs- prefix limits the pool of possible
      modules that can be loaded by mount to just filesystems trivially
      making things safer with no real cost.
      
      Using aliases means user space can control the policy of which
      filesystem modules are auto-loaded by editing /etc/modprobe.d/*.conf
      with blacklist and alias directives.  Allowing simple, safe,
      well understood work-arounds to known problematic software.
      
      This also addresses a rare but unfortunate problem where the filesystem
      name is not the same as it's module name and module auto-loading
      would not work.  While writing this patch I saw a handful of such
      cases.  The most significant being autofs that lives in the module
      autofs4.
      
      This is relevant to user namespaces because we can reach the request
      module in get_fs_type() without having any special permissions, and
      people get uncomfortable when a user specified string (in this case
      the filesystem type) goes all of the way to request_module.
      
      After having looked at this issue I don't think there is any
      particular reason to perform any filtering or permission checks beyond
      making it clear in the module request that we want a filesystem
      module.  The common pattern in the kernel is to call request_module()
      without regards to the users permissions.  In general all a filesystem
      module does once loaded is call register_filesystem() and go to sleep.
      Which means there is not much attack surface exposed by loading a
      filesytem module unless the filesystem is mounted.  In a user
      namespace filesystems are not mounted unless .fs_flags = FS_USERNS_MOUNT,
      which most filesystems do not set today.
      Acked-by: NSerge Hallyn <serge.hallyn@canonical.com>
      Acked-by: NKees Cook <keescook@chromium.org>
      Reported-by: NKees Cook <keescook@google.com>
      Signed-off-by: N"Eric W. Biederman" <ebiederm@xmission.com>
      7f78e035
  12. 18 1月, 2013 1 次提交
  13. 11 1月, 2013 1 次提交
  14. 16 11月, 2012 1 次提交
  15. 07 9月, 2012 1 次提交
  16. 28 8月, 2012 1 次提交
  17. 17 8月, 2012 1 次提交
  18. 14 7月, 2012 3 次提交
  19. 14 6月, 2012 1 次提交
  20. 27 1月, 2012 1 次提交
    • L
      debugfs: add mode, uid and gid options · d6e48686
      Ludwig Nussel 提交于
      Cautious admins may want to restrict access to debugfs. Currently a
      manual chown/chmod e.g. in an init script is needed to achieve that.
      Distributions that want to make the mount options configurable need
      to add extra config files. By allowing to set the root inode's uid,
      gid and mode via mount options no such hacks are needed anymore.
      Instead configuration becomes straight forward via fstab.
      Signed-off-by: NLudwig Nussel <ludwig.nussel@suse.de>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
      d6e48686
  21. 04 1月, 2012 2 次提交
  22. 23 8月, 2011 1 次提交
  23. 19 2月, 2011 1 次提交
  24. 04 2月, 2011 1 次提交
  25. 29 10月, 2010 1 次提交