diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ioctl.c | 2 | ||||
-rw-r--r-- | fs/compat.c | 12 | ||||
-rw-r--r-- | fs/exec.c | 14 | ||||
-rw-r--r-- | fs/filesystems.c | 4 | ||||
-rw-r--r-- | fs/internal.h | 4 | ||||
-rw-r--r-- | fs/namei.c | 213 | ||||
-rw-r--r-- | fs/namespace.c | 4 | ||||
-rw-r--r-- | fs/open.c | 29 | ||||
-rw-r--r-- | fs/proc/base.c | 5 | ||||
-rw-r--r-- | fs/quota/quota.c | 4 | ||||
-rw-r--r-- | fs/xattr.c | 8 |
11 files changed, 194 insertions, 105 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index e568c472f807..61168805f175 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -638,7 +638,7 @@ static int btrfs_may_delete(struct inode *dir,struct dentry *victim,int isdir) | |||
638 | return -ENOENT; | 638 | return -ENOENT; |
639 | 639 | ||
640 | BUG_ON(victim->d_parent->d_inode != dir); | 640 | BUG_ON(victim->d_parent->d_inode != dir); |
641 | audit_inode_child(victim, dir); | 641 | audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); |
642 | 642 | ||
643 | error = inode_permission(dir, MAY_WRITE | MAY_EXEC); | 643 | error = inode_permission(dir, MAY_WRITE | MAY_EXEC); |
644 | if (error) | 644 | if (error) |
diff --git a/fs/compat.c b/fs/compat.c index b7a24d0ca30d..015e1e1f87c6 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -776,16 +776,16 @@ asmlinkage long compat_sys_mount(const char __user * dev_name, | |||
776 | char *kernel_type; | 776 | char *kernel_type; |
777 | unsigned long data_page; | 777 | unsigned long data_page; |
778 | char *kernel_dev; | 778 | char *kernel_dev; |
779 | char *dir_page; | 779 | struct filename *dir; |
780 | int retval; | 780 | int retval; |
781 | 781 | ||
782 | retval = copy_mount_string(type, &kernel_type); | 782 | retval = copy_mount_string(type, &kernel_type); |
783 | if (retval < 0) | 783 | if (retval < 0) |
784 | goto out; | 784 | goto out; |
785 | 785 | ||
786 | dir_page = getname(dir_name); | 786 | dir = getname(dir_name); |
787 | retval = PTR_ERR(dir_page); | 787 | retval = PTR_ERR(dir); |
788 | if (IS_ERR(dir_page)) | 788 | if (IS_ERR(dir)) |
789 | goto out1; | 789 | goto out1; |
790 | 790 | ||
791 | retval = copy_mount_string(dev_name, &kernel_dev); | 791 | retval = copy_mount_string(dev_name, &kernel_dev); |
@@ -807,7 +807,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name, | |||
807 | } | 807 | } |
808 | } | 808 | } |
809 | 809 | ||
810 | retval = do_mount(kernel_dev, dir_page, kernel_type, | 810 | retval = do_mount(kernel_dev, dir->name, kernel_type, |
811 | flags, (void*)data_page); | 811 | flags, (void*)data_page); |
812 | 812 | ||
813 | out4: | 813 | out4: |
@@ -815,7 +815,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name, | |||
815 | out3: | 815 | out3: |
816 | kfree(kernel_dev); | 816 | kfree(kernel_dev); |
817 | out2: | 817 | out2: |
818 | putname(dir_page); | 818 | putname(dir); |
819 | out1: | 819 | out1: |
820 | kfree(kernel_type); | 820 | kfree(kernel_type); |
821 | out: | 821 | out: |
@@ -105,7 +105,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt) | |||
105 | SYSCALL_DEFINE1(uselib, const char __user *, library) | 105 | SYSCALL_DEFINE1(uselib, const char __user *, library) |
106 | { | 106 | { |
107 | struct file *file; | 107 | struct file *file; |
108 | char *tmp = getname(library); | 108 | struct filename *tmp = getname(library); |
109 | int error = PTR_ERR(tmp); | 109 | int error = PTR_ERR(tmp); |
110 | static const struct open_flags uselib_flags = { | 110 | static const struct open_flags uselib_flags = { |
111 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, | 111 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, |
@@ -751,13 +751,14 @@ struct file *open_exec(const char *name) | |||
751 | { | 751 | { |
752 | struct file *file; | 752 | struct file *file; |
753 | int err; | 753 | int err; |
754 | struct filename tmp = { .name = name }; | ||
754 | static const struct open_flags open_exec_flags = { | 755 | static const struct open_flags open_exec_flags = { |
755 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, | 756 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, |
756 | .acc_mode = MAY_EXEC | MAY_OPEN, | 757 | .acc_mode = MAY_EXEC | MAY_OPEN, |
757 | .intent = LOOKUP_OPEN | 758 | .intent = LOOKUP_OPEN |
758 | }; | 759 | }; |
759 | 760 | ||
760 | file = do_filp_open(AT_FDCWD, name, &open_exec_flags, LOOKUP_FOLLOW); | 761 | file = do_filp_open(AT_FDCWD, &tmp, &open_exec_flags, LOOKUP_FOLLOW); |
761 | if (IS_ERR(file)) | 762 | if (IS_ERR(file)) |
762 | goto out; | 763 | goto out; |
763 | 764 | ||
@@ -1664,10 +1665,10 @@ SYSCALL_DEFINE3(execve, | |||
1664 | const char __user *const __user *, argv, | 1665 | const char __user *const __user *, argv, |
1665 | const char __user *const __user *, envp) | 1666 | const char __user *const __user *, envp) |
1666 | { | 1667 | { |
1667 | const char *path = getname(filename); | 1668 | struct filename *path = getname(filename); |
1668 | int error = PTR_ERR(path); | 1669 | int error = PTR_ERR(path); |
1669 | if (!IS_ERR(path)) { | 1670 | if (!IS_ERR(path)) { |
1670 | error = do_execve(path, argv, envp, current_pt_regs()); | 1671 | error = do_execve(path->name, argv, envp, current_pt_regs()); |
1671 | putname(path); | 1672 | putname(path); |
1672 | } | 1673 | } |
1673 | return error; | 1674 | return error; |
@@ -1677,10 +1678,11 @@ asmlinkage long compat_sys_execve(const char __user * filename, | |||
1677 | const compat_uptr_t __user * argv, | 1678 | const compat_uptr_t __user * argv, |
1678 | const compat_uptr_t __user * envp) | 1679 | const compat_uptr_t __user * envp) |
1679 | { | 1680 | { |
1680 | const char *path = getname(filename); | 1681 | struct filename *path = getname(filename); |
1681 | int error = PTR_ERR(path); | 1682 | int error = PTR_ERR(path); |
1682 | if (!IS_ERR(path)) { | 1683 | if (!IS_ERR(path)) { |
1683 | error = compat_do_execve(path, argv, envp, current_pt_regs()); | 1684 | error = compat_do_execve(path->name, argv, envp, |
1685 | current_pt_regs()); | ||
1684 | putname(path); | 1686 | putname(path); |
1685 | } | 1687 | } |
1686 | return error; | 1688 | return error; |
diff --git a/fs/filesystems.c b/fs/filesystems.c index 96f24286667a..da165f6adcbf 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c | |||
@@ -124,7 +124,7 @@ EXPORT_SYMBOL(unregister_filesystem); | |||
124 | static int fs_index(const char __user * __name) | 124 | static int fs_index(const char __user * __name) |
125 | { | 125 | { |
126 | struct file_system_type * tmp; | 126 | struct file_system_type * tmp; |
127 | char * name; | 127 | struct filename *name; |
128 | int err, index; | 128 | int err, index; |
129 | 129 | ||
130 | name = getname(__name); | 130 | name = getname(__name); |
@@ -135,7 +135,7 @@ static int fs_index(const char __user * __name) | |||
135 | err = -EINVAL; | 135 | err = -EINVAL; |
136 | read_lock(&file_systems_lock); | 136 | read_lock(&file_systems_lock); |
137 | for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) { | 137 | for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) { |
138 | if (strcmp(tmp->name,name) == 0) { | 138 | if (strcmp(tmp->name, name->name) == 0) { |
139 | err = index; | 139 | err = index; |
140 | break; | 140 | break; |
141 | } | 141 | } |
diff --git a/fs/internal.h b/fs/internal.h index 371bcc4b1697..916b7cbf3e3e 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -97,8 +97,8 @@ struct open_flags { | |||
97 | int acc_mode; | 97 | int acc_mode; |
98 | int intent; | 98 | int intent; |
99 | }; | 99 | }; |
100 | extern struct file *do_filp_open(int dfd, const char *pathname, | 100 | extern struct file *do_filp_open(int dfd, struct filename *pathname, |
101 | const struct open_flags *op, int lookup_flags); | 101 | const struct open_flags *op, int flags); |
102 | extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, | 102 | extern struct file *do_file_open_root(struct dentry *, struct vfsmount *, |
103 | const char *, const struct open_flags *, int lookup_flags); | 103 | const char *, const struct open_flags *, int lookup_flags); |
104 | 104 | ||
diff --git a/fs/namei.c b/fs/namei.c index c1f18e4f034c..d1895f308156 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -117,18 +117,70 @@ | |||
117 | * POSIX.1 2.4: an empty pathname is invalid (ENOENT). | 117 | * POSIX.1 2.4: an empty pathname is invalid (ENOENT). |
118 | * PATH_MAX includes the nul terminator --RR. | 118 | * PATH_MAX includes the nul terminator --RR. |
119 | */ | 119 | */ |
120 | static char *getname_flags(const char __user *filename, int flags, int *empty) | 120 | void final_putname(struct filename *name) |
121 | { | 121 | { |
122 | char *result = __getname(), *err; | 122 | if (name->separate) { |
123 | __putname(name->name); | ||
124 | kfree(name); | ||
125 | } else { | ||
126 | __putname(name); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | #define EMBEDDED_NAME_MAX (PATH_MAX - sizeof(struct filename)) | ||
131 | |||
132 | static struct filename * | ||
133 | getname_flags(const char __user *filename, int flags, int *empty) | ||
134 | { | ||
135 | struct filename *result, *err; | ||
123 | int len; | 136 | int len; |
137 | long max; | ||
138 | char *kname; | ||
124 | 139 | ||
140 | result = audit_reusename(filename); | ||
141 | if (result) | ||
142 | return result; | ||
143 | |||
144 | result = __getname(); | ||
125 | if (unlikely(!result)) | 145 | if (unlikely(!result)) |
126 | return ERR_PTR(-ENOMEM); | 146 | return ERR_PTR(-ENOMEM); |
127 | 147 | ||
128 | len = strncpy_from_user(result, filename, PATH_MAX); | 148 | /* |
129 | err = ERR_PTR(len); | 149 | * First, try to embed the struct filename inside the names_cache |
130 | if (unlikely(len < 0)) | 150 | * allocation |
151 | */ | ||
152 | kname = (char *)result + sizeof(*result); | ||
153 | result->name = kname; | ||
154 | result->separate = false; | ||
155 | max = EMBEDDED_NAME_MAX; | ||
156 | |||
157 | recopy: | ||
158 | len = strncpy_from_user(kname, filename, max); | ||
159 | if (unlikely(len < 0)) { | ||
160 | err = ERR_PTR(len); | ||
131 | goto error; | 161 | goto error; |
162 | } | ||
163 | |||
164 | /* | ||
165 | * Uh-oh. We have a name that's approaching PATH_MAX. Allocate a | ||
166 | * separate struct filename so we can dedicate the entire | ||
167 | * names_cache allocation for the pathname, and re-do the copy from | ||
168 | * userland. | ||
169 | */ | ||
170 | if (len == EMBEDDED_NAME_MAX && max == EMBEDDED_NAME_MAX) { | ||
171 | kname = (char *)result; | ||
172 | |||
173 | result = kzalloc(sizeof(*result), GFP_KERNEL); | ||
174 | if (!result) { | ||
175 | err = ERR_PTR(-ENOMEM); | ||
176 | result = (struct filename *)kname; | ||
177 | goto error; | ||
178 | } | ||
179 | result->name = kname; | ||
180 | result->separate = true; | ||
181 | max = PATH_MAX; | ||
182 | goto recopy; | ||
183 | } | ||
132 | 184 | ||
133 | /* The empty path is special. */ | 185 | /* The empty path is special. */ |
134 | if (unlikely(!len)) { | 186 | if (unlikely(!len)) { |
@@ -140,30 +192,32 @@ static char *getname_flags(const char __user *filename, int flags, int *empty) | |||
140 | } | 192 | } |
141 | 193 | ||
142 | err = ERR_PTR(-ENAMETOOLONG); | 194 | err = ERR_PTR(-ENAMETOOLONG); |
143 | if (likely(len < PATH_MAX)) { | 195 | if (unlikely(len >= PATH_MAX)) |
144 | audit_getname(result); | 196 | goto error; |
145 | return result; | 197 | |
146 | } | 198 | result->uptr = filename; |
199 | audit_getname(result); | ||
200 | return result; | ||
147 | 201 | ||
148 | error: | 202 | error: |
149 | __putname(result); | 203 | final_putname(result); |
150 | return err; | 204 | return err; |
151 | } | 205 | } |
152 | 206 | ||
153 | char *getname(const char __user * filename) | 207 | struct filename * |
208 | getname(const char __user * filename) | ||
154 | { | 209 | { |
155 | return getname_flags(filename, 0, NULL); | 210 | return getname_flags(filename, 0, NULL); |
156 | } | 211 | } |
212 | EXPORT_SYMBOL(getname); | ||
157 | 213 | ||
158 | #ifdef CONFIG_AUDITSYSCALL | 214 | #ifdef CONFIG_AUDITSYSCALL |
159 | void putname(const char *name) | 215 | void putname(struct filename *name) |
160 | { | 216 | { |
161 | if (unlikely(!audit_dummy_context())) | 217 | if (unlikely(!audit_dummy_context())) |
162 | audit_putname(name); | 218 | return audit_putname(name); |
163 | else | 219 | final_putname(name); |
164 | __putname(name); | ||
165 | } | 220 | } |
166 | EXPORT_SYMBOL(putname); | ||
167 | #endif | 221 | #endif |
168 | 222 | ||
169 | static int check_acl(struct inode *inode, int mask) | 223 | static int check_acl(struct inode *inode, int mask) |
@@ -1963,24 +2017,29 @@ static int path_lookupat(int dfd, const char *name, | |||
1963 | return err; | 2017 | return err; |
1964 | } | 2018 | } |
1965 | 2019 | ||
1966 | static int do_path_lookup(int dfd, const char *name, | 2020 | static int filename_lookup(int dfd, struct filename *name, |
1967 | unsigned int flags, struct nameidata *nd) | 2021 | unsigned int flags, struct nameidata *nd) |
1968 | { | 2022 | { |
1969 | int retval = path_lookupat(dfd, name, flags | LOOKUP_RCU, nd); | 2023 | int retval = path_lookupat(dfd, name->name, flags | LOOKUP_RCU, nd); |
1970 | if (unlikely(retval == -ECHILD)) | 2024 | if (unlikely(retval == -ECHILD)) |
1971 | retval = path_lookupat(dfd, name, flags, nd); | 2025 | retval = path_lookupat(dfd, name->name, flags, nd); |
1972 | if (unlikely(retval == -ESTALE)) | 2026 | if (unlikely(retval == -ESTALE)) |
1973 | retval = path_lookupat(dfd, name, flags | LOOKUP_REVAL, nd); | 2027 | retval = path_lookupat(dfd, name->name, |
2028 | flags | LOOKUP_REVAL, nd); | ||
1974 | 2029 | ||
1975 | if (likely(!retval)) { | 2030 | if (likely(!retval)) |
1976 | if (unlikely(!audit_dummy_context())) { | 2031 | audit_inode(name, nd->path.dentry, flags & LOOKUP_PARENT); |
1977 | if (nd->path.dentry && nd->inode) | ||
1978 | audit_inode(name, nd->path.dentry); | ||
1979 | } | ||
1980 | } | ||
1981 | return retval; | 2032 | return retval; |
1982 | } | 2033 | } |
1983 | 2034 | ||
2035 | static int do_path_lookup(int dfd, const char *name, | ||
2036 | unsigned int flags, struct nameidata *nd) | ||
2037 | { | ||
2038 | struct filename filename = { .name = name }; | ||
2039 | |||
2040 | return filename_lookup(dfd, &filename, flags, nd); | ||
2041 | } | ||
2042 | |||
1984 | /* does lookup, returns the object with parent locked */ | 2043 | /* does lookup, returns the object with parent locked */ |
1985 | struct dentry *kern_path_locked(const char *name, struct path *path) | 2044 | struct dentry *kern_path_locked(const char *name, struct path *path) |
1986 | { | 2045 | { |
@@ -2098,13 +2157,13 @@ int user_path_at_empty(int dfd, const char __user *name, unsigned flags, | |||
2098 | struct path *path, int *empty) | 2157 | struct path *path, int *empty) |
2099 | { | 2158 | { |
2100 | struct nameidata nd; | 2159 | struct nameidata nd; |
2101 | char *tmp = getname_flags(name, flags, empty); | 2160 | struct filename *tmp = getname_flags(name, flags, empty); |
2102 | int err = PTR_ERR(tmp); | 2161 | int err = PTR_ERR(tmp); |
2103 | if (!IS_ERR(tmp)) { | 2162 | if (!IS_ERR(tmp)) { |
2104 | 2163 | ||
2105 | BUG_ON(flags & LOOKUP_PARENT); | 2164 | BUG_ON(flags & LOOKUP_PARENT); |
2106 | 2165 | ||
2107 | err = do_path_lookup(dfd, tmp, flags, &nd); | 2166 | err = filename_lookup(dfd, tmp, flags, &nd); |
2108 | putname(tmp); | 2167 | putname(tmp); |
2109 | if (!err) | 2168 | if (!err) |
2110 | *path = nd.path; | 2169 | *path = nd.path; |
@@ -2118,22 +2177,28 @@ int user_path_at(int dfd, const char __user *name, unsigned flags, | |||
2118 | return user_path_at_empty(dfd, name, flags, path, NULL); | 2177 | return user_path_at_empty(dfd, name, flags, path, NULL); |
2119 | } | 2178 | } |
2120 | 2179 | ||
2121 | static int user_path_parent(int dfd, const char __user *path, | 2180 | /* |
2122 | struct nameidata *nd, char **name) | 2181 | * NB: most callers don't do anything directly with the reference to the |
2182 | * to struct filename, but the nd->last pointer points into the name string | ||
2183 | * allocated by getname. So we must hold the reference to it until all | ||
2184 | * path-walking is complete. | ||
2185 | */ | ||
2186 | static struct filename * | ||
2187 | user_path_parent(int dfd, const char __user *path, struct nameidata *nd) | ||
2123 | { | 2188 | { |
2124 | char *s = getname(path); | 2189 | struct filename *s = getname(path); |
2125 | int error; | 2190 | int error; |
2126 | 2191 | ||
2127 | if (IS_ERR(s)) | 2192 | if (IS_ERR(s)) |
2128 | return PTR_ERR(s); | 2193 | return s; |
2129 | 2194 | ||
2130 | error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd); | 2195 | error = filename_lookup(dfd, s, LOOKUP_PARENT, nd); |
2131 | if (error) | 2196 | if (error) { |
2132 | putname(s); | 2197 | putname(s); |
2133 | else | 2198 | return ERR_PTR(error); |
2134 | *name = s; | 2199 | } |
2135 | 2200 | ||
2136 | return error; | 2201 | return s; |
2137 | } | 2202 | } |
2138 | 2203 | ||
2139 | /* | 2204 | /* |
@@ -2180,7 +2245,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir) | |||
2180 | return -ENOENT; | 2245 | return -ENOENT; |
2181 | 2246 | ||
2182 | BUG_ON(victim->d_parent->d_inode != dir); | 2247 | BUG_ON(victim->d_parent->d_inode != dir); |
2183 | audit_inode_child(victim, dir); | 2248 | audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); |
2184 | 2249 | ||
2185 | error = inode_permission(dir, MAY_WRITE | MAY_EXEC); | 2250 | error = inode_permission(dir, MAY_WRITE | MAY_EXEC); |
2186 | if (error) | 2251 | if (error) |
@@ -2625,7 +2690,7 @@ out_dput: | |||
2625 | */ | 2690 | */ |
2626 | static int do_last(struct nameidata *nd, struct path *path, | 2691 | static int do_last(struct nameidata *nd, struct path *path, |
2627 | struct file *file, const struct open_flags *op, | 2692 | struct file *file, const struct open_flags *op, |
2628 | int *opened, const char *pathname) | 2693 | int *opened, struct filename *name) |
2629 | { | 2694 | { |
2630 | struct dentry *dir = nd->path.dentry; | 2695 | struct dentry *dir = nd->path.dentry; |
2631 | int open_flag = op->open_flag; | 2696 | int open_flag = op->open_flag; |
@@ -2652,7 +2717,7 @@ static int do_last(struct nameidata *nd, struct path *path, | |||
2652 | error = complete_walk(nd); | 2717 | error = complete_walk(nd); |
2653 | if (error) | 2718 | if (error) |
2654 | return error; | 2719 | return error; |
2655 | audit_inode(pathname, nd->path.dentry); | 2720 | audit_inode(name, nd->path.dentry, 0); |
2656 | if (open_flag & O_CREAT) { | 2721 | if (open_flag & O_CREAT) { |
2657 | error = -EISDIR; | 2722 | error = -EISDIR; |
2658 | goto out; | 2723 | goto out; |
@@ -2662,7 +2727,7 @@ static int do_last(struct nameidata *nd, struct path *path, | |||
2662 | error = complete_walk(nd); | 2727 | error = complete_walk(nd); |
2663 | if (error) | 2728 | if (error) |
2664 | return error; | 2729 | return error; |
2665 | audit_inode(pathname, dir); | 2730 | audit_inode(name, dir, 0); |
2666 | goto finish_open; | 2731 | goto finish_open; |
2667 | } | 2732 | } |
2668 | 2733 | ||
@@ -2691,7 +2756,7 @@ static int do_last(struct nameidata *nd, struct path *path, | |||
2691 | if (error) | 2756 | if (error) |
2692 | return error; | 2757 | return error; |
2693 | 2758 | ||
2694 | audit_inode(pathname, dir); | 2759 | audit_inode(name, dir, 0); |
2695 | error = -EISDIR; | 2760 | error = -EISDIR; |
2696 | /* trailing slashes? */ | 2761 | /* trailing slashes? */ |
2697 | if (nd->last.name[nd->last.len]) | 2762 | if (nd->last.name[nd->last.len]) |
@@ -2721,7 +2786,7 @@ retry_lookup: | |||
2721 | !S_ISREG(file->f_path.dentry->d_inode->i_mode)) | 2786 | !S_ISREG(file->f_path.dentry->d_inode->i_mode)) |
2722 | will_truncate = false; | 2787 | will_truncate = false; |
2723 | 2788 | ||
2724 | audit_inode(pathname, file->f_path.dentry); | 2789 | audit_inode(name, file->f_path.dentry, 0); |
2725 | goto opened; | 2790 | goto opened; |
2726 | } | 2791 | } |
2727 | 2792 | ||
@@ -2738,7 +2803,7 @@ retry_lookup: | |||
2738 | * create/update audit record if it already exists. | 2803 | * create/update audit record if it already exists. |
2739 | */ | 2804 | */ |
2740 | if (path->dentry->d_inode) | 2805 | if (path->dentry->d_inode) |
2741 | audit_inode(pathname, path->dentry); | 2806 | audit_inode(name, path->dentry, 0); |
2742 | 2807 | ||
2743 | /* | 2808 | /* |
2744 | * If atomic_open() acquired write access it is dropped now due to | 2809 | * If atomic_open() acquired write access it is dropped now due to |
@@ -2803,7 +2868,7 @@ finish_lookup: | |||
2803 | error = -ENOTDIR; | 2868 | error = -ENOTDIR; |
2804 | if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) | 2869 | if ((nd->flags & LOOKUP_DIRECTORY) && !nd->inode->i_op->lookup) |
2805 | goto out; | 2870 | goto out; |
2806 | audit_inode(pathname, nd->path.dentry); | 2871 | audit_inode(name, nd->path.dentry, 0); |
2807 | finish_open: | 2872 | finish_open: |
2808 | if (!S_ISREG(nd->inode->i_mode)) | 2873 | if (!S_ISREG(nd->inode->i_mode)) |
2809 | will_truncate = false; | 2874 | will_truncate = false; |
@@ -2871,7 +2936,7 @@ stale_open: | |||
2871 | goto retry_lookup; | 2936 | goto retry_lookup; |
2872 | } | 2937 | } |
2873 | 2938 | ||
2874 | static struct file *path_openat(int dfd, const char *pathname, | 2939 | static struct file *path_openat(int dfd, struct filename *pathname, |
2875 | struct nameidata *nd, const struct open_flags *op, int flags) | 2940 | struct nameidata *nd, const struct open_flags *op, int flags) |
2876 | { | 2941 | { |
2877 | struct file *base = NULL; | 2942 | struct file *base = NULL; |
@@ -2886,12 +2951,12 @@ static struct file *path_openat(int dfd, const char *pathname, | |||
2886 | 2951 | ||
2887 | file->f_flags = op->open_flag; | 2952 | file->f_flags = op->open_flag; |
2888 | 2953 | ||
2889 | error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base); | 2954 | error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base); |
2890 | if (unlikely(error)) | 2955 | if (unlikely(error)) |
2891 | goto out; | 2956 | goto out; |
2892 | 2957 | ||
2893 | current->total_link_count = 0; | 2958 | current->total_link_count = 0; |
2894 | error = link_path_walk(pathname, nd); | 2959 | error = link_path_walk(pathname->name, nd); |
2895 | if (unlikely(error)) | 2960 | if (unlikely(error)) |
2896 | goto out; | 2961 | goto out; |
2897 | 2962 | ||
@@ -2937,7 +3002,7 @@ out: | |||
2937 | return file; | 3002 | return file; |
2938 | } | 3003 | } |
2939 | 3004 | ||
2940 | struct file *do_filp_open(int dfd, const char *pathname, | 3005 | struct file *do_filp_open(int dfd, struct filename *pathname, |
2941 | const struct open_flags *op, int flags) | 3006 | const struct open_flags *op, int flags) |
2942 | { | 3007 | { |
2943 | struct nameidata nd; | 3008 | struct nameidata nd; |
@@ -2956,6 +3021,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, | |||
2956 | { | 3021 | { |
2957 | struct nameidata nd; | 3022 | struct nameidata nd; |
2958 | struct file *file; | 3023 | struct file *file; |
3024 | struct filename filename = { .name = name }; | ||
2959 | 3025 | ||
2960 | nd.root.mnt = mnt; | 3026 | nd.root.mnt = mnt; |
2961 | nd.root.dentry = dentry; | 3027 | nd.root.dentry = dentry; |
@@ -2965,11 +3031,11 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt, | |||
2965 | if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) | 3031 | if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) |
2966 | return ERR_PTR(-ELOOP); | 3032 | return ERR_PTR(-ELOOP); |
2967 | 3033 | ||
2968 | file = path_openat(-1, name, &nd, op, flags | LOOKUP_RCU); | 3034 | file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU); |
2969 | if (unlikely(file == ERR_PTR(-ECHILD))) | 3035 | if (unlikely(file == ERR_PTR(-ECHILD))) |
2970 | file = path_openat(-1, name, &nd, op, flags); | 3036 | file = path_openat(-1, &filename, &nd, op, flags); |
2971 | if (unlikely(file == ERR_PTR(-ESTALE))) | 3037 | if (unlikely(file == ERR_PTR(-ESTALE))) |
2972 | file = path_openat(-1, name, &nd, op, flags | LOOKUP_REVAL); | 3038 | file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_REVAL); |
2973 | return file; | 3039 | return file; |
2974 | } | 3040 | } |
2975 | 3041 | ||
@@ -3044,11 +3110,11 @@ EXPORT_SYMBOL(done_path_create); | |||
3044 | 3110 | ||
3045 | struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir) | 3111 | struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir) |
3046 | { | 3112 | { |
3047 | char *tmp = getname(pathname); | 3113 | struct filename *tmp = getname(pathname); |
3048 | struct dentry *res; | 3114 | struct dentry *res; |
3049 | if (IS_ERR(tmp)) | 3115 | if (IS_ERR(tmp)) |
3050 | return ERR_CAST(tmp); | 3116 | return ERR_CAST(tmp); |
3051 | res = kern_path_create(dfd, tmp, path, is_dir); | 3117 | res = kern_path_create(dfd, tmp->name, path, is_dir); |
3052 | putname(tmp); | 3118 | putname(tmp); |
3053 | return res; | 3119 | return res; |
3054 | } | 3120 | } |
@@ -3253,13 +3319,13 @@ out: | |||
3253 | static long do_rmdir(int dfd, const char __user *pathname) | 3319 | static long do_rmdir(int dfd, const char __user *pathname) |
3254 | { | 3320 | { |
3255 | int error = 0; | 3321 | int error = 0; |
3256 | char * name; | 3322 | struct filename *name; |
3257 | struct dentry *dentry; | 3323 | struct dentry *dentry; |
3258 | struct nameidata nd; | 3324 | struct nameidata nd; |
3259 | 3325 | ||
3260 | error = user_path_parent(dfd, pathname, &nd, &name); | 3326 | name = user_path_parent(dfd, pathname, &nd); |
3261 | if (error) | 3327 | if (IS_ERR(name)) |
3262 | return error; | 3328 | return PTR_ERR(name); |
3263 | 3329 | ||
3264 | switch(nd.last_type) { | 3330 | switch(nd.last_type) { |
3265 | case LAST_DOTDOT: | 3331 | case LAST_DOTDOT: |
@@ -3348,14 +3414,14 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
3348 | static long do_unlinkat(int dfd, const char __user *pathname) | 3414 | static long do_unlinkat(int dfd, const char __user *pathname) |
3349 | { | 3415 | { |
3350 | int error; | 3416 | int error; |
3351 | char *name; | 3417 | struct filename *name; |
3352 | struct dentry *dentry; | 3418 | struct dentry *dentry; |
3353 | struct nameidata nd; | 3419 | struct nameidata nd; |
3354 | struct inode *inode = NULL; | 3420 | struct inode *inode = NULL; |
3355 | 3421 | ||
3356 | error = user_path_parent(dfd, pathname, &nd, &name); | 3422 | name = user_path_parent(dfd, pathname, &nd); |
3357 | if (error) | 3423 | if (IS_ERR(name)) |
3358 | return error; | 3424 | return PTR_ERR(name); |
3359 | 3425 | ||
3360 | error = -EISDIR; | 3426 | error = -EISDIR; |
3361 | if (nd.last_type != LAST_NORM) | 3427 | if (nd.last_type != LAST_NORM) |
@@ -3439,7 +3505,7 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, | |||
3439 | int, newdfd, const char __user *, newname) | 3505 | int, newdfd, const char __user *, newname) |
3440 | { | 3506 | { |
3441 | int error; | 3507 | int error; |
3442 | char *from; | 3508 | struct filename *from; |
3443 | struct dentry *dentry; | 3509 | struct dentry *dentry; |
3444 | struct path path; | 3510 | struct path path; |
3445 | 3511 | ||
@@ -3452,9 +3518,9 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, | |||
3452 | if (IS_ERR(dentry)) | 3518 | if (IS_ERR(dentry)) |
3453 | goto out_putname; | 3519 | goto out_putname; |
3454 | 3520 | ||
3455 | error = security_path_symlink(&path, dentry, from); | 3521 | error = security_path_symlink(&path, dentry, from->name); |
3456 | if (!error) | 3522 | if (!error) |
3457 | error = vfs_symlink(path.dentry->d_inode, dentry, from); | 3523 | error = vfs_symlink(path.dentry->d_inode, dentry, from->name); |
3458 | done_path_create(&path, dentry); | 3524 | done_path_create(&path, dentry); |
3459 | out_putname: | 3525 | out_putname: |
3460 | putname(from); | 3526 | putname(from); |
@@ -3734,17 +3800,21 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, | |||
3734 | struct dentry *old_dentry, *new_dentry; | 3800 | struct dentry *old_dentry, *new_dentry; |
3735 | struct dentry *trap; | 3801 | struct dentry *trap; |
3736 | struct nameidata oldnd, newnd; | 3802 | struct nameidata oldnd, newnd; |
3737 | char *from; | 3803 | struct filename *from; |
3738 | char *to; | 3804 | struct filename *to; |
3739 | int error; | 3805 | int error; |
3740 | 3806 | ||
3741 | error = user_path_parent(olddfd, oldname, &oldnd, &from); | 3807 | from = user_path_parent(olddfd, oldname, &oldnd); |
3742 | if (error) | 3808 | if (IS_ERR(from)) { |
3809 | error = PTR_ERR(from); | ||
3743 | goto exit; | 3810 | goto exit; |
3811 | } | ||
3744 | 3812 | ||
3745 | error = user_path_parent(newdfd, newname, &newnd, &to); | 3813 | to = user_path_parent(newdfd, newname, &newnd); |
3746 | if (error) | 3814 | if (IS_ERR(to)) { |
3815 | error = PTR_ERR(to); | ||
3747 | goto exit1; | 3816 | goto exit1; |
3817 | } | ||
3748 | 3818 | ||
3749 | error = -EXDEV; | 3819 | error = -EXDEV; |
3750 | if (oldnd.path.mnt != newnd.path.mnt) | 3820 | if (oldnd.path.mnt != newnd.path.mnt) |
@@ -3968,7 +4038,6 @@ EXPORT_SYMBOL(follow_down_one); | |||
3968 | EXPORT_SYMBOL(follow_down); | 4038 | EXPORT_SYMBOL(follow_down); |
3969 | EXPORT_SYMBOL(follow_up); | 4039 | EXPORT_SYMBOL(follow_up); |
3970 | EXPORT_SYMBOL(get_write_access); /* nfsd */ | 4040 | EXPORT_SYMBOL(get_write_access); /* nfsd */ |
3971 | EXPORT_SYMBOL(getname); | ||
3972 | EXPORT_SYMBOL(lock_rename); | 4041 | EXPORT_SYMBOL(lock_rename); |
3973 | EXPORT_SYMBOL(lookup_one_len); | 4042 | EXPORT_SYMBOL(lookup_one_len); |
3974 | EXPORT_SYMBOL(page_follow_link_light); | 4043 | EXPORT_SYMBOL(page_follow_link_light); |
diff --git a/fs/namespace.c b/fs/namespace.c index fc33207e28ad..24960626bb6b 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -2408,7 +2408,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | |||
2408 | { | 2408 | { |
2409 | int ret; | 2409 | int ret; |
2410 | char *kernel_type; | 2410 | char *kernel_type; |
2411 | char *kernel_dir; | 2411 | struct filename *kernel_dir; |
2412 | char *kernel_dev; | 2412 | char *kernel_dev; |
2413 | unsigned long data_page; | 2413 | unsigned long data_page; |
2414 | 2414 | ||
@@ -2430,7 +2430,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | |||
2430 | if (ret < 0) | 2430 | if (ret < 0) |
2431 | goto out_data; | 2431 | goto out_data; |
2432 | 2432 | ||
2433 | ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags, | 2433 | ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags, |
2434 | (void *) data_page); | 2434 | (void *) data_page); |
2435 | 2435 | ||
2436 | free_page(data_page); | 2436 | free_page(data_page); |
@@ -478,7 +478,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode) | |||
478 | 478 | ||
479 | file = fget(fd); | 479 | file = fget(fd); |
480 | if (file) { | 480 | if (file) { |
481 | audit_inode(NULL, file->f_path.dentry); | 481 | audit_inode(NULL, file->f_path.dentry, 0); |
482 | err = chmod_common(&file->f_path, mode); | 482 | err = chmod_common(&file->f_path, mode); |
483 | fput(file); | 483 | fput(file); |
484 | } | 484 | } |
@@ -588,7 +588,7 @@ SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group) | |||
588 | error = mnt_want_write_file(f.file); | 588 | error = mnt_want_write_file(f.file); |
589 | if (error) | 589 | if (error) |
590 | goto out_fput; | 590 | goto out_fput; |
591 | audit_inode(NULL, f.file->f_path.dentry); | 591 | audit_inode(NULL, f.file->f_path.dentry, 0); |
592 | error = chown_common(&f.file->f_path, user, group); | 592 | error = chown_common(&f.file->f_path, user, group); |
593 | mnt_drop_write_file(f.file); | 593 | mnt_drop_write_file(f.file); |
594 | out_fput: | 594 | out_fput: |
@@ -859,6 +859,24 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
859 | } | 859 | } |
860 | 860 | ||
861 | /** | 861 | /** |
862 | * file_open_name - open file and return file pointer | ||
863 | * | ||
864 | * @name: struct filename containing path to open | ||
865 | * @flags: open flags as per the open(2) second argument | ||
866 | * @mode: mode for the new file if O_CREAT is set, else ignored | ||
867 | * | ||
868 | * This is the helper to open a file from kernelspace if you really | ||
869 | * have to. But in generally you should not do this, so please move | ||
870 | * along, nothing to see here.. | ||
871 | */ | ||
872 | struct file *file_open_name(struct filename *name, int flags, umode_t mode) | ||
873 | { | ||
874 | struct open_flags op; | ||
875 | int lookup = build_open_flags(flags, mode, &op); | ||
876 | return do_filp_open(AT_FDCWD, name, &op, lookup); | ||
877 | } | ||
878 | |||
879 | /** | ||
862 | * filp_open - open file and return file pointer | 880 | * filp_open - open file and return file pointer |
863 | * | 881 | * |
864 | * @filename: path to open | 882 | * @filename: path to open |
@@ -871,9 +889,8 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
871 | */ | 889 | */ |
872 | struct file *filp_open(const char *filename, int flags, umode_t mode) | 890 | struct file *filp_open(const char *filename, int flags, umode_t mode) |
873 | { | 891 | { |
874 | struct open_flags op; | 892 | struct filename name = {.name = filename}; |
875 | int lookup = build_open_flags(flags, mode, &op); | 893 | return file_open_name(&name, flags, mode); |
876 | return do_filp_open(AT_FDCWD, filename, &op, lookup); | ||
877 | } | 894 | } |
878 | EXPORT_SYMBOL(filp_open); | 895 | EXPORT_SYMBOL(filp_open); |
879 | 896 | ||
@@ -895,7 +912,7 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) | |||
895 | { | 912 | { |
896 | struct open_flags op; | 913 | struct open_flags op; |
897 | int lookup = build_open_flags(flags, mode, &op); | 914 | int lookup = build_open_flags(flags, mode, &op); |
898 | char *tmp = getname(filename); | 915 | struct filename *tmp = getname(filename); |
899 | int fd = PTR_ERR(tmp); | 916 | int fd = PTR_ERR(tmp); |
900 | 917 | ||
901 | if (!IS_ERR(tmp)) { | 918 | if (!IS_ERR(tmp)) { |
diff --git a/fs/proc/base.c b/fs/proc/base.c index ef5c84be66f9..144a96732dd7 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2258,7 +2258,8 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
2258 | pid_t tgid = task_tgid_nr_ns(current, ns); | 2258 | pid_t tgid = task_tgid_nr_ns(current, ns); |
2259 | char *name = ERR_PTR(-ENOENT); | 2259 | char *name = ERR_PTR(-ENOENT); |
2260 | if (tgid) { | 2260 | if (tgid) { |
2261 | name = __getname(); | 2261 | /* 11 for max length of signed int in decimal + NULL term */ |
2262 | name = kmalloc(12, GFP_KERNEL); | ||
2262 | if (!name) | 2263 | if (!name) |
2263 | name = ERR_PTR(-ENOMEM); | 2264 | name = ERR_PTR(-ENOMEM); |
2264 | else | 2265 | else |
@@ -2273,7 +2274,7 @@ static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd, | |||
2273 | { | 2274 | { |
2274 | char *s = nd_get_link(nd); | 2275 | char *s = nd_get_link(nd); |
2275 | if (!IS_ERR(s)) | 2276 | if (!IS_ERR(s)) |
2276 | __putname(s); | 2277 | kfree(s); |
2277 | } | 2278 | } |
2278 | 2279 | ||
2279 | static const struct inode_operations proc_self_inode_operations = { | 2280 | static const struct inode_operations proc_self_inode_operations = { |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index ff0135d6bc51..af1661f7a54f 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
@@ -331,11 +331,11 @@ static struct super_block *quotactl_block(const char __user *special, int cmd) | |||
331 | #ifdef CONFIG_BLOCK | 331 | #ifdef CONFIG_BLOCK |
332 | struct block_device *bdev; | 332 | struct block_device *bdev; |
333 | struct super_block *sb; | 333 | struct super_block *sb; |
334 | char *tmp = getname(special); | 334 | struct filename *tmp = getname(special); |
335 | 335 | ||
336 | if (IS_ERR(tmp)) | 336 | if (IS_ERR(tmp)) |
337 | return ERR_CAST(tmp); | 337 | return ERR_CAST(tmp); |
338 | bdev = lookup_bdev(tmp); | 338 | bdev = lookup_bdev(tmp->name); |
339 | putname(tmp); | 339 | putname(tmp); |
340 | if (IS_ERR(bdev)) | 340 | if (IS_ERR(bdev)) |
341 | return ERR_CAST(bdev); | 341 | return ERR_CAST(bdev); |
diff --git a/fs/xattr.c b/fs/xattr.c index 1780f062dbaf..e164dddb8e96 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -412,7 +412,7 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, | |||
412 | if (!f.file) | 412 | if (!f.file) |
413 | return error; | 413 | return error; |
414 | dentry = f.file->f_path.dentry; | 414 | dentry = f.file->f_path.dentry; |
415 | audit_inode(NULL, dentry); | 415 | audit_inode(NULL, dentry, 0); |
416 | error = mnt_want_write_file(f.file); | 416 | error = mnt_want_write_file(f.file); |
417 | if (!error) { | 417 | if (!error) { |
418 | error = setxattr(dentry, name, value, size, flags); | 418 | error = setxattr(dentry, name, value, size, flags); |
@@ -507,7 +507,7 @@ SYSCALL_DEFINE4(fgetxattr, int, fd, const char __user *, name, | |||
507 | 507 | ||
508 | if (!f.file) | 508 | if (!f.file) |
509 | return error; | 509 | return error; |
510 | audit_inode(NULL, f.file->f_path.dentry); | 510 | audit_inode(NULL, f.file->f_path.dentry, 0); |
511 | error = getxattr(f.file->f_path.dentry, name, value, size); | 511 | error = getxattr(f.file->f_path.dentry, name, value, size); |
512 | fdput(f); | 512 | fdput(f); |
513 | return error; | 513 | return error; |
@@ -586,7 +586,7 @@ SYSCALL_DEFINE3(flistxattr, int, fd, char __user *, list, size_t, size) | |||
586 | 586 | ||
587 | if (!f.file) | 587 | if (!f.file) |
588 | return error; | 588 | return error; |
589 | audit_inode(NULL, f.file->f_path.dentry); | 589 | audit_inode(NULL, f.file->f_path.dentry, 0); |
590 | error = listxattr(f.file->f_path.dentry, list, size); | 590 | error = listxattr(f.file->f_path.dentry, list, size); |
591 | fdput(f); | 591 | fdput(f); |
592 | return error; | 592 | return error; |
@@ -655,7 +655,7 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) | |||
655 | if (!f.file) | 655 | if (!f.file) |
656 | return error; | 656 | return error; |
657 | dentry = f.file->f_path.dentry; | 657 | dentry = f.file->f_path.dentry; |
658 | audit_inode(NULL, dentry); | 658 | audit_inode(NULL, dentry, 0); |
659 | error = mnt_want_write_file(f.file); | 659 | error = mnt_want_write_file(f.file); |
660 | if (!error) { | 660 | if (!error) { |
661 | error = removexattr(dentry, name); | 661 | error = removexattr(dentry, name); |