mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 05:44:45 +01:00
getname_flags() massage, part 1
In case of long name don't reread what we'd already copied. memmove() it instead. That avoids the possibility of ending up with empty name there and the need to look at the flags on the slow path. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
ca2a04e84a
commit
8ba29c85e2
1 changed files with 16 additions and 17 deletions
33
fs/namei.c
33
fs/namei.c
|
|
@ -174,36 +174,35 @@ getname_flags(const char __user *filename, int flags)
|
|||
*/
|
||||
if (unlikely(len == EMBEDDED_NAME_MAX)) {
|
||||
const size_t size = offsetof(struct filename, iname[1]);
|
||||
kname = (char *)result;
|
||||
struct filename *p;
|
||||
|
||||
/*
|
||||
* size is chosen that way we to guarantee that
|
||||
* result->iname[0] is within the same object and that
|
||||
* kname can't be equal to result->iname, no matter what.
|
||||
*/
|
||||
result = kzalloc(size, GFP_KERNEL);
|
||||
if (unlikely(!result)) {
|
||||
__putname(kname);
|
||||
p = kzalloc(size, GFP_KERNEL);
|
||||
if (unlikely(!p)) {
|
||||
__putname(result);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
result->name = kname;
|
||||
len = strncpy_from_user(kname, filename, PATH_MAX);
|
||||
memmove(result, &result->iname, EMBEDDED_NAME_MAX);
|
||||
kname = (char *)result;
|
||||
p->name = kname;
|
||||
len = strncpy_from_user(kname + EMBEDDED_NAME_MAX,
|
||||
filename + EMBEDDED_NAME_MAX,
|
||||
PATH_MAX - EMBEDDED_NAME_MAX);
|
||||
if (unlikely(len < 0)) {
|
||||
__putname(kname);
|
||||
kfree(result);
|
||||
kfree(p);
|
||||
__putname(result);
|
||||
return ERR_PTR(len);
|
||||
}
|
||||
/* The empty path is special. */
|
||||
if (unlikely(!len) && !(flags & LOOKUP_EMPTY)) {
|
||||
__putname(kname);
|
||||
kfree(result);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
if (unlikely(len == PATH_MAX)) {
|
||||
__putname(kname);
|
||||
kfree(result);
|
||||
if (unlikely(len == PATH_MAX - EMBEDDED_NAME_MAX)) {
|
||||
kfree(p);
|
||||
__putname(result);
|
||||
return ERR_PTR(-ENAMETOOLONG);
|
||||
}
|
||||
result = p;
|
||||
}
|
||||
initname(result);
|
||||
audit_getname(result);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue