aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2015-01-21 23:59:56 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2015-01-23 00:22:20 -0500
commit08518549722f0c992a9e4be71a0777f37147e9d2 (patch)
tree80ac5b25e4b113fb80125c01e26e846f5fde4b98
parentfa14a0b8d2bca1d2226afaa04bdf80200d8e9b03 (diff)
fs: rework getname_kernel to handle up to PATH_MAX sized filenames
In preparation for expanded use in the kernel, make getname_kernel() more useful by allowing it to handle any legal filename length. Thanks to Guenter Roeck for his suggestion to substitute memcpy() for strlcpy(). CC: linux@roeck-us.net CC: viro@zeniv.linux.org.uk CC: linux-fsdevel@vger.kernel.org Signed-off-by: Paul Moore <pmoore@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/namei.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 73fcf4280d6e..71dc1cc23b1a 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -212,32 +212,38 @@ getname(const char __user * filename)
212 return getname_flags(filename, 0, NULL); 212 return getname_flags(filename, 0, NULL);
213} 213}
214 214
215/*
216 * The "getname_kernel()" interface doesn't do pathnames longer
217 * than EMBEDDED_NAME_MAX. Deal with it - you're a kernel user.
218 */
219struct filename * 215struct filename *
220getname_kernel(const char * filename) 216getname_kernel(const char * filename)
221{ 217{
222 struct filename *result; 218 struct filename *result;
223 char *kname; 219 int len = strlen(filename) + 1;
224 int len;
225
226 len = strlen(filename);
227 if (len >= EMBEDDED_NAME_MAX)
228 return ERR_PTR(-ENAMETOOLONG);
229 220
230 result = __getname(); 221 result = __getname();
231 if (unlikely(!result)) 222 if (unlikely(!result))
232 return ERR_PTR(-ENOMEM); 223 return ERR_PTR(-ENOMEM);
233 224
234 kname = (char *)result + sizeof(*result); 225 if (len <= EMBEDDED_NAME_MAX) {
235 result->name = kname; 226 result->name = (char *)(result) + sizeof(*result);
227 result->separate = false;
228 } else if (len <= PATH_MAX) {
229 struct filename *tmp;
230
231 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
232 if (unlikely(!tmp)) {
233 __putname(result);
234 return ERR_PTR(-ENOMEM);
235 }
236 tmp->name = (char *)result;
237 tmp->separate = true;
238 result = tmp;
239 } else {
240 __putname(result);
241 return ERR_PTR(-ENAMETOOLONG);
242 }
243 memcpy((char *)result->name, filename, len);
236 result->uptr = NULL; 244 result->uptr = NULL;
237 result->aname = NULL; 245 result->aname = NULL;
238 result->separate = false;
239 246
240 strlcpy(kname, filename, EMBEDDED_NAME_MAX);
241 return result; 247 return result;
242} 248}
243 249