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>
This commit is contained in:
Paul Moore 2015-01-21 23:59:56 -05:00 committed by Al Viro
parent fa14a0b8d2
commit 0851854972

View File

@ -212,32 +212,38 @@ getname(const char __user * filename)
return getname_flags(filename, 0, NULL);
}
/*
* The "getname_kernel()" interface doesn't do pathnames longer
* than EMBEDDED_NAME_MAX. Deal with it - you're a kernel user.
*/
struct filename *
getname_kernel(const char * filename)
{
struct filename *result;
char *kname;
int len;
len = strlen(filename);
if (len >= EMBEDDED_NAME_MAX)
return ERR_PTR(-ENAMETOOLONG);
int len = strlen(filename) + 1;
result = __getname();
if (unlikely(!result))
return ERR_PTR(-ENOMEM);
kname = (char *)result + sizeof(*result);
result->name = kname;
if (len <= EMBEDDED_NAME_MAX) {
result->name = (char *)(result) + sizeof(*result);
result->separate = false;
} else if (len <= PATH_MAX) {
struct filename *tmp;
tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
if (unlikely(!tmp)) {
__putname(result);
return ERR_PTR(-ENOMEM);
}
tmp->name = (char *)result;
tmp->separate = true;
result = tmp;
} else {
__putname(result);
return ERR_PTR(-ENAMETOOLONG);
}
memcpy((char *)result->name, filename, len);
result->uptr = NULL;
result->aname = NULL;
result->separate = false;
strlcpy(kname, filename, EMBEDDED_NAME_MAX);
return result;
}