diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2011-01-29 08:13:42 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-15 17:16:05 -0400 |
commit | 11a7b371b64ef39fc5fb1b6f2218eef7c4d035e3 (patch) | |
tree | 7d2059c9570e24c7d742eedfeedf19743d05a744 /fs/namei.c | |
parent | 326be7b484843988afe57566b627fb7a70beac56 (diff) |
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/namei.c')
-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, | |||
2945 | struct dentry *new_dentry; | 2945 | struct dentry *new_dentry; |
2946 | struct nameidata nd; | 2946 | struct nameidata nd; |
2947 | struct path old_path; | 2947 | struct path old_path; |
2948 | int how = 0; | ||
2948 | int error; | 2949 | int error; |
2949 | char *to; | 2950 | char *to; |
2950 | 2951 | ||
2951 | if ((flags & ~AT_SYMLINK_FOLLOW) != 0) | 2952 | if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) |
2952 | return -EINVAL; | 2953 | return -EINVAL; |
2954 | /* | ||
2955 | * To use null names we require CAP_DAC_READ_SEARCH | ||
2956 | * This ensures that not everyone will be able to create | ||
2957 | * handlink using the passed filedescriptor. | ||
2958 | */ | ||
2959 | if (flags & AT_EMPTY_PATH) { | ||
2960 | if (!capable(CAP_DAC_READ_SEARCH)) | ||
2961 | return -ENOENT; | ||
2962 | how = LOOKUP_EMPTY; | ||
2963 | } | ||
2964 | |||
2965 | if (flags & AT_SYMLINK_FOLLOW) | ||
2966 | how |= LOOKUP_FOLLOW; | ||
2953 | 2967 | ||
2954 | error = user_path_at(olddfd, oldname, | 2968 | error = user_path_at(olddfd, oldname, how, &old_path); |
2955 | flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0, | ||
2956 | &old_path); | ||
2957 | if (error) | 2969 | if (error) |
2958 | return error; | 2970 | return error; |
2959 | 2971 | ||