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 2

Take the "long name" case into a helper (getname_long()). In
case of failure have the caller deal with freeing the original
struct filename.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 8f2ac848 8ba29c85

+29 -27
+29 -27
fs/namei.c
··· 131 131 atomic_set(&name->refcnt, 1); 132 132 } 133 133 134 + static struct filename *getname_long(struct filename *old, 135 + const char __user *filename) 136 + { 137 + int len; 138 + /* 139 + * size is chosen that way we to guarantee that 140 + * p->iname[0] is within the same object and that 141 + * p->name can't be equal to p->iname, no matter what. 142 + */ 143 + const size_t size = offsetof(struct filename, iname[1]); 144 + struct filename *p __free(kfree) = kzalloc(size, GFP_KERNEL); 145 + if (unlikely(!p)) 146 + return ERR_PTR(-ENOMEM); 147 + 148 + memmove(old, &old->iname, EMBEDDED_NAME_MAX); 149 + p->name = (char *)old; 150 + len = strncpy_from_user((char *)old + EMBEDDED_NAME_MAX, 151 + filename + EMBEDDED_NAME_MAX, 152 + PATH_MAX - EMBEDDED_NAME_MAX); 153 + if (unlikely(len < 0)) 154 + return ERR_PTR(len); 155 + if (unlikely(len == PATH_MAX - EMBEDDED_NAME_MAX)) 156 + return ERR_PTR(-ENAMETOOLONG); 157 + return no_free_ptr(p); 158 + } 159 + 134 160 struct filename * 135 161 getname_flags(const char __user *filename, int flags) 136 162 { ··· 199 173 * userland. 200 174 */ 201 175 if (unlikely(len == EMBEDDED_NAME_MAX)) { 202 - const size_t size = offsetof(struct filename, iname[1]); 203 - struct filename *p; 204 - 205 - /* 206 - * size is chosen that way we to guarantee that 207 - * result->iname[0] is within the same object and that 208 - * kname can't be equal to result->iname, no matter what. 209 - */ 210 - p = kzalloc(size, GFP_KERNEL); 211 - if (unlikely(!p)) { 176 + struct filename *p = getname_long(result, filename); 177 + if (IS_ERR(p)) { 212 178 __putname(result); 213 - return ERR_PTR(-ENOMEM); 214 - } 215 - memmove(result, &result->iname, EMBEDDED_NAME_MAX); 216 - kname = (char *)result; 217 - p->name = kname; 218 - len = strncpy_from_user(kname + EMBEDDED_NAME_MAX, 219 - filename + EMBEDDED_NAME_MAX, 220 - PATH_MAX - EMBEDDED_NAME_MAX); 221 - if (unlikely(len < 0)) { 222 - kfree(p); 223 - __putname(result); 224 - return ERR_PTR(len); 225 - } 226 - if (unlikely(len == PATH_MAX - EMBEDDED_NAME_MAX)) { 227 - kfree(p); 228 - __putname(result); 229 - return ERR_PTR(-ENAMETOOLONG); 179 + return p; 230 180 } 231 181 result = p; 232 182 }