Commit 65cfc6722361570bfe255698d9cd4dccaf47570d
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
fs/open.c
... | ... | @@ -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); |
fs/stat.c
... | ... | @@ -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 |
-
mentioned in commit b0917c