Commit 65cfc6722361570bfe255698d9cd4dccaf47570d

Authored by Al Viro
1 parent bcda76524c

readlinkat(), fchownat() and fstatat() with empty relative pathnames

For readlinkat() we simply allow empty pathname; it will fail unless
we have dfd equal to O_PATH-opened symlink, so we are outside of
POSIX scope here.  For fchownat() and fstatat() we allow AT_EMPTY_PATH;
let the caller explicitly ask for such behaviour.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Showing 2 changed files with 11 additions and 6 deletions Side-by-side Diff

... ... @@ -573,13 +573,15 @@
573 573 {
574 574 struct path path;
575 575 int error = -EINVAL;
576   - int follow;
  576 + int lookup_flags;
577 577  
578   - if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
  578 + if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
579 579 goto out;
580 580  
581   - follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
582   - error = user_path_at(dfd, filename, follow, &path);
  581 + lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
  582 + if (flag & AT_EMPTY_PATH)
  583 + lookup_flags |= LOOKUP_EMPTY;
  584 + error = user_path_at(dfd, filename, lookup_flags, &path);
583 585 if (error)
584 586 goto out;
585 587 error = mnt_want_write(path.mnt);
... ... @@ -75,13 +75,16 @@
75 75 int error = -EINVAL;
76 76 int lookup_flags = 0;
77 77  
78   - if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT)) != 0)
  78 + if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
  79 + AT_EMPTY_PATH)) != 0)
79 80 goto out;
80 81  
81 82 if (!(flag & AT_SYMLINK_NOFOLLOW))
82 83 lookup_flags |= LOOKUP_FOLLOW;
83 84 if (flag & AT_NO_AUTOMOUNT)
84 85 lookup_flags |= LOOKUP_NO_AUTOMOUNT;
  86 + if (flag & AT_EMPTY_PATH)
  87 + lookup_flags |= LOOKUP_EMPTY;
85 88  
86 89 error = user_path_at(dfd, filename, lookup_flags, &path);
87 90 if (error)
... ... @@ -297,7 +300,7 @@
297 300 if (bufsiz <= 0)
298 301 return -EINVAL;
299 302  
300   - error = user_path_at(dfd, pathname, 0, &path);
  303 + error = user_path_at(dfd, pathname, LOOKUP_EMPTY, &path);
301 304 if (!error) {
302 305 struct inode *inode = path.dentry->d_inode;
303 306