Forum | Documentation | Website | Blog

Skip to content
Snippets Groups Projects
  1. May 17, 2023
  2. Aug 20, 2022
  3. Nov 06, 2021
  4. Sep 02, 2021
  5. May 18, 2021
    • Al Viro's avatar
      getcwd(2): clean up error handling · e4b27553
      Al Viro authored
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      e4b27553
    • Al Viro's avatar
      cf4febc1
    • Al Viro's avatar
      d_path: prepend_path(): lift the inner loop into a new helper · 008673ff
      Al Viro authored
      
      ... and leave the rename_lock/mount_lock handling in prepend_path()
      itself
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      008673ff
    • Al Viro's avatar
      d_path: prepend_path(): lift resetting b in case when we'd return 3 out of loop · 2dac0ad1
      Al Viro authored
      
      preparation to extracting the loop into helper (next commit)
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      2dac0ad1
    • Al Viro's avatar
      d_path: prepend_path(): get rid of vfsmnt · 7c0d552f
      Al Viro authored
      
      it's kept equal to &mnt->mnt all along.
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      7c0d552f
    • Al Viro's avatar
      d_path: introduce struct prepend_buffer · ad08ae58
      Al Viro authored
      
              We've a lot of places where we have pairs of form (pointer to end
      of buffer, amount of space left in front of that).  These sit in pairs of
      variables located next to each other and usually passed by reference.
      Turn those into instances of new type (struct prepend_buffer) and pass
      reference to the pair instead of pairs of references to its fields.
      
      Declared and initialized by DECLARE_BUFFER(name, buf, buflen).
      
      extract_string(prepend_buffer) returns the buffer contents if
      no overflow has happened, ERR_PTR(ENAMETOOLONG) otherwise.
      All places where we used to have that boilerplate converted to use
      of that helper.
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      ad08ae58
    • Al Viro's avatar
      d_path: make prepend_name() boolean · 95b55c42
      Al Viro authored
      
      It returns only 0 or -ENAMETOOLONG and both callers only check if
      the result is negative.  Might as well return true on success and
      false on failure...
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      95b55c42
    • Al Viro's avatar
      d_path: lift -ENAMETOOLONG handling into callers of prepend_path() · 01a4428e
      Al Viro authored
      
      The only negative value ever returned by prepend_path() is -ENAMETOOLONG
      and callers can recognize that situation (overflow) by looking at the
      sign of buflen.  Lift that into the callers; we already have the
      same logics (buf if buflen is non-negative, ERR_PTR(-ENAMETOOLONG) otherwise)
      in several places and that'll become a new primitive several commits down
      the road.
      
      Make prepend_path() return 0 instead of -ENAMETOOLONG.  That makes for
      saner calling conventions (0/1/2/3/-ENAMETOOLONG is obnoxious) and
      callers actually get simpler, especially once the aforementioned
      primitive gets added.
      
      In prepend_path() itself we switch prepending the / (in case of
      empty path) to use of prepend() - no need to open-code that, compiler
      will do the right thing.  It's exactly the same logics as in
      __dentry_path().
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      01a4428e
    • Al Viro's avatar
      d_path: don't bother with return value of prepend() · d8548232
      Al Viro authored
      
      Only simple_dname() checks it, and there we can simply do those
      calls and check for overflow (by looking of negative buflen)
      in the end.
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      d8548232
    • Al Viro's avatar
      getcwd(2): saner logics around prepend_path() call · a0378fb9
      Al Viro authored
      
      The only negative value that might get returned by prepend_path() is
      -ENAMETOOLONG, and that happens only on overflow.  The same goes for
      prepend_unreachable().  Overflow is detectable by observing negative
      buflen, so we can simplify the control flow around the prepend_path()
      call.  Expand prepend_unreachable(), while we are at it - that's the
      only caller.
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      a0378fb9
    • Al Viro's avatar
      d_path: get rid of path_with_deleted() · 9024348f
      Al Viro authored
      
      expand in the sole caller; transform the initial prepends similar to
      what we'd done in dentry_path() (prepend_path() will fail the right
      way if we call it with negative buflen, same as __dentry_path() does).
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      9024348f
    • Al Viro's avatar
      d_path: regularize handling of root dentry in __dentry_path() · 3acca043
      Al Viro authored
      
      All path-forming primitives boil down to sequence of prepend_name()
      on dentries encountered along the way toward root.  Each time we prepend
      / + dentry name to the buffer.  Normally that does exactly what we want,
      but there's a corner case when we don't call prepend_name() at all (in case
      of __dentry_path() that happens if we are given root dentry).  We obviously
      want to end up with "/", rather than "", so this corner case needs to be
      handled.
      
      __dentry_path() used to manually put '/' in the end of buffer before
      doing anything else, to be overwritten by the first call of prepend_name()
      if one happens and to be left in place if we don't call prepend_name() at
      all.  That required manually checking that we had space in the buffer
      (prepend_name() and prepend() take care of such checks themselves) and lead
      to clumsy keeping track of return value.
      
      A better approach is to check if the main loop has added anything
      into the buffer and prepend "/" if it hasn't.  A side benefit of using prepend()
      is that it does the right thing if we'd already run out of buffer, making
      the overflow-handling logics simpler.
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      3acca043
  6. May 17, 2021
    • Al Viro's avatar
      d_path: saner calling conventions for __dentry_path() · 3a291c97
      Al Viro authored
      
      1) lift NUL-termination into the callers
      2) pass pointer to the end of buffer instead of that to beginning.
      
      (1) allows to simplify dentry_path() - we don't need to play silly
      games with restoring the leading / of "//deleted" after __dentry_path()
      would've overwritten it with NUL.
      
      We also do not need to check if (either) prepend() in there fails -
      if the buffer is not large enough, we'll end with negative buflen
      after prepend() and __dentry_path() will return the right value
      (ERR_PTR(-ENAMETOOLONG)) just fine.
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      3a291c97
    • Al Viro's avatar
      d_path: "\0" is {0,0}, not {0} · dfe50876
      Al Viro authored
      
      Single-element array consisting of one NUL is spelled ""...
      
      Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      dfe50876
  7. Mar 21, 2021
  8. Oct 14, 2020
    • Andrii Nakryiko's avatar
      fs: fix NULL dereference due to data race in prepend_path() · 09cad075
      Andrii Nakryiko authored
      Fix data race in prepend_path() with re-reading mnt->mnt_ns twice
      without holding the lock.
      
      is_mounted() does check for NULL, but is_anon_ns(mnt->mnt_ns) might
      re-read the pointer again which could be NULL already, if in between
      reads one of kern_unmount()/kern_unmount_array()/umount_tree() sets
      mnt->mnt_ns to NULL.
      
      This is seen in production with the following stack trace:
      
        BUG: kernel NULL pointer dereference, address: 0000000000000048
        ...
        RIP: 0010:prepend_path.isra.4+0x1ce/0x2e0
        Call Trace:
          d_path+0xe6/0x150
          proc_pid_readlink+0x8f/0x100
          vfs_readlink+0xf8/0x110
          do_readlinkat+0xfd/0x120
          __x64_sys_readlinkat+0x1a/0x20
          do_syscall_64+0x42/0x110
          entry_SYSCALL_64_after_hwframe+0x44/0xa9
      
      Fixes: f2683bd8
      
       ("[PATCH] fix d_absolute_path() interplay with fsmount()")
      Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
      Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
      Cc: Alexander Viro <viro@zeniv.linux.org.uk>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      09cad075
  9. Aug 30, 2019
  10. May 21, 2019
  11. Mar 29, 2018