1. 03 3月, 2015 1 次提交
    • T
      eCryptfs: don't pass fs-specific ioctl commands through · 6d65261a
      Tyler Hicks 提交于
      eCryptfs can't be aware of what to expect when after passing an
      arbitrary ioctl command through to the lower filesystem. The ioctl
      command may trigger an action in the lower filesystem that is
      incompatible with eCryptfs.
      
      One specific example is when one attempts to use the Btrfs clone
      ioctl command when the source file is in the Btrfs filesystem that
      eCryptfs is mounted on top of and the destination fd is from a new file
      created in the eCryptfs mount. The ioctl syscall incorrectly returns
      success because the command is passed down to Btrfs which thinks that it
      was able to do the clone operation. However, the result is an empty
      eCryptfs file.
      
      This patch allows the trim, {g,s}etflags, and {g,s}etversion ioctl
      commands through and then copies up the inode metadata from the lower
      inode to the eCryptfs inode to catch any changes made to the lower
      inode's metadata. Those five ioctl commands are mostly common across all
      filesystems but the whitelist may need to be further pruned in the
      future.
      
      https://bugzilla.kernel.org/show_bug.cgi?id=93691
      https://launchpad.net/bugs/1305335Signed-off-by: NTyler Hicks <tyhicks@canonical.com>
      Cc: Rocko <rockorequin@hotmail.com>
      Cc: Colin Ian King <colin.king@canonical.com>
      Cc: stable@vger.kernel.org # v2.6.36+: c43f7b8f eCryptfs: Handle ioctl calls with unlocked and compat functions
      6d65261a
  2. 23 2月, 2015 1 次提交
    • 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. 01 11月, 2014 1 次提交
  4. 23 10月, 2014 1 次提交
    • T
      eCryptfs: Force RO mount when encrypted view is enabled · 332b122d
      Tyler Hicks 提交于
      The ecryptfs_encrypted_view mount option greatly changes the
      functionality of an eCryptfs mount. Instead of encrypting and decrypting
      lower files, it provides a unified view of the encrypted files in the
      lower filesystem. The presence of the ecryptfs_encrypted_view mount
      option is intended to force a read-only mount and modifying files is not
      supported when the feature is in use. See the following commit for more
      information:
      
        e77a56dd [PATCH] eCryptfs: Encrypted passthrough
      
      This patch forces the mount to be read-only when the
      ecryptfs_encrypted_view mount option is specified by setting the
      MS_RDONLY flag on the superblock. Additionally, this patch removes some
      broken logic in ecryptfs_open() that attempted to prevent modifications
      of files when the encrypted view feature was in use. The check in
      ecryptfs_open() was not sufficient to prevent file modifications using
      system calls that do not operate on a file descriptor.
      Signed-off-by: NTyler Hicks <tyhicks@canonical.com>
      Reported-by: NPriya Bansal <p.bansal@samsung.com>
      Cc: stable@vger.kernel.org # v2.6.21+: e77a56dd [PATCH] eCryptfs: Encrypted passthrough
      332b122d
  5. 09 10月, 2014 1 次提交
  6. 07 5月, 2014 2 次提交
  7. 18 12月, 2013 1 次提交
  8. 15 11月, 2013 1 次提交
    • T
      eCryptfs: file->private_data is always valid · 2000f5be
      Tyler Hicks 提交于
      When accessing the lower_file pointer located in private_data of
      eCryptfs files, there is no need to check to see if the private_data
      pointer has been initialized to a non-NULL value. The file->private_data
      and file->private_data->lower_file pointers are always initialized to
      non-NULL values in ecryptfs_open().
      
      This change quiets a Smatch warning:
      
        CHECK   /var/scm/kernel/linux/fs/ecryptfs/file.c
      fs/ecryptfs/file.c:321 ecryptfs_unlocked_ioctl() error: potential NULL dereference 'lower_file'.
      fs/ecryptfs/file.c:335 ecryptfs_compat_ioctl() error: potential NULL dereference 'lower_file'.
      Signed-off-by: NTyler Hicks <tyhicks@canonical.com>
      Reported-by: NDan Carpenter <dan.carpenter@oracle.com>
      Reviewed-by: NGeyslan G. Bem <geyslan@gmail.com>
      Cc: Al Viro <viro@zeniv.linux.org.uk>
      2000f5be
  9. 10 11月, 2013 1 次提交
  10. 25 10月, 2013 1 次提交
  11. 10 7月, 2013 1 次提交
  12. 29 6月, 2013 3 次提交
  13. 05 6月, 2013 1 次提交
  14. 25 5月, 2013 1 次提交
  15. 08 5月, 2013 1 次提交
  16. 23 2月, 2013 1 次提交
  17. 18 1月, 2013 1 次提交
  18. 15 9月, 2012 1 次提交
    • T
      eCryptfs: Call lower ->flush() from ecryptfs_flush() · 64e6651d
      Tyler Hicks 提交于
      Since eCryptfs only calls fput() on the lower file in
      ecryptfs_release(), eCryptfs should call the lower filesystem's
      ->flush() from ecryptfs_flush().
      
      If the lower filesystem implements ->flush(), then eCryptfs should try
      to flush out any dirty pages prior to calling the lower ->flush(). If
      the lower filesystem does not implement ->flush(), then eCryptfs has no
      need to do anything in ecryptfs_flush() since dirty pages are now
      written out to the lower filesystem in ecryptfs_release().
      Signed-off-by: NTyler Hicks <tyhicks@canonical.com>
      64e6651d
  19. 14 7月, 2012 1 次提交
    • T
      eCryptfs: Revert to a writethrough cache model · 821f7494
      Tyler Hicks 提交于
      A change was made about a year ago to get eCryptfs to better utilize its
      page cache during writes. The idea was to do the page encryption
      operations during page writeback, rather than doing them when initially
      writing into the page cache, to reduce the number of page encryption
      operations during sequential writes. This meant that the encrypted page
      would only be written to the lower filesystem during page writeback,
      which was a change from how eCryptfs had previously wrote to the lower
      filesystem in ecryptfs_write_end().
      
      The change caused a few eCryptfs-internal bugs that were shook out.
      Unfortunately, more grave side effects have been identified that will
      force changes outside of eCryptfs. Because the lower filesystem isn't
      consulted until page writeback, eCryptfs has no way to pass lower write
      errors (ENOSPC, mainly) back to userspace. Additionaly, it was reported
      that quotas could be bypassed because of the way eCryptfs may sometimes
      open the lower filesystem using a privileged kthread.
      
      It would be nice to resolve the latest issues, but it is best if the
      eCryptfs commits be reverted to the old behavior in the meantime.
      
      This reverts:
      32001d6f "eCryptfs: Flush file in vma close"
      5be79de2 "eCryptfs: Flush dirty pages in setattr"
      57db4e8d "ecryptfs: modify write path to encrypt page in writepage"
      Signed-off-by: NTyler Hicks <tyhicks@canonical.com>
      Tested-by: NColin King <colin.king@canonical.com>
      Cc: Colin King <colin.king@canonical.com>
      Cc: Thieu Le <thieule@google.com>
      821f7494
  20. 09 7月, 2012 1 次提交
    • T
      eCryptfs: Initialize empty lower files when opening them · e3ccaa97
      Tyler Hicks 提交于
      Historically, eCryptfs has only initialized lower files in the
      ecryptfs_create() path. Lower file initialization is the act of writing
      the cryptographic metadata from the inode's crypt_stat to the header of
      the file. The ecryptfs_open() path already expects that metadata to be
      in the header of the file.
      
      A number of users have reported empty lower files in beneath their
      eCryptfs mounts. Most of the causes for those empty files being left
      around have been addressed, but the presence of empty files causes
      problems due to the lack of proper cryptographic metadata.
      
      To transparently solve this problem, this patch initializes empty lower
      files in the ecryptfs_open() error path. If the metadata is unreadable
      due to the lower inode size being 0, plaintext passthrough support is
      not in use, and the metadata is stored in the header of the file (as
      opposed to the user.ecryptfs extended attribute), the lower file will be
      initialized.
      
      The number of nested conditionals in ecryptfs_open() was getting out of
      hand, so a helper function was created. To avoid the same nested
      conditional problem, the conditional logic was reversed inside of the
      helper function.
      
      https://launchpad.net/bugs/911507Signed-off-by: NTyler Hicks <tyhicks@canonical.com>
      Cc: John Johansen <john.johansen@canonical.com>
      Cc: Colin Ian King <colin.king@canonical.com>
      e3ccaa97
  21. 21 3月, 2012 1 次提交
  22. 24 11月, 2011 1 次提交
  23. 21 7月, 2011 1 次提交
    • J
      fs: push i_mutex and filemap_write_and_wait down into ->fsync() handlers · 02c24a82
      Josef Bacik 提交于
      Btrfs needs to be able to control how filemap_write_and_wait_range() is called
      in fsync to make it less of a painful operation, so push down taking i_mutex and
      the calling of filemap_write_and_wait() down into the ->fsync() handlers.  Some
      file systems can drop taking the i_mutex altogether it seems, like ext3 and
      ocfs2.  For correctness sake I just pushed everything down in all cases to make
      sure that we keep the current behavior the same for everybody, and then each
      individual fs maintainer can make up their mind about what to do from there.
      Thanks,
      Acked-by: NJan Kara <jack@suse.cz>
      Signed-off-by: NJosef Bacik <josef@redhat.com>
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      02c24a82
  24. 30 5月, 2011 1 次提交
  25. 26 4月, 2011 2 次提交
    • T
      eCryptfs: Handle failed metadata read in lookup · 3aeb86ea
      Tyler Hicks 提交于
      When failing to read the lower file's crypto metadata during a lookup,
      eCryptfs must continue on without throwing an error. For example, there
      may be a plaintext file in the lower mount point that the user wants to
      delete through the eCryptfs mount.
      
      If an error is encountered while reading the metadata in lookup(), the
      eCryptfs inode's size could be incorrect. We must be sure to reread the
      plaintext inode size from the metadata when performing an open() or
      setattr(). The metadata is already being read in those paths, so this
      adds minimal performance overhead.
      
      This patch introduces a flag which will track whether or not the
      plaintext inode size has been read so that an incorrect i_size can be
      fixed in the open() or setattr() paths.
      
      https://bugs.launchpad.net/bugs/509180
      
      Cc: <stable@kernel.org>
      Signed-off-by: NTyler Hicks <tyhicks@linux.vnet.ibm.com>
      3aeb86ea
    • T
      eCryptfs: Add reference counting to lower files · 332ab16f
      Tyler Hicks 提交于
      For any given lower inode, eCryptfs keeps only one lower file open and
      multiplexes all eCryptfs file operations through that lower file. The
      lower file was considered "persistent" and stayed open from the first
      lookup through the lifetime of the inode.
      
      This patch keeps the notion of a single, per-inode lower file, but adds
      reference counting around the lower file so that it is closed when not
      currently in use. If the reference count is at 0 when an operation (such
      as open, create, etc.) needs to use the lower file, a new lower file is
      opened. Since the file is no longer persistent, all references to the
      term persistent file are changed to lower file.
      
      Locking is added around the sections of code that opens the lower file
      and assign the pointer in the inode info, as well as the code the fputs
      the lower file when all eCryptfs users are done with it.
      
      This patch is needed to fix issues, when mounted on top of the NFSv3
      client, where the lower file is left silly renamed until the eCryptfs
      inode is destroyed.
      Signed-off-by: NTyler Hicks <tyhicks@linux.vnet.ibm.com>
      332ab16f
  26. 28 3月, 2011 1 次提交
  27. 22 2月, 2011 1 次提交
  28. 18 1月, 2011 4 次提交
  29. 15 10月, 2010 1 次提交
    • A
      llseek: automatically add .llseek fop · 6038f373
      Arnd Bergmann 提交于
      All file_operations should get a .llseek operation so we can make
      nonseekable_open the default for future file operations without a
      .llseek pointer.
      
      The three cases that we can automatically detect are no_llseek, seq_lseek
      and default_llseek. For cases where we can we can automatically prove that
      the file offset is always ignored, we use noop_llseek, which maintains
      the current behavior of not returning an error from a seek.
      
      New drivers should normally not use noop_llseek but instead use no_llseek
      and call nonseekable_open at open time.  Existing drivers can be converted
      to do the same when the maintainer knows for certain that no user code
      relies on calling seek on the device file.
      
      The generated code is often incorrectly indented and right now contains
      comments that clarify for each added line why a specific variant was
      chosen. In the version that gets submitted upstream, the comments will
      be gone and I will manually fix the indentation, because there does not
      seem to be a way to do that using coccinelle.
      
      Some amount of new code is currently sitting in linux-next that should get
      the same modifications, which I will do at the end of the merge window.
      
      Many thanks to Julia Lawall for helping me learn to write a semantic
      patch that does all this.
      
      ===== begin semantic patch =====
      // This adds an llseek= method to all file operations,
      // as a preparation for making no_llseek the default.
      //
      // The rules are
      // - use no_llseek explicitly if we do nonseekable_open
      // - use seq_lseek for sequential files
      // - use default_llseek if we know we access f_pos
      // - use noop_llseek if we know we don't access f_pos,
      //   but we still want to allow users to call lseek
      //
      @ open1 exists @
      identifier nested_open;
      @@
      nested_open(...)
      {
      <+...
      nonseekable_open(...)
      ...+>
      }
      
      @ open exists@
      identifier open_f;
      identifier i, f;
      identifier open1.nested_open;
      @@
      int open_f(struct inode *i, struct file *f)
      {
      <+...
      (
      nonseekable_open(...)
      |
      nested_open(...)
      )
      ...+>
      }
      
      @ read disable optional_qualifier exists @
      identifier read_f;
      identifier f, p, s, off;
      type ssize_t, size_t, loff_t;
      expression E;
      identifier func;
      @@
      ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
      {
      <+...
      (
         *off = E
      |
         *off += E
      |
         func(..., off, ...)
      |
         E = *off
      )
      ...+>
      }
      
      @ read_no_fpos disable optional_qualifier exists @
      identifier read_f;
      identifier f, p, s, off;
      type ssize_t, size_t, loff_t;
      @@
      ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
      {
      ... when != off
      }
      
      @ write @
      identifier write_f;
      identifier f, p, s, off;
      type ssize_t, size_t, loff_t;
      expression E;
      identifier func;
      @@
      ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
      {
      <+...
      (
        *off = E
      |
        *off += E
      |
        func(..., off, ...)
      |
        E = *off
      )
      ...+>
      }
      
      @ write_no_fpos @
      identifier write_f;
      identifier f, p, s, off;
      type ssize_t, size_t, loff_t;
      @@
      ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
      {
      ... when != off
      }
      
      @ fops0 @
      identifier fops;
      @@
      struct file_operations fops = {
       ...
      };
      
      @ has_llseek depends on fops0 @
      identifier fops0.fops;
      identifier llseek_f;
      @@
      struct file_operations fops = {
      ...
       .llseek = llseek_f,
      ...
      };
      
      @ has_read depends on fops0 @
      identifier fops0.fops;
      identifier read_f;
      @@
      struct file_operations fops = {
      ...
       .read = read_f,
      ...
      };
      
      @ has_write depends on fops0 @
      identifier fops0.fops;
      identifier write_f;
      @@
      struct file_operations fops = {
      ...
       .write = write_f,
      ...
      };
      
      @ has_open depends on fops0 @
      identifier fops0.fops;
      identifier open_f;
      @@
      struct file_operations fops = {
      ...
       .open = open_f,
      ...
      };
      
      // use no_llseek if we call nonseekable_open
      ////////////////////////////////////////////
      @ nonseekable1 depends on !has_llseek && has_open @
      identifier fops0.fops;
      identifier nso ~= "nonseekable_open";
      @@
      struct file_operations fops = {
      ...  .open = nso, ...
      +.llseek = no_llseek, /* nonseekable */
      };
      
      @ nonseekable2 depends on !has_llseek @
      identifier fops0.fops;
      identifier open.open_f;
      @@
      struct file_operations fops = {
      ...  .open = open_f, ...
      +.llseek = no_llseek, /* open uses nonseekable */
      };
      
      // use seq_lseek for sequential files
      /////////////////////////////////////
      @ seq depends on !has_llseek @
      identifier fops0.fops;
      identifier sr ~= "seq_read";
      @@
      struct file_operations fops = {
      ...  .read = sr, ...
      +.llseek = seq_lseek, /* we have seq_read */
      };
      
      // use default_llseek if there is a readdir
      ///////////////////////////////////////////
      @ fops1 depends on !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier readdir_e;
      @@
      // any other fop is used that changes pos
      struct file_operations fops = {
      ... .readdir = readdir_e, ...
      +.llseek = default_llseek, /* readdir is present */
      };
      
      // use default_llseek if at least one of read/write touches f_pos
      /////////////////////////////////////////////////////////////////
      @ fops2 depends on !fops1 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier read.read_f;
      @@
      // read fops use offset
      struct file_operations fops = {
      ... .read = read_f, ...
      +.llseek = default_llseek, /* read accesses f_pos */
      };
      
      @ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier write.write_f;
      @@
      // write fops use offset
      struct file_operations fops = {
      ... .write = write_f, ...
      +	.llseek = default_llseek, /* write accesses f_pos */
      };
      
      // Use noop_llseek if neither read nor write accesses f_pos
      ///////////////////////////////////////////////////////////
      
      @ fops4 depends on !fops1 && !fops2 && !fops3 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier read_no_fpos.read_f;
      identifier write_no_fpos.write_f;
      @@
      // write fops use offset
      struct file_operations fops = {
      ...
       .write = write_f,
       .read = read_f,
      ...
      +.llseek = noop_llseek, /* read and write both use no f_pos */
      };
      
      @ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier write_no_fpos.write_f;
      @@
      struct file_operations fops = {
      ... .write = write_f, ...
      +.llseek = noop_llseek, /* write uses no f_pos */
      };
      
      @ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      identifier read_no_fpos.read_f;
      @@
      struct file_operations fops = {
      ... .read = read_f, ...
      +.llseek = noop_llseek, /* read uses no f_pos */
      };
      
      @ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
      identifier fops0.fops;
      @@
      struct file_operations fops = {
      ...
      +.llseek = noop_llseek, /* no read or write fn */
      };
      ===== End semantic patch =====
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Cc: Julia Lawall <julia@diku.dk>
      Cc: Christoph Hellwig <hch@infradead.org>
      6038f373
  30. 05 10月, 2010 1 次提交
    • A
      BKL: Remove BKL from ecryptfs · 18dfe89d
      Arnd Bergmann 提交于
      The BKL is only used in fill_super, which is protected by the superblocks
      s_umount rw_semaphorei, and in fasync, which does not do anything that
      could require the BKL. Therefore it is safe to remove the BKL entirely.
      Signed-off-by: NArnd Bergmann <arnd@arndb.de>
      Cc: Dustin Kirkland <kirkland@canonical.com>
      Cc: Tyler Hicks <tyhicks@linux.vnet.ibm.com>
      Cc: ecryptfs-devel@lists.launchpad.net
      18dfe89d
  31. 10 8月, 2010 1 次提交
    • J
      fs/ecryptfs/file.c: introduce missing free · ceeab929
      Julia Lawall 提交于
      The comments in the code indicate that file_info should be released if the
      function fails.  This releasing is done at the label out_free, not out.
      
      The semantic match that finds this problem is as follows:
      (http://www.emn.fr/x-info/coccinelle/)
      
      // <smpl>
      @r exists@
      local idexpression x;
      statement S;
      expression E;
      identifier f,f1,l;
      position p1,p2;
      expression *ptr != NULL;
      @@
      
      x@p1 = kmem_cache_zalloc(...);
      ...
      if (x == NULL) S
      <... when != x
           when != if (...) { <+...x...+> }
      (
      x->f1 = E
      |
       (x->f1 == NULL || ...)
      |
       f(...,x->f1,...)
      )
      ...>
      (
       return <+...x...+>;
      |
       return@p2 ...;
      )
      
      @script:python@
      p1 << r.p1;
      p2 << r.p2;
      @@
      
      print "* file: %s kmem_cache_zalloc %s" % (p1[0].file,p1[0].line)
      // </smpl>
      Signed-off-by: NJulia Lawall <julia@diku.dk>
      Cc: stable@kernel.org
      Signed-off-by: NTyler Hicks <tyhicks@linux.vnet.ibm.com>
      ceeab929
  32. 09 8月, 2010 1 次提交
  33. 28 5月, 2010 1 次提交