diff options
-rw-r--r-- | fs/namei.c | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/fs/namei.c b/fs/namei.c index 0062dd17eb55..494b1caa25f8 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -116,47 +116,37 @@ | |||
116 | * POSIX.1 2.4: an empty pathname is invalid (ENOENT). | 116 | * POSIX.1 2.4: an empty pathname is invalid (ENOENT). |
117 | * PATH_MAX includes the nul terminator --RR. | 117 | * PATH_MAX includes the nul terminator --RR. |
118 | */ | 118 | */ |
119 | static int do_getname(const char __user *filename, char *page) | ||
120 | { | ||
121 | int retval; | ||
122 | unsigned long len = PATH_MAX; | ||
123 | |||
124 | if (!segment_eq(get_fs(), KERNEL_DS)) { | ||
125 | if ((unsigned long) filename >= TASK_SIZE) | ||
126 | return -EFAULT; | ||
127 | if (TASK_SIZE - (unsigned long) filename < PATH_MAX) | ||
128 | len = TASK_SIZE - (unsigned long) filename; | ||
129 | } | ||
130 | |||
131 | retval = strncpy_from_user(page, filename, len); | ||
132 | if (retval > 0) { | ||
133 | if (retval < len) | ||
134 | return 0; | ||
135 | return -ENAMETOOLONG; | ||
136 | } else if (!retval) | ||
137 | retval = -ENOENT; | ||
138 | return retval; | ||
139 | } | ||
140 | |||
141 | static char *getname_flags(const char __user *filename, int flags, int *empty) | 119 | static char *getname_flags(const char __user *filename, int flags, int *empty) |
142 | { | 120 | { |
143 | char *result = __getname(); | 121 | char *result = __getname(), *err; |
144 | int retval; | 122 | int len; |
145 | 123 | ||
146 | if (!result) | 124 | if (unlikely(!result)) |
147 | return ERR_PTR(-ENOMEM); | 125 | return ERR_PTR(-ENOMEM); |
148 | 126 | ||
149 | retval = do_getname(filename, result); | 127 | len = strncpy_from_user(result, filename, PATH_MAX); |
150 | if (retval < 0) { | 128 | err = ERR_PTR(len); |
151 | if (retval == -ENOENT && empty) | 129 | if (unlikely(len < 0)) |
130 | goto error; | ||
131 | |||
132 | /* The empty path is special. */ | ||
133 | if (unlikely(!len)) { | ||
134 | if (empty) | ||
152 | *empty = 1; | 135 | *empty = 1; |
153 | if (retval != -ENOENT || !(flags & LOOKUP_EMPTY)) { | 136 | err = ERR_PTR(-ENOENT); |
154 | __putname(result); | 137 | if (!(flags & LOOKUP_EMPTY)) |
155 | return ERR_PTR(retval); | 138 | goto error; |
156 | } | ||
157 | } | 139 | } |
158 | audit_getname(result); | 140 | |
159 | return result; | 141 | err = ERR_PTR(-ENAMETOOLONG); |
142 | if (likely(len < PATH_MAX)) { | ||
143 | audit_getname(result); | ||
144 | return result; | ||
145 | } | ||
146 | |||
147 | error: | ||
148 | __putname(result); | ||
149 | return err; | ||
160 | } | 150 | } |
161 | 151 | ||
162 | char *getname(const char __user * filename) | 152 | char *getname(const char __user * filename) |