diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2011-01-29 18:43:42 +0530 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-15 17:16:05 -0400 |
commit | 11a7b371b64ef39fc5fb1b6f2218eef7c4d035e3 (patch) | |
tree | 7d2059c9570e24c7d742eedfeedf19743d05a744 /fs | |
parent | 326be7b484843988afe57566b627fb7a70beac56 (diff) | |
download | linux-11a7b371b64ef39fc5fb1b6f2218eef7c4d035e3.tar.bz2 |
fs: allow AT_EMPTY_PATH in linkat(), limit that to CAP_DAC_READ_SEARCH
We don't want to allow creation of private hardlinks by different application
using the fd passed to them via SCM_RIGHTS. So limit the null relative name
usage in linkat syscall to CAP_DAC_READ_SEARCH
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/namei.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/namei.c b/fs/namei.c index 9d4f32700179..c9b7f5b7e92a 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2945,15 +2945,27 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, struct dentry *new_dentry; struct nameidata nd; struct path old_path; + int how = 0; int error; char *to; - if ((flags & ~AT_SYMLINK_FOLLOW) != 0) + if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) return -EINVAL; + /* + * To use null names we require CAP_DAC_READ_SEARCH + * This ensures that not everyone will be able to create + * handlink using the passed filedescriptor. + */ + if (flags & AT_EMPTY_PATH) { + if (!capable(CAP_DAC_READ_SEARCH)) + return -ENOENT; + how = LOOKUP_EMPTY; + } + + if (flags & AT_SYMLINK_FOLLOW) + how |= LOOKUP_FOLLOW; - error = user_path_at(olddfd, oldname, - flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0, - &old_path); + error = user_path_at(olddfd, oldname, how, &old_path); if (error) return error; |