Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

Al Viro 8ba29c85 ca2a04e8

+16 -17
+16 -17
fs/namei.c
··· 174 174 */ 175 175 if (unlikely(len == EMBEDDED_NAME_MAX)) { 176 176 const size_t size = offsetof(struct filename, iname[1]); 177 - kname = (char *)result; 177 + struct filename *p; 178 178 179 179 /* 180 180 * size is chosen that way we to guarantee that 181 181 * result->iname[0] is within the same object and that 182 182 * kname can't be equal to result->iname, no matter what. 183 183 */ 184 - result = kzalloc(size, GFP_KERNEL); 185 - if (unlikely(!result)) { 186 - __putname(kname); 184 + p = kzalloc(size, GFP_KERNEL); 185 + if (unlikely(!p)) { 186 + __putname(result); 187 187 return ERR_PTR(-ENOMEM); 188 188 } 189 - result->name = kname; 190 - len = strncpy_from_user(kname, filename, PATH_MAX); 189 + memmove(result, &result->iname, EMBEDDED_NAME_MAX); 190 + kname = (char *)result; 191 + p->name = kname; 192 + len = strncpy_from_user(kname + EMBEDDED_NAME_MAX, 193 + filename + EMBEDDED_NAME_MAX, 194 + PATH_MAX - EMBEDDED_NAME_MAX); 191 195 if (unlikely(len < 0)) { 192 - __putname(kname); 193 - kfree(result); 196 + kfree(p); 197 + __putname(result); 194 198 return ERR_PTR(len); 195 199 } 196 - /* The empty path is special. */ 197 - if (unlikely(!len) && !(flags & LOOKUP_EMPTY)) { 198 - __putname(kname); 199 - kfree(result); 200 - return ERR_PTR(-ENOENT); 201 - } 202 - if (unlikely(len == PATH_MAX)) { 203 - __putname(kname); 204 - kfree(result); 200 + if (unlikely(len == PATH_MAX - EMBEDDED_NAME_MAX)) { 201 + kfree(p); 202 + __putname(result); 205 203 return ERR_PTR(-ENAMETOOLONG); 206 204 } 205 + result = p; 207 206 } 208 207 initname(result); 209 208 audit_getname(result);