diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-13 15:56:26 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-15 02:21:45 -0400 |
commit | 65cfc6722361570bfe255698d9cd4dccaf47570d (patch) | |
tree | d98ac0a392cf9abc1bbc3363448c8e072504c6a4 /fs/stat.c | |
parent | bcda76524cd1fa32af748536f27f674a13e56700 (diff) | |
download | lwn-65cfc6722361570bfe255698d9cd4dccaf47570d.tar.gz lwn-65cfc6722361570bfe255698d9cd4dccaf47570d.zip |
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>
Diffstat (limited to 'fs/stat.c')
-rw-r--r-- | fs/stat.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/stat.c b/fs/stat.c index d5c61cf2b703..961039121cb8 100644 --- a/fs/stat.c +++ b/fs/stat.c @@ -75,13 +75,16 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat, int error = -EINVAL; int lookup_flags = 0; - if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT)) != 0) + if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | + AT_EMPTY_PATH)) != 0) goto out; if (!(flag & AT_SYMLINK_NOFOLLOW)) lookup_flags |= LOOKUP_FOLLOW; if (flag & AT_NO_AUTOMOUNT) lookup_flags |= LOOKUP_NO_AUTOMOUNT; + if (flag & AT_EMPTY_PATH) + lookup_flags |= LOOKUP_EMPTY; error = user_path_at(dfd, filename, lookup_flags, &path); if (error) @@ -297,7 +300,7 @@ SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname, if (bufsiz <= 0) return -EINVAL; - error = user_path_at(dfd, pathname, 0, &path); + error = user_path_at(dfd, pathname, LOOKUP_EMPTY, &path); if (!error) { struct inode *inode = path.dentry->d_inode; |