1. 23 2月, 2017 2 次提交
    • M
      fuse: cleanup fuse_file refcounting · 267d8444
      Miklos Szeredi 提交于
      struct fuse_file is stored in file->private_data.  Make this always be a
      counting reference for consistency.
      
      This also allows fuse_sync_release() to call fuse_file_put() instead of
      partially duplicating its functionality.
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      267d8444
    • M
      fuse: add missing FR_FORCE · 2e38bea9
      Miklos Szeredi 提交于
      fuse_file_put() was missing the "force" flag for the RELEASE request when
      sending synchronously (fuseblk).
      
      If this flag is not set, then a sync request may be interrupted before it
      is dequeued by the userspace filesystem.  In this case the OPEN won't be
      balanced with a RELEASE.
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      Fixes: 5a18ec17 ("fuse: fix hang of single threaded fuseblk filesystem")
      Cc: <stable@vger.kernel.org> # v2.6.38+
      2e38bea9
  2. 16 2月, 2017 1 次提交
  3. 15 2月, 2017 1 次提交
    • S
      fuse: fix use after free issue in fuse_dev_do_read() · 6ba4d272
      Sahitya Tummala 提交于
      There is a potential race between fuse_dev_do_write()
      and request_wait_answer() contexts as shown below:
      
      TASK 1:
      __fuse_request_send():
        |--spin_lock(&fiq->waitq.lock);
        |--queue_request();
        |--spin_unlock(&fiq->waitq.lock);
        |--request_wait_answer():
             |--if (test_bit(FR_SENT, &req->flags))
             <gets pre-empted after it is validated true>
                                         TASK 2:
                                         fuse_dev_do_write():
                                           |--clears bit FR_SENT,
                                           |--request_end():
                                              |--sets bit FR_FINISHED
                                              |--spin_lock(&fiq->waitq.lock);
                                              |--list_del_init(&req->intr_entry);
                                              |--spin_unlock(&fiq->waitq.lock);
                                              |--fuse_put_request();
             |--queue_interrupt();
             <request gets queued to interrupts list>
                  |--wake_up_locked(&fiq->waitq);
             |--wait_event_freezable();
             <as FR_FINISHED is set, it returns and then
             the caller frees this request>
      
      Now, the next fuse_dev_do_read(), see interrupts list is not empty
      and then calls fuse_read_interrupt() which tries to access the request
      which is already free'd and gets the below crash:
      
      [11432.401266] Unable to handle kernel paging request at virtual address
      6b6b6b6b6b6b6b6b
      ...
      [11432.418518] Kernel BUG at ffffff80083720e0
      [11432.456168] PC is at __list_del_entry+0x6c/0xc4
      [11432.463573] LR is at fuse_dev_do_read+0x1ac/0x474
      ...
      [11432.679999] [<ffffff80083720e0>] __list_del_entry+0x6c/0xc4
      [11432.687794] [<ffffff80082c65e0>] fuse_dev_do_read+0x1ac/0x474
      [11432.693180] [<ffffff80082c6b14>] fuse_dev_read+0x6c/0x78
      [11432.699082] [<ffffff80081d5638>] __vfs_read+0xc0/0xe8
      [11432.704459] [<ffffff80081d5efc>] vfs_read+0x90/0x108
      [11432.709406] [<ffffff80081d67f0>] SyS_read+0x58/0x94
      
      As FR_FINISHED bit is set before deleting the intr_entry with input
      queue lock in request completion path, do the testing of this flag and
      queueing atomically with the same lock in queue_interrupt().
      Signed-off-by: NSahitya Tummala <stummala@codeaurora.org>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      Fixes: fd22d62e ("fuse: no fc->lock for iqueue parts")
      Cc: <stable@vger.kernel.org> # 4.2+
      6ba4d272
  4. 14 1月, 2017 1 次提交
  5. 13 1月, 2017 1 次提交
    • T
      fuse: clear FR_PENDING flag when moving requests out of pending queue · a8a86d78
      Tahsin Erdogan 提交于
      fuse_abort_conn() moves requests from pending list to a temporary list
      before canceling them. This operation races with request_wait_answer()
      which also tries to remove the request after it gets a fatal signal. It
      checks FR_PENDING flag to determine whether the request is still in the
      pending list.
      
      Make fuse_abort_conn() clear FR_PENDING flag so that request_wait_answer()
      does not remove the request from temporary list.
      
      This bug causes an Oops when trying to delete an already deleted list entry
      in end_requests().
      
      Fixes: ee314a87 ("fuse: abort: no fc->lock needed for request ending")
      Signed-off-by: NTahsin Erdogan <tahsin@google.com>
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      Cc: <stable@vger.kernel.org> # 4.2+
      a8a86d78
  6. 09 12月, 2016 1 次提交
  7. 06 12月, 2016 1 次提交
    • M
      fuse: fix clearing suid, sgid for chown() · c01638f5
      Miklos Szeredi 提交于
      Basically, the pjdfstests set the ownership of a file to 06555, and then
      chowns it (as root) to a new uid/gid. Prior to commit a09f99ed ("fuse:
      fix killing s[ug]id in setattr"), fuse would send down a setattr with both
      the uid/gid change and a new mode.  Now, it just sends down the uid/gid
      change.
      
      Technically this is NOTABUG, since POSIX doesn't _require_ that we clear
      these bits for a privileged process, but Linux (wisely) has done that and I
      think we don't want to change that behavior here.
      
      This is caused by the use of should_remove_suid(), which will always return
      0 when the process has CAP_FSETID.
      
      In fact we really don't need to be calling should_remove_suid() at all,
      since we've already been indicated that we should remove the suid, we just
      don't want to use a (very) stale mode for that.
      
      This patch should fix the above as well as simplify the logic.
      
      Reported-by: Jeff Layton <jlayton@redhat.com> 
      Signed-off-by: NMiklos Szeredi <mszeredi@redhat.com>
      Fixes: a09f99ed ("fuse: fix killing s[ug]id in setattr")
      Cc: <stable@vger.kernel.org>
      Reviewed-by: NJeff Layton <jlayton@redhat.com>
      c01638f5
  8. 15 11月, 2016 1 次提交
  9. 18 10月, 2016 1 次提交
  10. 08 10月, 2016 1 次提交
  11. 06 10月, 2016 4 次提交
  12. 04 10月, 2016 2 次提交
    • A
      fuse_dev_splice_read(): switch to add_to_pipe() · d82718e3
      Al Viro 提交于
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      d82718e3
    • A
      splice: lift pipe_lock out of splice_to_pipe() · 8924feff
      Al Viro 提交于
      * splice_to_pipe() stops at pipe overflow and does *not* take pipe_lock
      * ->splice_read() instances do the same
      * vmsplice_to_pipe() and do_splice() (ultimate callers of splice_to_pipe())
        arrange for waiting, looping, etc. themselves.
      
      That should make pipe_lock the outermost one.
      
      Unfortunately, existing rules for the amount passed by vmsplice_to_pipe()
      and do_splice() are quite ugly _and_ userland code can be easily broken
      by changing those.  It's not even "no more than the maximal capacity of
      this pipe" - it's "once we'd fed pipe->nr_buffers pages into the pipe,
      leave instead of waiting".
      
      Considering how poorly these rules are documented, let's try "wait for some
      space to appear, unless given SPLICE_F_NONBLOCK, then push into pipe
      and if we run into overflow, we are done".
      Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
      8924feff
  13. 03 10月, 2016 1 次提交
  14. 01 10月, 2016 12 次提交
  15. 28 9月, 2016 2 次提交
  16. 27 9月, 2016 1 次提交
  17. 22 9月, 2016 2 次提交
  18. 25 8月, 2016 1 次提交
  19. 31 7月, 2016 1 次提交
  20. 29 7月, 2016 3 次提交