diff options
40 files changed, 218 insertions, 175 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 63e77e3944ce..9eb090582cf1 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -449,7 +449,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) | |||
449 | { | 449 | { |
450 | int retval; | 450 | int retval; |
451 | struct cdfs_args tmp; | 451 | struct cdfs_args tmp; |
452 | char *devname; | 452 | struct filename *devname; |
453 | 453 | ||
454 | retval = -EFAULT; | 454 | retval = -EFAULT; |
455 | if (copy_from_user(&tmp, args, sizeof(tmp))) | 455 | if (copy_from_user(&tmp, args, sizeof(tmp))) |
@@ -458,7 +458,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags) | |||
458 | retval = PTR_ERR(devname); | 458 | retval = PTR_ERR(devname); |
459 | if (IS_ERR(devname)) | 459 | if (IS_ERR(devname)) |
460 | goto out; | 460 | goto out; |
461 | retval = do_mount(devname, dirname, "ext2", flags, NULL); | 461 | retval = do_mount(devname->name, dirname, "ext2", flags, NULL); |
462 | putname(devname); | 462 | putname(devname); |
463 | out: | 463 | out: |
464 | return retval; | 464 | return retval; |
@@ -469,7 +469,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) | |||
469 | { | 469 | { |
470 | int retval; | 470 | int retval; |
471 | struct cdfs_args tmp; | 471 | struct cdfs_args tmp; |
472 | char *devname; | 472 | struct filename *devname; |
473 | 473 | ||
474 | retval = -EFAULT; | 474 | retval = -EFAULT; |
475 | if (copy_from_user(&tmp, args, sizeof(tmp))) | 475 | if (copy_from_user(&tmp, args, sizeof(tmp))) |
@@ -478,7 +478,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags) | |||
478 | retval = PTR_ERR(devname); | 478 | retval = PTR_ERR(devname); |
479 | if (IS_ERR(devname)) | 479 | if (IS_ERR(devname)) |
480 | goto out; | 480 | goto out; |
481 | retval = do_mount(devname, dirname, "iso9660", flags, NULL); | 481 | retval = do_mount(devname->name, dirname, "iso9660", flags, NULL); |
482 | putname(devname); | 482 | putname(devname); |
483 | out: | 483 | out: |
484 | return retval; | 484 | return retval; |
@@ -499,7 +499,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path, | |||
499 | int, flag, void __user *, data) | 499 | int, flag, void __user *, data) |
500 | { | 500 | { |
501 | int retval; | 501 | int retval; |
502 | char *name; | 502 | struct filename *name; |
503 | 503 | ||
504 | name = getname(path); | 504 | name = getname(path); |
505 | retval = PTR_ERR(name); | 505 | retval = PTR_ERR(name); |
@@ -507,13 +507,13 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path, | |||
507 | goto out; | 507 | goto out; |
508 | switch (typenr) { | 508 | switch (typenr) { |
509 | case 1: | 509 | case 1: |
510 | retval = osf_ufs_mount(name, data, flag); | 510 | retval = osf_ufs_mount(name->name, data, flag); |
511 | break; | 511 | break; |
512 | case 6: | 512 | case 6: |
513 | retval = osf_cdfs_mount(name, data, flag); | 513 | retval = osf_cdfs_mount(name->name, data, flag); |
514 | break; | 514 | break; |
515 | case 9: | 515 | case 9: |
516 | retval = osf_procfs_mount(name, data, flag); | 516 | retval = osf_procfs_mount(name->name, data, flag); |
517 | break; | 517 | break; |
518 | default: | 518 | default: |
519 | retval = -EINVAL; | 519 | retval = -EINVAL; |
diff --git a/arch/arm64/kernel/sys.c b/arch/arm64/kernel/sys.c index 905fcfb0ddd0..b120df37de35 100644 --- a/arch/arm64/kernel/sys.c +++ b/arch/arm64/kernel/sys.c | |||
@@ -50,13 +50,13 @@ asmlinkage long sys_execve(const char __user *filenamei, | |||
50 | struct pt_regs *regs) | 50 | struct pt_regs *regs) |
51 | { | 51 | { |
52 | long error; | 52 | long error; |
53 | char * filename; | 53 | struct filename *filename; |
54 | 54 | ||
55 | filename = getname(filenamei); | 55 | filename = getname(filenamei); |
56 | error = PTR_ERR(filename); | 56 | error = PTR_ERR(filename); |
57 | if (IS_ERR(filename)) | 57 | if (IS_ERR(filename)) |
58 | goto out; | 58 | goto out; |
59 | error = do_execve(filename, argv, envp, regs); | 59 | error = do_execve(filename->name, argv, envp, regs); |
60 | putname(filename); | 60 | putname(filename); |
61 | out: | 61 | out: |
62 | return error; | 62 | return error; |
diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c index 93f10e27dc79..e521087cb0c4 100644 --- a/arch/arm64/kernel/sys_compat.c +++ b/arch/arm64/kernel/sys_compat.c | |||
@@ -56,14 +56,14 @@ asmlinkage int compat_sys_execve(const char __user *filenamei, | |||
56 | struct pt_regs *regs) | 56 | struct pt_regs *regs) |
57 | { | 57 | { |
58 | int error; | 58 | int error; |
59 | char * filename; | 59 | struct filename *filename; |
60 | 60 | ||
61 | filename = getname(filenamei); | 61 | filename = getname(filenamei); |
62 | error = PTR_ERR(filename); | 62 | error = PTR_ERR(filename); |
63 | if (IS_ERR(filename)) | 63 | if (IS_ERR(filename)) |
64 | goto out; | 64 | goto out; |
65 | error = compat_do_execve(filename, compat_ptr(argv), compat_ptr(envp), | 65 | error = compat_do_execve(filename->name, compat_ptr(argv), |
66 | regs); | 66 | compat_ptr(envp), regs); |
67 | putname(filename); | 67 | putname(filename); |
68 | out: | 68 | out: |
69 | return error; | 69 | return error; |
diff --git a/arch/avr32/kernel/process.c b/arch/avr32/kernel/process.c index 92c5af98a6f7..1bb0a8abd79b 100644 --- a/arch/avr32/kernel/process.c +++ b/arch/avr32/kernel/process.c | |||
@@ -388,14 +388,14 @@ asmlinkage int sys_execve(const char __user *ufilename, | |||
388 | struct pt_regs *regs) | 388 | struct pt_regs *regs) |
389 | { | 389 | { |
390 | int error; | 390 | int error; |
391 | char *filename; | 391 | struct filename *filename; |
392 | 392 | ||
393 | filename = getname(ufilename); | 393 | filename = getname(ufilename); |
394 | error = PTR_ERR(filename); | 394 | error = PTR_ERR(filename); |
395 | if (IS_ERR(filename)) | 395 | if (IS_ERR(filename)) |
396 | goto out; | 396 | goto out; |
397 | 397 | ||
398 | error = do_execve(filename, uargv, uenvp, regs); | 398 | error = do_execve(filename->name, uargv, uenvp, regs); |
399 | putname(filename); | 399 | putname(filename); |
400 | 400 | ||
401 | out: | 401 | out: |
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 62bcea7dcc6d..bb1cc721fcf7 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c | |||
@@ -213,14 +213,14 @@ asmlinkage int sys_execve(const char __user *name, | |||
213 | const char __user *const __user *envp) | 213 | const char __user *const __user *envp) |
214 | { | 214 | { |
215 | int error; | 215 | int error; |
216 | char *filename; | 216 | struct filename *filename; |
217 | struct pt_regs *regs = (struct pt_regs *)((&name) + 6); | 217 | struct pt_regs *regs = (struct pt_regs *)((&name) + 6); |
218 | 218 | ||
219 | filename = getname(name); | 219 | filename = getname(name); |
220 | error = PTR_ERR(filename); | 220 | error = PTR_ERR(filename); |
221 | if (IS_ERR(filename)) | 221 | if (IS_ERR(filename)) |
222 | return error; | 222 | return error; |
223 | error = do_execve(filename, argv, envp, regs); | 223 | error = do_execve(filename->name, argv, envp, regs); |
224 | putname(filename); | 224 | putname(filename); |
225 | return error; | 225 | return error; |
226 | } | 226 | } |
diff --git a/arch/cris/arch-v10/kernel/process.c b/arch/cris/arch-v10/kernel/process.c index bee8df43c201..15ac7150371f 100644 --- a/arch/cris/arch-v10/kernel/process.c +++ b/arch/cris/arch-v10/kernel/process.c | |||
@@ -212,14 +212,14 @@ asmlinkage int sys_execve(const char *fname, | |||
212 | struct pt_regs *regs) | 212 | struct pt_regs *regs) |
213 | { | 213 | { |
214 | int error; | 214 | int error; |
215 | char *filename; | 215 | struct filename *filename; |
216 | 216 | ||
217 | filename = getname(fname); | 217 | filename = getname(fname); |
218 | error = PTR_ERR(filename); | 218 | error = PTR_ERR(filename); |
219 | 219 | ||
220 | if (IS_ERR(filename)) | 220 | if (IS_ERR(filename)) |
221 | goto out; | 221 | goto out; |
222 | error = do_execve(filename, argv, envp, regs); | 222 | error = do_execve(filename->name, argv, envp, regs); |
223 | putname(filename); | 223 | putname(filename); |
224 | out: | 224 | out: |
225 | return error; | 225 | return error; |
diff --git a/arch/cris/arch-v32/kernel/process.c b/arch/cris/arch-v32/kernel/process.c index 0570e8ce603d..4e9992246359 100644 --- a/arch/cris/arch-v32/kernel/process.c +++ b/arch/cris/arch-v32/kernel/process.c | |||
@@ -224,7 +224,7 @@ sys_execve(const char *fname, | |||
224 | struct pt_regs *regs) | 224 | struct pt_regs *regs) |
225 | { | 225 | { |
226 | int error; | 226 | int error; |
227 | char *filename; | 227 | struct filename *filename; |
228 | 228 | ||
229 | filename = getname(fname); | 229 | filename = getname(fname); |
230 | error = PTR_ERR(filename); | 230 | error = PTR_ERR(filename); |
@@ -232,7 +232,7 @@ sys_execve(const char *fname, | |||
232 | if (IS_ERR(filename)) | 232 | if (IS_ERR(filename)) |
233 | goto out; | 233 | goto out; |
234 | 234 | ||
235 | error = do_execve(filename, argv, envp, regs); | 235 | error = do_execve(filename->name, argv, envp, regs); |
236 | putname(filename); | 236 | putname(filename); |
237 | out: | 237 | out: |
238 | return error; | 238 | return error; |
diff --git a/arch/h8300/kernel/process.c b/arch/h8300/kernel/process.c index f153ed1a4c08..e8dc1393a13a 100644 --- a/arch/h8300/kernel/process.c +++ b/arch/h8300/kernel/process.c | |||
@@ -217,14 +217,14 @@ asmlinkage int sys_execve(const char *name, | |||
217 | int dummy, ...) | 217 | int dummy, ...) |
218 | { | 218 | { |
219 | int error; | 219 | int error; |
220 | char * filename; | 220 | struct filename *filename; |
221 | struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4); | 221 | struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4); |
222 | 222 | ||
223 | filename = getname(name); | 223 | filename = getname(name); |
224 | error = PTR_ERR(filename); | 224 | error = PTR_ERR(filename); |
225 | if (IS_ERR(filename)) | 225 | if (IS_ERR(filename)) |
226 | return error; | 226 | return error; |
227 | error = do_execve(filename, argv, envp, regs); | 227 | error = do_execve(filename->name, argv, envp, regs); |
228 | putname(filename); | 228 | putname(filename); |
229 | return error; | 229 | return error; |
230 | } | 230 | } |
diff --git a/arch/hexagon/kernel/syscall.c b/arch/hexagon/kernel/syscall.c index 553cd60ee659..25a9bfe3445d 100644 --- a/arch/hexagon/kernel/syscall.c +++ b/arch/hexagon/kernel/syscall.c | |||
@@ -40,7 +40,7 @@ asmlinkage int sys_execve(char __user *ufilename, | |||
40 | const char __user *const __user *envp) | 40 | const char __user *const __user *envp) |
41 | { | 41 | { |
42 | struct pt_regs *pregs = current_thread_info()->regs; | 42 | struct pt_regs *pregs = current_thread_info()->regs; |
43 | char *filename; | 43 | struct filename *filename; |
44 | int retval; | 44 | int retval; |
45 | 45 | ||
46 | filename = getname(ufilename); | 46 | filename = getname(ufilename); |
@@ -48,7 +48,7 @@ asmlinkage int sys_execve(char __user *ufilename, | |||
48 | if (IS_ERR(filename)) | 48 | if (IS_ERR(filename)) |
49 | return retval; | 49 | return retval; |
50 | 50 | ||
51 | retval = do_execve(filename, argv, envp, pregs); | 51 | retval = do_execve(filename->name, argv, envp, pregs); |
52 | putname(filename); | 52 | putname(filename); |
53 | 53 | ||
54 | return retval; | 54 | return retval; |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index ee31fe9b310e..35e106f2ed13 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -614,14 +614,14 @@ sys_execve (const char __user *filename, | |||
614 | const char __user *const __user *envp, | 614 | const char __user *const __user *envp, |
615 | struct pt_regs *regs) | 615 | struct pt_regs *regs) |
616 | { | 616 | { |
617 | char *fname; | 617 | struct filename *fname; |
618 | int error; | 618 | int error; |
619 | 619 | ||
620 | fname = getname(filename); | 620 | fname = getname(filename); |
621 | error = PTR_ERR(fname); | 621 | error = PTR_ERR(fname); |
622 | if (IS_ERR(fname)) | 622 | if (IS_ERR(fname)) |
623 | goto out; | 623 | goto out; |
624 | error = do_execve(fname, argv, envp, regs); | 624 | error = do_execve(fname->name, argv, envp, regs); |
625 | putname(fname); | 625 | putname(fname); |
626 | out: | 626 | out: |
627 | return error; | 627 | return error; |
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index 384e63f3a4c4..e7366276ef30 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c | |||
@@ -296,14 +296,14 @@ asmlinkage int sys_execve(const char __user *ufilename, | |||
296 | unsigned long r6, struct pt_regs regs) | 296 | unsigned long r6, struct pt_regs regs) |
297 | { | 297 | { |
298 | int error; | 298 | int error; |
299 | char *filename; | 299 | struct filename *filename; |
300 | 300 | ||
301 | filename = getname(ufilename); | 301 | filename = getname(ufilename); |
302 | error = PTR_ERR(filename); | 302 | error = PTR_ERR(filename); |
303 | if (IS_ERR(filename)) | 303 | if (IS_ERR(filename)) |
304 | goto out; | 304 | goto out; |
305 | 305 | ||
306 | error = do_execve(filename, uargv, uenvp, ®s); | 306 | error = do_execve(filename->name, uargv, uenvp, ®s); |
307 | putname(filename); | 307 | putname(filename); |
308 | out: | 308 | out: |
309 | return error; | 309 | return error; |
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index e5b154f24f85..404c0f24bd41 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c | |||
@@ -54,13 +54,13 @@ asmlinkage long microblaze_execve(const char __user *filenamei, | |||
54 | struct pt_regs *regs) | 54 | struct pt_regs *regs) |
55 | { | 55 | { |
56 | int error; | 56 | int error; |
57 | char *filename; | 57 | struct filename *filename; |
58 | 58 | ||
59 | filename = getname(filenamei); | 59 | filename = getname(filenamei); |
60 | error = PTR_ERR(filename); | 60 | error = PTR_ERR(filename); |
61 | if (IS_ERR(filename)) | 61 | if (IS_ERR(filename)) |
62 | goto out; | 62 | goto out; |
63 | error = do_execve(filename, argv, envp, regs); | 63 | error = do_execve(filename->name, argv, envp, regs); |
64 | putname(filename); | 64 | putname(filename); |
65 | out: | 65 | out: |
66 | return error; | 66 | return error; |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 922a554cd108..3a21acedf882 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -83,13 +83,13 @@ out: | |||
83 | asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs) | 83 | asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs) |
84 | { | 84 | { |
85 | int error; | 85 | int error; |
86 | char * filename; | 86 | struct filename *filename; |
87 | 87 | ||
88 | filename = getname(compat_ptr(regs.regs[4])); | 88 | filename = getname(compat_ptr(regs.regs[4])); |
89 | error = PTR_ERR(filename); | 89 | error = PTR_ERR(filename); |
90 | if (IS_ERR(filename)) | 90 | if (IS_ERR(filename)) |
91 | goto out; | 91 | goto out; |
92 | error = compat_do_execve(filename, compat_ptr(regs.regs[5]), | 92 | error = compat_do_execve(filename->name, compat_ptr(regs.regs[5]), |
93 | compat_ptr(regs.regs[6]), ®s); | 93 | compat_ptr(regs.regs[6]), ®s); |
94 | putname(filename); | 94 | putname(filename); |
95 | 95 | ||
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index b08220c82113..2bd561bc05ae 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
@@ -133,13 +133,13 @@ _sys_clone(nabi_no_regargs struct pt_regs regs) | |||
133 | asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) | 133 | asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) |
134 | { | 134 | { |
135 | int error; | 135 | int error; |
136 | char * filename; | 136 | struct filename *filename; |
137 | 137 | ||
138 | filename = getname((const char __user *) (long)regs.regs[4]); | 138 | filename = getname((const char __user *) (long)regs.regs[4]); |
139 | error = PTR_ERR(filename); | 139 | error = PTR_ERR(filename); |
140 | if (IS_ERR(filename)) | 140 | if (IS_ERR(filename)) |
141 | goto out; | 141 | goto out; |
142 | error = do_execve(filename, | 142 | error = do_execve(filename->name, |
143 | (const char __user *const __user *) (long)regs.regs[5], | 143 | (const char __user *const __user *) (long)regs.regs[5], |
144 | (const char __user *const __user *) (long)regs.regs[6], | 144 | (const char __user *const __user *) (long)regs.regs[6], |
145 | ®s); | 145 | ®s); |
diff --git a/arch/openrisc/kernel/process.c b/arch/openrisc/kernel/process.c index 55210f37d1a3..c35f3ab1a8d3 100644 --- a/arch/openrisc/kernel/process.c +++ b/arch/openrisc/kernel/process.c | |||
@@ -271,7 +271,7 @@ asmlinkage long _sys_execve(const char __user *name, | |||
271 | struct pt_regs *regs) | 271 | struct pt_regs *regs) |
272 | { | 272 | { |
273 | int error; | 273 | int error; |
274 | char *filename; | 274 | struct filename *filename; |
275 | 275 | ||
276 | filename = getname(name); | 276 | filename = getname(name); |
277 | error = PTR_ERR(filename); | 277 | error = PTR_ERR(filename); |
@@ -279,7 +279,7 @@ asmlinkage long _sys_execve(const char __user *name, | |||
279 | if (IS_ERR(filename)) | 279 | if (IS_ERR(filename)) |
280 | goto out; | 280 | goto out; |
281 | 281 | ||
282 | error = do_execve(filename, argv, envp, regs); | 282 | error = do_execve(filename->name, argv, envp, regs); |
283 | putname(filename); | 283 | putname(filename); |
284 | 284 | ||
285 | out: | 285 | out: |
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index 6785de7bd2a0..a0760b87fd4e 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c | |||
@@ -34,14 +34,14 @@ | |||
34 | int hpux_execve(struct pt_regs *regs) | 34 | int hpux_execve(struct pt_regs *regs) |
35 | { | 35 | { |
36 | int error; | 36 | int error; |
37 | char *filename; | 37 | struct filename *filename; |
38 | 38 | ||
39 | filename = getname((const char __user *) regs->gr[26]); | 39 | filename = getname((const char __user *) regs->gr[26]); |
40 | error = PTR_ERR(filename); | 40 | error = PTR_ERR(filename); |
41 | if (IS_ERR(filename)) | 41 | if (IS_ERR(filename)) |
42 | goto out; | 42 | goto out; |
43 | 43 | ||
44 | error = do_execve(filename, | 44 | error = do_execve(filename->name, |
45 | (const char __user *const __user *) regs->gr[25], | 45 | (const char __user *const __user *) regs->gr[25], |
46 | (const char __user *const __user *) regs->gr[24], | 46 | (const char __user *const __user *) regs->gr[24], |
47 | regs); | 47 | regs); |
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 8c6b6b6561f0..cbc37216bf90 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c | |||
@@ -342,13 +342,13 @@ unsigned long thread_saved_pc(struct task_struct *t) | |||
342 | asmlinkage int sys_execve(struct pt_regs *regs) | 342 | asmlinkage int sys_execve(struct pt_regs *regs) |
343 | { | 343 | { |
344 | int error; | 344 | int error; |
345 | char *filename; | 345 | struct filename *filename; |
346 | 346 | ||
347 | filename = getname((const char __user *) regs->gr[26]); | 347 | filename = getname((const char __user *) regs->gr[26]); |
348 | error = PTR_ERR(filename); | 348 | error = PTR_ERR(filename); |
349 | if (IS_ERR(filename)) | 349 | if (IS_ERR(filename)) |
350 | goto out; | 350 | goto out; |
351 | error = do_execve(filename, | 351 | error = do_execve(filename->name, |
352 | (const char __user *const __user *) regs->gr[25], | 352 | (const char __user *const __user *) regs->gr[25], |
353 | (const char __user *const __user *) regs->gr[24], | 353 | (const char __user *const __user *) regs->gr[24], |
354 | regs); | 354 | regs); |
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index dc9a62462323..bf5b93a885d3 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c | |||
@@ -60,14 +60,14 @@ | |||
60 | asmlinkage int sys32_execve(struct pt_regs *regs) | 60 | asmlinkage int sys32_execve(struct pt_regs *regs) |
61 | { | 61 | { |
62 | int error; | 62 | int error; |
63 | char *filename; | 63 | struct filename *filename; |
64 | 64 | ||
65 | DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26])); | 65 | DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26])); |
66 | filename = getname((const char __user *) regs->gr[26]); | 66 | filename = getname((const char __user *) regs->gr[26]); |
67 | error = PTR_ERR(filename); | 67 | error = PTR_ERR(filename); |
68 | if (IS_ERR(filename)) | 68 | if (IS_ERR(filename)) |
69 | goto out; | 69 | goto out; |
70 | error = compat_do_execve(filename, compat_ptr(regs->gr[25]), | 70 | error = compat_do_execve(filename->name, compat_ptr(regs->gr[25]), |
71 | compat_ptr(regs->gr[24]), regs); | 71 | compat_ptr(regs->gr[24]), regs); |
72 | putname(filename); | 72 | putname(filename); |
73 | out: | 73 | out: |
diff --git a/arch/score/kernel/sys_score.c b/arch/score/kernel/sys_score.c index 21e867974066..d45cf00a3351 100644 --- a/arch/score/kernel/sys_score.c +++ b/arch/score/kernel/sys_score.c | |||
@@ -92,14 +92,14 @@ asmlinkage long | |||
92 | score_execve(struct pt_regs *regs) | 92 | score_execve(struct pt_regs *regs) |
93 | { | 93 | { |
94 | int error; | 94 | int error; |
95 | char *filename; | 95 | struct filename *filename; |
96 | 96 | ||
97 | filename = getname((char __user*)regs->regs[4]); | 97 | filename = getname((char __user*)regs->regs[4]); |
98 | error = PTR_ERR(filename); | 98 | error = PTR_ERR(filename); |
99 | if (IS_ERR(filename)) | 99 | if (IS_ERR(filename)) |
100 | return error; | 100 | return error; |
101 | 101 | ||
102 | error = do_execve(filename, | 102 | error = do_execve(filename->name, |
103 | (const char __user *const __user *)regs->regs[5], | 103 | (const char __user *const __user *)regs->regs[5], |
104 | (const char __user *const __user *)regs->regs[6], | 104 | (const char __user *const __user *)regs->regs[6], |
105 | regs); | 105 | regs); |
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c index 59521e8a164d..ba7345f37bc9 100644 --- a/arch/sh/kernel/process_32.c +++ b/arch/sh/kernel/process_32.c | |||
@@ -298,14 +298,14 @@ asmlinkage int sys_execve(const char __user *ufilename, | |||
298 | { | 298 | { |
299 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | 299 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); |
300 | int error; | 300 | int error; |
301 | char *filename; | 301 | struct filename *filename; |
302 | 302 | ||
303 | filename = getname(ufilename); | 303 | filename = getname(ufilename); |
304 | error = PTR_ERR(filename); | 304 | error = PTR_ERR(filename); |
305 | if (IS_ERR(filename)) | 305 | if (IS_ERR(filename)) |
306 | goto out; | 306 | goto out; |
307 | 307 | ||
308 | error = do_execve(filename, uargv, uenvp, regs); | 308 | error = do_execve(filename->name, uargv, uenvp, regs); |
309 | putname(filename); | 309 | putname(filename); |
310 | out: | 310 | out: |
311 | return error; | 311 | return error; |
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c index 602545b12a86..98a709f0c3c4 100644 --- a/arch/sh/kernel/process_64.c +++ b/arch/sh/kernel/process_64.c | |||
@@ -491,14 +491,14 @@ asmlinkage int sys_execve(const char *ufilename, char **uargv, | |||
491 | struct pt_regs *pregs) | 491 | struct pt_regs *pregs) |
492 | { | 492 | { |
493 | int error; | 493 | int error; |
494 | char *filename; | 494 | struct filename *filename; |
495 | 495 | ||
496 | filename = getname((char __user *)ufilename); | 496 | filename = getname((char __user *)ufilename); |
497 | error = PTR_ERR(filename); | 497 | error = PTR_ERR(filename); |
498 | if (IS_ERR(filename)) | 498 | if (IS_ERR(filename)) |
499 | goto out; | 499 | goto out; |
500 | 500 | ||
501 | error = do_execve(filename, | 501 | error = do_execve(filename->name, |
502 | (const char __user *const __user *)uargv, | 502 | (const char __user *const __user *)uargv, |
503 | (const char __user *const __user *)uenvp, | 503 | (const char __user *const __user *)uenvp, |
504 | pregs); | 504 | pregs); |
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c index 14006d8aca28..487bffb36f5e 100644 --- a/arch/sparc/kernel/process_32.c +++ b/arch/sparc/kernel/process_32.c | |||
@@ -482,7 +482,7 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) | |||
482 | asmlinkage int sparc_execve(struct pt_regs *regs) | 482 | asmlinkage int sparc_execve(struct pt_regs *regs) |
483 | { | 483 | { |
484 | int error, base = 0; | 484 | int error, base = 0; |
485 | char *filename; | 485 | struct filename *filename; |
486 | 486 | ||
487 | /* Check for indirect call. */ | 487 | /* Check for indirect call. */ |
488 | if(regs->u_regs[UREG_G1] == 0) | 488 | if(regs->u_regs[UREG_G1] == 0) |
@@ -492,7 +492,7 @@ asmlinkage int sparc_execve(struct pt_regs *regs) | |||
492 | error = PTR_ERR(filename); | 492 | error = PTR_ERR(filename); |
493 | if(IS_ERR(filename)) | 493 | if(IS_ERR(filename)) |
494 | goto out; | 494 | goto out; |
495 | error = do_execve(filename, | 495 | error = do_execve(filename->name, |
496 | (const char __user *const __user *) | 496 | (const char __user *const __user *) |
497 | regs->u_regs[base + UREG_I1], | 497 | regs->u_regs[base + UREG_I1], |
498 | (const char __user *const __user *) | 498 | (const char __user *const __user *) |
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index aff0c72fac09..fcaa59421126 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -722,7 +722,7 @@ EXPORT_SYMBOL(dump_fpu); | |||
722 | asmlinkage int sparc_execve(struct pt_regs *regs) | 722 | asmlinkage int sparc_execve(struct pt_regs *regs) |
723 | { | 723 | { |
724 | int error, base = 0; | 724 | int error, base = 0; |
725 | char *filename; | 725 | struct filename *filename; |
726 | 726 | ||
727 | /* User register window flush is done by entry.S */ | 727 | /* User register window flush is done by entry.S */ |
728 | 728 | ||
@@ -734,7 +734,7 @@ asmlinkage int sparc_execve(struct pt_regs *regs) | |||
734 | error = PTR_ERR(filename); | 734 | error = PTR_ERR(filename); |
735 | if (IS_ERR(filename)) | 735 | if (IS_ERR(filename)) |
736 | goto out; | 736 | goto out; |
737 | error = do_execve(filename, | 737 | error = do_execve(filename->name, |
738 | (const char __user *const __user *) | 738 | (const char __user *const __user *) |
739 | regs->u_regs[base + UREG_I1], | 739 | regs->u_regs[base + UREG_I1], |
740 | (const char __user *const __user *) | 740 | (const char __user *const __user *) |
diff --git a/arch/sparc/kernel/sys_sparc32.c b/arch/sparc/kernel/sys_sparc32.c index d862499eb01c..c3239811a1b5 100644 --- a/arch/sparc/kernel/sys_sparc32.c +++ b/arch/sparc/kernel/sys_sparc32.c | |||
@@ -403,7 +403,7 @@ asmlinkage long compat_sys_rt_sigaction(int sig, | |||
403 | asmlinkage long sparc32_execve(struct pt_regs *regs) | 403 | asmlinkage long sparc32_execve(struct pt_regs *regs) |
404 | { | 404 | { |
405 | int error, base = 0; | 405 | int error, base = 0; |
406 | char *filename; | 406 | struct filename *filename; |
407 | 407 | ||
408 | /* User register window flush is done by entry.S */ | 408 | /* User register window flush is done by entry.S */ |
409 | 409 | ||
@@ -416,7 +416,7 @@ asmlinkage long sparc32_execve(struct pt_regs *regs) | |||
416 | if (IS_ERR(filename)) | 416 | if (IS_ERR(filename)) |
417 | goto out; | 417 | goto out; |
418 | 418 | ||
419 | error = compat_do_execve(filename, | 419 | error = compat_do_execve(filename->name, |
420 | compat_ptr(regs->u_regs[base + UREG_I1]), | 420 | compat_ptr(regs->u_regs[base + UREG_I1]), |
421 | compat_ptr(regs->u_regs[base + UREG_I2]), regs); | 421 | compat_ptr(regs->u_regs[base + UREG_I2]), regs); |
422 | 422 | ||
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 6be799150501..622560030a58 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c | |||
@@ -594,13 +594,13 @@ SYSCALL_DEFINE4(execve, const char __user *, path, | |||
594 | struct pt_regs *, regs) | 594 | struct pt_regs *, regs) |
595 | { | 595 | { |
596 | long error; | 596 | long error; |
597 | char *filename; | 597 | struct filename *filename; |
598 | 598 | ||
599 | filename = getname(path); | 599 | filename = getname(path); |
600 | error = PTR_ERR(filename); | 600 | error = PTR_ERR(filename); |
601 | if (IS_ERR(filename)) | 601 | if (IS_ERR(filename)) |
602 | goto out; | 602 | goto out; |
603 | error = do_execve(filename, argv, envp, regs); | 603 | error = do_execve(filename->name, argv, envp, regs); |
604 | putname(filename); | 604 | putname(filename); |
605 | if (error == 0) | 605 | if (error == 0) |
606 | single_step_execve(); | 606 | single_step_execve(); |
@@ -615,13 +615,13 @@ long compat_sys_execve(const char __user *path, | |||
615 | struct pt_regs *regs) | 615 | struct pt_regs *regs) |
616 | { | 616 | { |
617 | long error; | 617 | long error; |
618 | char *filename; | 618 | struct filename *filename; |
619 | 619 | ||
620 | filename = getname(path); | 620 | filename = getname(path); |
621 | error = PTR_ERR(filename); | 621 | error = PTR_ERR(filename); |
622 | if (IS_ERR(filename)) | 622 | if (IS_ERR(filename)) |
623 | goto out; | 623 | goto out; |
624 | error = compat_do_execve(filename, argv, envp, regs); | 624 | error = compat_do_execve(filename->name, argv, envp, regs); |
625 | putname(filename); | 625 | putname(filename); |
626 | if (error == 0) | 626 | if (error == 0) |
627 | single_step_execve(); | 627 | single_step_execve(); |
diff --git a/arch/unicore32/kernel/sys.c b/arch/unicore32/kernel/sys.c index 5fd9af773e15..fabdee96110b 100644 --- a/arch/unicore32/kernel/sys.c +++ b/arch/unicore32/kernel/sys.c | |||
@@ -51,13 +51,13 @@ asmlinkage long __sys_execve(const char __user *filename, | |||
51 | struct pt_regs *regs) | 51 | struct pt_regs *regs) |
52 | { | 52 | { |
53 | int error; | 53 | int error; |
54 | char *fn; | 54 | struct filename *fn; |
55 | 55 | ||
56 | fn = getname(filename); | 56 | fn = getname(filename); |
57 | error = PTR_ERR(fn); | 57 | error = PTR_ERR(fn); |
58 | if (IS_ERR(fn)) | 58 | if (IS_ERR(fn)) |
59 | goto out; | 59 | goto out; |
60 | error = do_execve(fn, argv, envp, regs); | 60 | error = do_execve(fn->name, argv, envp, regs); |
61 | putname(fn); | 61 | putname(fn); |
62 | out: | 62 | out: |
63 | return error; | 63 | return error; |
diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index bc44311aa18c..bc020825cce5 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c | |||
@@ -328,13 +328,13 @@ long xtensa_execve(const char __user *name, | |||
328 | struct pt_regs *regs) | 328 | struct pt_regs *regs) |
329 | { | 329 | { |
330 | long error; | 330 | long error; |
331 | char * filename; | 331 | struct filename *filename; |
332 | 332 | ||
333 | filename = getname(name); | 333 | filename = getname(name); |
334 | error = PTR_ERR(filename); | 334 | error = PTR_ERR(filename); |
335 | if (IS_ERR(filename)) | 335 | if (IS_ERR(filename)) |
336 | goto out; | 336 | goto out; |
337 | error = do_execve(filename, argv, envp, regs); | 337 | error = do_execve(filename->name, argv, envp, regs); |
338 | putname(filename); | 338 | putname(filename); |
339 | out: | 339 | out: |
340 | return error; | 340 | return error; |
diff --git a/fs/compat.c b/fs/compat.c index b7a24d0ca30d..015e1e1f87c6 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -776,16 +776,16 @@ asmlinkage long compat_sys_mount(const char __user * dev_name, | |||
776 | char *kernel_type; | 776 | char *kernel_type; |
777 | unsigned long data_page; | 777 | unsigned long data_page; |
778 | char *kernel_dev; | 778 | char *kernel_dev; |
779 | char *dir_page; | 779 | struct filename *dir; |
780 | int retval; | 780 | int retval; |
781 | 781 | ||
782 | retval = copy_mount_string(type, &kernel_type); | 782 | retval = copy_mount_string(type, &kernel_type); |
783 | if (retval < 0) | 783 | if (retval < 0) |
784 | goto out; | 784 | goto out; |
785 | 785 | ||
786 | dir_page = getname(dir_name); | 786 | dir = getname(dir_name); |
787 | retval = PTR_ERR(dir_page); | 787 | retval = PTR_ERR(dir); |
788 | if (IS_ERR(dir_page)) | 788 | if (IS_ERR(dir)) |
789 | goto out1; | 789 | goto out1; |
790 | 790 | ||
791 | retval = copy_mount_string(dev_name, &kernel_dev); | 791 | retval = copy_mount_string(dev_name, &kernel_dev); |
@@ -807,7 +807,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name, | |||
807 | } | 807 | } |
808 | } | 808 | } |
809 | 809 | ||
810 | retval = do_mount(kernel_dev, dir_page, kernel_type, | 810 | retval = do_mount(kernel_dev, dir->name, kernel_type, |
811 | flags, (void*)data_page); | 811 | flags, (void*)data_page); |
812 | 812 | ||
813 | out4: | 813 | out4: |
@@ -815,7 +815,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name, | |||
815 | out3: | 815 | out3: |
816 | kfree(kernel_dev); | 816 | kfree(kernel_dev); |
817 | out2: | 817 | out2: |
818 | putname(dir_page); | 818 | putname(dir); |
819 | out1: | 819 | out1: |
820 | kfree(kernel_type); | 820 | kfree(kernel_type); |
821 | out: | 821 | out: |
@@ -105,7 +105,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt) | |||
105 | SYSCALL_DEFINE1(uselib, const char __user *, library) | 105 | SYSCALL_DEFINE1(uselib, const char __user *, library) |
106 | { | 106 | { |
107 | struct file *file; | 107 | struct file *file; |
108 | char *tmp = getname(library); | 108 | struct filename *tmp = getname(library); |
109 | int error = PTR_ERR(tmp); | 109 | int error = PTR_ERR(tmp); |
110 | static const struct open_flags uselib_flags = { | 110 | static const struct open_flags uselib_flags = { |
111 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, | 111 | .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC, |
@@ -116,7 +116,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library) | |||
116 | if (IS_ERR(tmp)) | 116 | if (IS_ERR(tmp)) |
117 | goto out; | 117 | goto out; |
118 | 118 | ||
119 | file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW); | 119 | file = do_filp_open(AT_FDCWD, tmp->name, &uselib_flags, LOOKUP_FOLLOW); |
120 | putname(tmp); | 120 | putname(tmp); |
121 | error = PTR_ERR(file); | 121 | error = PTR_ERR(file); |
122 | if (IS_ERR(file)) | 122 | if (IS_ERR(file)) |
@@ -1664,10 +1664,10 @@ SYSCALL_DEFINE3(execve, | |||
1664 | const char __user *const __user *, argv, | 1664 | const char __user *const __user *, argv, |
1665 | const char __user *const __user *, envp) | 1665 | const char __user *const __user *, envp) |
1666 | { | 1666 | { |
1667 | const char *path = getname(filename); | 1667 | struct filename *path = getname(filename); |
1668 | int error = PTR_ERR(path); | 1668 | int error = PTR_ERR(path); |
1669 | if (!IS_ERR(path)) { | 1669 | if (!IS_ERR(path)) { |
1670 | error = do_execve(path, argv, envp, current_pt_regs()); | 1670 | error = do_execve(path->name, argv, envp, current_pt_regs()); |
1671 | putname(path); | 1671 | putname(path); |
1672 | } | 1672 | } |
1673 | return error; | 1673 | return error; |
@@ -1677,10 +1677,11 @@ asmlinkage long compat_sys_execve(const char __user * filename, | |||
1677 | const compat_uptr_t __user * argv, | 1677 | const compat_uptr_t __user * argv, |
1678 | const compat_uptr_t __user * envp) | 1678 | const compat_uptr_t __user * envp) |
1679 | { | 1679 | { |
1680 | const char *path = getname(filename); | 1680 | struct filename *path = getname(filename); |
1681 | int error = PTR_ERR(path); | 1681 | int error = PTR_ERR(path); |
1682 | if (!IS_ERR(path)) { | 1682 | if (!IS_ERR(path)) { |
1683 | error = compat_do_execve(path, argv, envp, current_pt_regs()); | 1683 | error = compat_do_execve(path->name, argv, envp, |
1684 | current_pt_regs()); | ||
1684 | putname(path); | 1685 | putname(path); |
1685 | } | 1686 | } |
1686 | return error; | 1687 | return error; |
diff --git a/fs/filesystems.c b/fs/filesystems.c index 96f24286667a..da165f6adcbf 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c | |||
@@ -124,7 +124,7 @@ EXPORT_SYMBOL(unregister_filesystem); | |||
124 | static int fs_index(const char __user * __name) | 124 | static int fs_index(const char __user * __name) |
125 | { | 125 | { |
126 | struct file_system_type * tmp; | 126 | struct file_system_type * tmp; |
127 | char * name; | 127 | struct filename *name; |
128 | int err, index; | 128 | int err, index; |
129 | 129 | ||
130 | name = getname(__name); | 130 | name = getname(__name); |
@@ -135,7 +135,7 @@ static int fs_index(const char __user * __name) | |||
135 | err = -EINVAL; | 135 | err = -EINVAL; |
136 | read_lock(&file_systems_lock); | 136 | read_lock(&file_systems_lock); |
137 | for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) { | 137 | for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) { |
138 | if (strcmp(tmp->name,name) == 0) { | 138 | if (strcmp(tmp->name, name->name) == 0) { |
139 | err = index; | 139 | err = index; |
140 | break; | 140 | break; |
141 | } | 141 | } |
diff --git a/fs/namei.c b/fs/namei.c index 9cc0fce7fc91..ec638d27642f 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -117,18 +117,37 @@ | |||
117 | * POSIX.1 2.4: an empty pathname is invalid (ENOENT). | 117 | * POSIX.1 2.4: an empty pathname is invalid (ENOENT). |
118 | * PATH_MAX includes the nul terminator --RR. | 118 | * PATH_MAX includes the nul terminator --RR. |
119 | */ | 119 | */ |
120 | static char *getname_flags(const char __user *filename, int flags, int *empty) | 120 | void final_putname(struct filename *name) |
121 | { | 121 | { |
122 | char *result = __getname(), *err; | 122 | __putname(name->name); |
123 | kfree(name); | ||
124 | } | ||
125 | |||
126 | static struct filename * | ||
127 | getname_flags(const char __user *filename, int flags, int *empty) | ||
128 | { | ||
129 | struct filename *result, *err; | ||
130 | char *kname; | ||
123 | int len; | 131 | int len; |
124 | 132 | ||
133 | /* FIXME: create dedicated slabcache? */ | ||
134 | result = kzalloc(sizeof(*result), GFP_KERNEL); | ||
125 | if (unlikely(!result)) | 135 | if (unlikely(!result)) |
126 | return ERR_PTR(-ENOMEM); | 136 | return ERR_PTR(-ENOMEM); |
127 | 137 | ||
128 | len = strncpy_from_user(result, filename, PATH_MAX); | 138 | kname = __getname(); |
129 | err = ERR_PTR(len); | 139 | if (unlikely(!kname)) { |
130 | if (unlikely(len < 0)) | 140 | err = ERR_PTR(-ENOMEM); |
141 | goto error_free_name; | ||
142 | } | ||
143 | |||
144 | result->name = kname; | ||
145 | result->uptr = filename; | ||
146 | len = strncpy_from_user(kname, filename, PATH_MAX); | ||
147 | if (unlikely(len < 0)) { | ||
148 | err = ERR_PTR(len); | ||
131 | goto error; | 149 | goto error; |
150 | } | ||
132 | 151 | ||
133 | /* The empty path is special. */ | 152 | /* The empty path is special. */ |
134 | if (unlikely(!len)) { | 153 | if (unlikely(!len)) { |
@@ -146,22 +165,25 @@ static char *getname_flags(const char __user *filename, int flags, int *empty) | |||
146 | } | 165 | } |
147 | 166 | ||
148 | error: | 167 | error: |
149 | __putname(result); | 168 | __putname(kname); |
169 | error_free_name: | ||
170 | kfree(result); | ||
150 | return err; | 171 | return err; |
151 | } | 172 | } |
152 | 173 | ||
153 | char *getname(const char __user * filename) | 174 | struct filename * |
175 | getname(const char __user * filename) | ||
154 | { | 176 | { |
155 | return getname_flags(filename, 0, NULL); | 177 | return getname_flags(filename, 0, NULL); |
156 | } | 178 | } |
179 | EXPORT_SYMBOL(getname); | ||
157 | 180 | ||
158 | #ifdef CONFIG_AUDITSYSCALL | 181 | #ifdef CONFIG_AUDITSYSCALL |
159 | void putname(const char *name) | 182 | void putname(struct filename *name) |
160 | { | 183 | { |
161 | if (unlikely(!audit_dummy_context())) | 184 | if (unlikely(!audit_dummy_context())) |
162 | audit_putname(name); | 185 | return audit_putname(name); |
163 | else | 186 | final_putname(name); |
164 | __putname(name); | ||
165 | } | 187 | } |
166 | #endif | 188 | #endif |
167 | 189 | ||
@@ -2093,13 +2115,13 @@ int user_path_at_empty(int dfd, const char __user *name, unsigned flags, | |||
2093 | struct path *path, int *empty) | 2115 | struct path *path, int *empty) |
2094 | { | 2116 | { |
2095 | struct nameidata nd; | 2117 | struct nameidata nd; |
2096 | char *tmp = getname_flags(name, flags, empty); | 2118 | struct filename *tmp = getname_flags(name, flags, empty); |
2097 | int err = PTR_ERR(tmp); | 2119 | int err = PTR_ERR(tmp); |
2098 | if (!IS_ERR(tmp)) { | 2120 | if (!IS_ERR(tmp)) { |
2099 | 2121 | ||
2100 | BUG_ON(flags & LOOKUP_PARENT); | 2122 | BUG_ON(flags & LOOKUP_PARENT); |
2101 | 2123 | ||
2102 | err = do_path_lookup(dfd, tmp, flags, &nd); | 2124 | err = do_path_lookup(dfd, tmp->name, flags, &nd); |
2103 | putname(tmp); | 2125 | putname(tmp); |
2104 | if (!err) | 2126 | if (!err) |
2105 | *path = nd.path; | 2127 | *path = nd.path; |
@@ -2113,22 +2135,22 @@ int user_path_at(int dfd, const char __user *name, unsigned flags, | |||
2113 | return user_path_at_empty(dfd, name, flags, path, NULL); | 2135 | return user_path_at_empty(dfd, name, flags, path, NULL); |
2114 | } | 2136 | } |
2115 | 2137 | ||
2116 | static int user_path_parent(int dfd, const char __user *path, | 2138 | static struct filename * |
2117 | struct nameidata *nd, char **name) | 2139 | user_path_parent(int dfd, const char __user *path, struct nameidata *nd) |
2118 | { | 2140 | { |
2119 | char *s = getname(path); | 2141 | struct filename *s = getname(path); |
2120 | int error; | 2142 | int error; |
2121 | 2143 | ||
2122 | if (IS_ERR(s)) | 2144 | if (IS_ERR(s)) |
2123 | return PTR_ERR(s); | 2145 | return s; |
2124 | 2146 | ||
2125 | error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd); | 2147 | error = do_path_lookup(dfd, s->name, LOOKUP_PARENT, nd); |
2126 | if (error) | 2148 | if (error) { |
2127 | putname(s); | 2149 | putname(s); |
2128 | else | 2150 | return ERR_PTR(error); |
2129 | *name = s; | 2151 | } |
2130 | 2152 | ||
2131 | return error; | 2153 | return s; |
2132 | } | 2154 | } |
2133 | 2155 | ||
2134 | /* | 2156 | /* |
@@ -3039,11 +3061,11 @@ EXPORT_SYMBOL(done_path_create); | |||
3039 | 3061 | ||
3040 | struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir) | 3062 | struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir) |
3041 | { | 3063 | { |
3042 | char *tmp = getname(pathname); | 3064 | struct filename *tmp = getname(pathname); |
3043 | struct dentry *res; | 3065 | struct dentry *res; |
3044 | if (IS_ERR(tmp)) | 3066 | if (IS_ERR(tmp)) |
3045 | return ERR_CAST(tmp); | 3067 | return ERR_CAST(tmp); |
3046 | res = kern_path_create(dfd, tmp, path, is_dir); | 3068 | res = kern_path_create(dfd, tmp->name, path, is_dir); |
3047 | putname(tmp); | 3069 | putname(tmp); |
3048 | return res; | 3070 | return res; |
3049 | } | 3071 | } |
@@ -3248,13 +3270,13 @@ out: | |||
3248 | static long do_rmdir(int dfd, const char __user *pathname) | 3270 | static long do_rmdir(int dfd, const char __user *pathname) |
3249 | { | 3271 | { |
3250 | int error = 0; | 3272 | int error = 0; |
3251 | char * name; | 3273 | struct filename *name; |
3252 | struct dentry *dentry; | 3274 | struct dentry *dentry; |
3253 | struct nameidata nd; | 3275 | struct nameidata nd; |
3254 | 3276 | ||
3255 | error = user_path_parent(dfd, pathname, &nd, &name); | 3277 | name = user_path_parent(dfd, pathname, &nd); |
3256 | if (error) | 3278 | if (IS_ERR(name)) |
3257 | return error; | 3279 | return PTR_ERR(name); |
3258 | 3280 | ||
3259 | switch(nd.last_type) { | 3281 | switch(nd.last_type) { |
3260 | case LAST_DOTDOT: | 3282 | case LAST_DOTDOT: |
@@ -3343,14 +3365,14 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
3343 | static long do_unlinkat(int dfd, const char __user *pathname) | 3365 | static long do_unlinkat(int dfd, const char __user *pathname) |
3344 | { | 3366 | { |
3345 | int error; | 3367 | int error; |
3346 | char *name; | 3368 | struct filename *name; |
3347 | struct dentry *dentry; | 3369 | struct dentry *dentry; |
3348 | struct nameidata nd; | 3370 | struct nameidata nd; |
3349 | struct inode *inode = NULL; | 3371 | struct inode *inode = NULL; |
3350 | 3372 | ||
3351 | error = user_path_parent(dfd, pathname, &nd, &name); | 3373 | name = user_path_parent(dfd, pathname, &nd); |
3352 | if (error) | 3374 | if (IS_ERR(name)) |
3353 | return error; | 3375 | return PTR_ERR(name); |
3354 | 3376 | ||
3355 | error = -EISDIR; | 3377 | error = -EISDIR; |
3356 | if (nd.last_type != LAST_NORM) | 3378 | if (nd.last_type != LAST_NORM) |
@@ -3434,7 +3456,7 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, | |||
3434 | int, newdfd, const char __user *, newname) | 3456 | int, newdfd, const char __user *, newname) |
3435 | { | 3457 | { |
3436 | int error; | 3458 | int error; |
3437 | char *from; | 3459 | struct filename *from; |
3438 | struct dentry *dentry; | 3460 | struct dentry *dentry; |
3439 | struct path path; | 3461 | struct path path; |
3440 | 3462 | ||
@@ -3447,9 +3469,9 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, | |||
3447 | if (IS_ERR(dentry)) | 3469 | if (IS_ERR(dentry)) |
3448 | goto out_putname; | 3470 | goto out_putname; |
3449 | 3471 | ||
3450 | error = security_path_symlink(&path, dentry, from); | 3472 | error = security_path_symlink(&path, dentry, from->name); |
3451 | if (!error) | 3473 | if (!error) |
3452 | error = vfs_symlink(path.dentry->d_inode, dentry, from); | 3474 | error = vfs_symlink(path.dentry->d_inode, dentry, from->name); |
3453 | done_path_create(&path, dentry); | 3475 | done_path_create(&path, dentry); |
3454 | out_putname: | 3476 | out_putname: |
3455 | putname(from); | 3477 | putname(from); |
@@ -3729,17 +3751,21 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, | |||
3729 | struct dentry *old_dentry, *new_dentry; | 3751 | struct dentry *old_dentry, *new_dentry; |
3730 | struct dentry *trap; | 3752 | struct dentry *trap; |
3731 | struct nameidata oldnd, newnd; | 3753 | struct nameidata oldnd, newnd; |
3732 | char *from; | 3754 | struct filename *from; |
3733 | char *to; | 3755 | struct filename *to; |
3734 | int error; | 3756 | int error; |
3735 | 3757 | ||
3736 | error = user_path_parent(olddfd, oldname, &oldnd, &from); | 3758 | from = user_path_parent(olddfd, oldname, &oldnd); |
3737 | if (error) | 3759 | if (IS_ERR(from)) { |
3760 | error = PTR_ERR(from); | ||
3738 | goto exit; | 3761 | goto exit; |
3762 | } | ||
3739 | 3763 | ||
3740 | error = user_path_parent(newdfd, newname, &newnd, &to); | 3764 | to = user_path_parent(newdfd, newname, &newnd); |
3741 | if (error) | 3765 | if (IS_ERR(to)) { |
3766 | error = PTR_ERR(to); | ||
3742 | goto exit1; | 3767 | goto exit1; |
3768 | } | ||
3743 | 3769 | ||
3744 | error = -EXDEV; | 3770 | error = -EXDEV; |
3745 | if (oldnd.path.mnt != newnd.path.mnt) | 3771 | if (oldnd.path.mnt != newnd.path.mnt) |
diff --git a/fs/namespace.c b/fs/namespace.c index fc33207e28ad..24960626bb6b 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -2408,7 +2408,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | |||
2408 | { | 2408 | { |
2409 | int ret; | 2409 | int ret; |
2410 | char *kernel_type; | 2410 | char *kernel_type; |
2411 | char *kernel_dir; | 2411 | struct filename *kernel_dir; |
2412 | char *kernel_dev; | 2412 | char *kernel_dev; |
2413 | unsigned long data_page; | 2413 | unsigned long data_page; |
2414 | 2414 | ||
@@ -2430,7 +2430,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, | |||
2430 | if (ret < 0) | 2430 | if (ret < 0) |
2431 | goto out_data; | 2431 | goto out_data; |
2432 | 2432 | ||
2433 | ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags, | 2433 | ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags, |
2434 | (void *) data_page); | 2434 | (void *) data_page); |
2435 | 2435 | ||
2436 | free_page(data_page); | 2436 | free_page(data_page); |
@@ -895,13 +895,13 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) | |||
895 | { | 895 | { |
896 | struct open_flags op; | 896 | struct open_flags op; |
897 | int lookup = build_open_flags(flags, mode, &op); | 897 | int lookup = build_open_flags(flags, mode, &op); |
898 | char *tmp = getname(filename); | 898 | struct filename *tmp = getname(filename); |
899 | int fd = PTR_ERR(tmp); | 899 | int fd = PTR_ERR(tmp); |
900 | 900 | ||
901 | if (!IS_ERR(tmp)) { | 901 | if (!IS_ERR(tmp)) { |
902 | fd = get_unused_fd_flags(flags); | 902 | fd = get_unused_fd_flags(flags); |
903 | if (fd >= 0) { | 903 | if (fd >= 0) { |
904 | struct file *f = do_filp_open(dfd, tmp, &op, lookup); | 904 | struct file *f = do_filp_open(dfd, tmp->name, &op, lookup); |
905 | if (IS_ERR(f)) { | 905 | if (IS_ERR(f)) { |
906 | put_unused_fd(fd); | 906 | put_unused_fd(fd); |
907 | fd = PTR_ERR(f); | 907 | fd = PTR_ERR(f); |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index ff0135d6bc51..af1661f7a54f 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
@@ -331,11 +331,11 @@ static struct super_block *quotactl_block(const char __user *special, int cmd) | |||
331 | #ifdef CONFIG_BLOCK | 331 | #ifdef CONFIG_BLOCK |
332 | struct block_device *bdev; | 332 | struct block_device *bdev; |
333 | struct super_block *sb; | 333 | struct super_block *sb; |
334 | char *tmp = getname(special); | 334 | struct filename *tmp = getname(special); |
335 | 335 | ||
336 | if (IS_ERR(tmp)) | 336 | if (IS_ERR(tmp)) |
337 | return ERR_CAST(tmp); | 337 | return ERR_CAST(tmp); |
338 | bdev = lookup_bdev(tmp); | 338 | bdev = lookup_bdev(tmp->name); |
339 | putname(tmp); | 339 | putname(tmp); |
340 | if (IS_ERR(bdev)) | 340 | if (IS_ERR(bdev)) |
341 | return ERR_CAST(bdev); | 341 | return ERR_CAST(bdev); |
diff --git a/include/linux/audit.h b/include/linux/audit.h index 3df643d1ac5b..94d29164803f 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -460,6 +460,8 @@ extern int audit_classify_arch(int arch); | |||
460 | #define AUDIT_TYPE_CHILD_DELETE 3 /* a child being deleted */ | 460 | #define AUDIT_TYPE_CHILD_DELETE 3 /* a child being deleted */ |
461 | #define AUDIT_TYPE_CHILD_CREATE 4 /* a child being created */ | 461 | #define AUDIT_TYPE_CHILD_CREATE 4 /* a child being created */ |
462 | 462 | ||
463 | struct filename; | ||
464 | |||
463 | #ifdef CONFIG_AUDITSYSCALL | 465 | #ifdef CONFIG_AUDITSYSCALL |
464 | /* These are defined in auditsc.c */ | 466 | /* These are defined in auditsc.c */ |
465 | /* Public API */ | 467 | /* Public API */ |
@@ -469,8 +471,8 @@ extern void __audit_syscall_entry(int arch, | |||
469 | int major, unsigned long a0, unsigned long a1, | 471 | int major, unsigned long a0, unsigned long a1, |
470 | unsigned long a2, unsigned long a3); | 472 | unsigned long a2, unsigned long a3); |
471 | extern void __audit_syscall_exit(int ret_success, long ret_value); | 473 | extern void __audit_syscall_exit(int ret_success, long ret_value); |
472 | extern void __audit_getname(const char *name); | 474 | extern void __audit_getname(struct filename *name); |
473 | extern void audit_putname(const char *name); | 475 | extern void audit_putname(struct filename *name); |
474 | extern void __audit_inode(const char *name, const struct dentry *dentry, | 476 | extern void __audit_inode(const char *name, const struct dentry *dentry, |
475 | unsigned int parent); | 477 | unsigned int parent); |
476 | extern void __audit_inode_child(const struct inode *parent, | 478 | extern void __audit_inode_child(const struct inode *parent, |
@@ -505,7 +507,7 @@ static inline void audit_syscall_exit(void *pt_regs) | |||
505 | __audit_syscall_exit(success, return_code); | 507 | __audit_syscall_exit(success, return_code); |
506 | } | 508 | } |
507 | } | 509 | } |
508 | static inline void audit_getname(const char *name) | 510 | static inline void audit_getname(struct filename *name) |
509 | { | 511 | { |
510 | if (unlikely(!audit_dummy_context())) | 512 | if (unlikely(!audit_dummy_context())) |
511 | __audit_getname(name); | 513 | __audit_getname(name); |
@@ -663,9 +665,9 @@ static inline int audit_dummy_context(void) | |||
663 | { | 665 | { |
664 | return 1; | 666 | return 1; |
665 | } | 667 | } |
666 | static inline void audit_getname(const char *name) | 668 | static inline void audit_getname(struct filename *name) |
667 | { } | 669 | { } |
668 | static inline void audit_putname(const char *name) | 670 | static inline void audit_putname(struct filename *name) |
669 | { } | 671 | { } |
670 | static inline void __audit_inode(const char *name, const struct dentry *dentry, | 672 | static inline void __audit_inode(const char *name, const struct dentry *dentry, |
671 | unsigned int parent) | 673 | unsigned int parent) |
diff --git a/include/linux/fs.h b/include/linux/fs.h index b44b4ca82164..6c93b46f46dc 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -2196,6 +2196,10 @@ static inline int break_lease(struct inode *inode, unsigned int mode) | |||
2196 | #endif /* CONFIG_FILE_LOCKING */ | 2196 | #endif /* CONFIG_FILE_LOCKING */ |
2197 | 2197 | ||
2198 | /* fs/open.c */ | 2198 | /* fs/open.c */ |
2199 | struct filename { | ||
2200 | const char *name; /* pointer to actual string */ | ||
2201 | const __user char *uptr; /* original userland pointer */ | ||
2202 | }; | ||
2199 | 2203 | ||
2200 | extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, | 2204 | extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, |
2201 | struct file *filp); | 2205 | struct file *filp); |
@@ -2208,7 +2212,9 @@ extern struct file *file_open_root(struct dentry *, struct vfsmount *, | |||
2208 | const char *, int); | 2212 | const char *, int); |
2209 | extern struct file * dentry_open(const struct path *, int, const struct cred *); | 2213 | extern struct file * dentry_open(const struct path *, int, const struct cred *); |
2210 | extern int filp_close(struct file *, fl_owner_t id); | 2214 | extern int filp_close(struct file *, fl_owner_t id); |
2211 | extern char * getname(const char __user *); | 2215 | |
2216 | extern struct filename *getname(const char __user *); | ||
2217 | |||
2212 | enum { | 2218 | enum { |
2213 | FILE_CREATED = 1, | 2219 | FILE_CREATED = 1, |
2214 | FILE_OPENED = 2 | 2220 | FILE_OPENED = 2 |
@@ -2228,12 +2234,14 @@ extern void __init vfs_caches_init(unsigned long); | |||
2228 | 2234 | ||
2229 | extern struct kmem_cache *names_cachep; | 2235 | extern struct kmem_cache *names_cachep; |
2230 | 2236 | ||
2237 | extern void final_putname(struct filename *name); | ||
2238 | |||
2231 | #define __getname() kmem_cache_alloc(names_cachep, GFP_KERNEL) | 2239 | #define __getname() kmem_cache_alloc(names_cachep, GFP_KERNEL) |
2232 | #define __putname(name) kmem_cache_free(names_cachep, (void *)(name)) | 2240 | #define __putname(name) kmem_cache_free(names_cachep, (void *)(name)) |
2233 | #ifndef CONFIG_AUDITSYSCALL | 2241 | #ifndef CONFIG_AUDITSYSCALL |
2234 | #define putname(name) __putname(name) | 2242 | #define putname(name) final_putname(name) |
2235 | #else | 2243 | #else |
2236 | extern void putname(const char *name); | 2244 | extern void putname(struct filename *name); |
2237 | #endif | 2245 | #endif |
2238 | 2246 | ||
2239 | #ifdef CONFIG_BLOCK | 2247 | #ifdef CONFIG_BLOCK |
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 9553ed006042..6c5d9dcc9030 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -772,7 +772,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, | |||
772 | { | 772 | { |
773 | struct path path; | 773 | struct path path; |
774 | struct file *filp; | 774 | struct file *filp; |
775 | char *name; | 775 | struct filename *name; |
776 | struct mq_attr attr; | 776 | struct mq_attr attr; |
777 | int fd, error; | 777 | int fd, error; |
778 | struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; | 778 | struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; |
@@ -795,7 +795,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, | |||
795 | ro = mnt_want_write(mnt); /* we'll drop it in any case */ | 795 | ro = mnt_want_write(mnt); /* we'll drop it in any case */ |
796 | error = 0; | 796 | error = 0; |
797 | mutex_lock(&root->d_inode->i_mutex); | 797 | mutex_lock(&root->d_inode->i_mutex); |
798 | path.dentry = lookup_one_len(name, root, strlen(name)); | 798 | path.dentry = lookup_one_len(name->name, root, strlen(name->name)); |
799 | if (IS_ERR(path.dentry)) { | 799 | if (IS_ERR(path.dentry)) { |
800 | error = PTR_ERR(path.dentry); | 800 | error = PTR_ERR(path.dentry); |
801 | goto out_putfd; | 801 | goto out_putfd; |
@@ -804,7 +804,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, | |||
804 | 804 | ||
805 | if (oflag & O_CREAT) { | 805 | if (oflag & O_CREAT) { |
806 | if (path.dentry->d_inode) { /* entry already exists */ | 806 | if (path.dentry->d_inode) { /* entry already exists */ |
807 | audit_inode(name, path.dentry, 0); | 807 | audit_inode(name->name, path.dentry, 0); |
808 | if (oflag & O_EXCL) { | 808 | if (oflag & O_EXCL) { |
809 | error = -EEXIST; | 809 | error = -EEXIST; |
810 | goto out; | 810 | goto out; |
@@ -824,7 +824,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, | |||
824 | error = -ENOENT; | 824 | error = -ENOENT; |
825 | goto out; | 825 | goto out; |
826 | } | 826 | } |
827 | audit_inode(name, path.dentry, 0); | 827 | audit_inode(name->name, path.dentry, 0); |
828 | filp = do_open(&path, oflag); | 828 | filp = do_open(&path, oflag); |
829 | } | 829 | } |
830 | 830 | ||
@@ -849,7 +849,7 @@ out_putname: | |||
849 | SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) | 849 | SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) |
850 | { | 850 | { |
851 | int err; | 851 | int err; |
852 | char *name; | 852 | struct filename *name; |
853 | struct dentry *dentry; | 853 | struct dentry *dentry; |
854 | struct inode *inode = NULL; | 854 | struct inode *inode = NULL; |
855 | struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; | 855 | struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; |
@@ -863,7 +863,8 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) | |||
863 | if (err) | 863 | if (err) |
864 | goto out_name; | 864 | goto out_name; |
865 | mutex_lock_nested(&mnt->mnt_root->d_inode->i_mutex, I_MUTEX_PARENT); | 865 | mutex_lock_nested(&mnt->mnt_root->d_inode->i_mutex, I_MUTEX_PARENT); |
866 | dentry = lookup_one_len(name, mnt->mnt_root, strlen(name)); | 866 | dentry = lookup_one_len(name->name, mnt->mnt_root, |
867 | strlen(name->name)); | ||
867 | if (IS_ERR(dentry)) { | 868 | if (IS_ERR(dentry)) { |
868 | err = PTR_ERR(dentry); | 869 | err = PTR_ERR(dentry); |
869 | goto out_unlock; | 870 | goto out_unlock; |
diff --git a/kernel/acct.c b/kernel/acct.c index 5be01017d30f..08354195eecc 100644 --- a/kernel/acct.c +++ b/kernel/acct.c | |||
@@ -260,10 +260,10 @@ SYSCALL_DEFINE1(acct, const char __user *, name) | |||
260 | return -EPERM; | 260 | return -EPERM; |
261 | 261 | ||
262 | if (name) { | 262 | if (name) { |
263 | char *tmp = getname(name); | 263 | struct filename *tmp = getname(name); |
264 | if (IS_ERR(tmp)) | 264 | if (IS_ERR(tmp)) |
265 | return (PTR_ERR(tmp)); | 265 | return (PTR_ERR(tmp)); |
266 | error = acct_on(tmp); | 266 | error = acct_on(tmp->name); |
267 | putname(tmp); | 267 | putname(tmp); |
268 | } else { | 268 | } else { |
269 | struct bsd_acct_struct *acct; | 269 | struct bsd_acct_struct *acct; |
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index d147585e9ef3..d4d82319eed5 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -103,28 +103,29 @@ struct audit_cap_data { | |||
103 | * we don't let putname() free it (instead we free all of the saved | 103 | * we don't let putname() free it (instead we free all of the saved |
104 | * pointers at syscall exit time). | 104 | * pointers at syscall exit time). |
105 | * | 105 | * |
106 | * Further, in fs/namei.c:path_lookup() we store the inode and device. */ | 106 | * Further, in fs/namei.c:path_lookup() we store the inode and device. |
107 | */ | ||
107 | struct audit_names { | 108 | struct audit_names { |
108 | struct list_head list; /* audit_context->names_list */ | 109 | struct list_head list; /* audit_context->names_list */ |
109 | const char *name; | 110 | struct filename *name; |
110 | unsigned long ino; | 111 | unsigned long ino; |
111 | dev_t dev; | 112 | dev_t dev; |
112 | umode_t mode; | 113 | umode_t mode; |
113 | kuid_t uid; | 114 | kuid_t uid; |
114 | kgid_t gid; | 115 | kgid_t gid; |
115 | dev_t rdev; | 116 | dev_t rdev; |
116 | u32 osid; | 117 | u32 osid; |
117 | struct audit_cap_data fcap; | 118 | struct audit_cap_data fcap; |
118 | unsigned int fcap_ver; | 119 | unsigned int fcap_ver; |
119 | int name_len; /* number of name's characters to log */ | 120 | int name_len; /* number of name's characters to log */ |
120 | unsigned char type; /* record type */ | 121 | unsigned char type; /* record type */ |
121 | bool name_put; /* call __putname() for this name */ | 122 | bool name_put; /* call __putname() for this name */ |
122 | /* | 123 | /* |
123 | * This was an allocated audit_names and not from the array of | 124 | * This was an allocated audit_names and not from the array of |
124 | * names allocated in the task audit context. Thus this name | 125 | * names allocated in the task audit context. Thus this name |
125 | * should be freed on syscall exit | 126 | * should be freed on syscall exit |
126 | */ | 127 | */ |
127 | bool should_free; | 128 | bool should_free; |
128 | }; | 129 | }; |
129 | 130 | ||
130 | struct audit_aux_data { | 131 | struct audit_aux_data { |
@@ -996,7 +997,7 @@ static inline void audit_free_names(struct audit_context *context) | |||
996 | context->ino_count); | 997 | context->ino_count); |
997 | list_for_each_entry(n, &context->names_list, list) { | 998 | list_for_each_entry(n, &context->names_list, list) { |
998 | printk(KERN_ERR "names[%d] = %p = %s\n", i, | 999 | printk(KERN_ERR "names[%d] = %p = %s\n", i, |
999 | n->name, n->name ?: "(null)"); | 1000 | n->name, n->name->name ?: "(null)"); |
1000 | } | 1001 | } |
1001 | dump_stack(); | 1002 | dump_stack(); |
1002 | return; | 1003 | return; |
@@ -1553,7 +1554,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, | |||
1553 | case AUDIT_NAME_FULL: | 1554 | case AUDIT_NAME_FULL: |
1554 | /* log the full path */ | 1555 | /* log the full path */ |
1555 | audit_log_format(ab, " name="); | 1556 | audit_log_format(ab, " name="); |
1556 | audit_log_untrustedstring(ab, n->name); | 1557 | audit_log_untrustedstring(ab, n->name->name); |
1557 | break; | 1558 | break; |
1558 | case 0: | 1559 | case 0: |
1559 | /* name was specified as a relative path and the | 1560 | /* name was specified as a relative path and the |
@@ -1563,7 +1564,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n, | |||
1563 | default: | 1564 | default: |
1564 | /* log the name's directory component */ | 1565 | /* log the name's directory component */ |
1565 | audit_log_format(ab, " name="); | 1566 | audit_log_format(ab, " name="); |
1566 | audit_log_n_untrustedstring(ab, n->name, | 1567 | audit_log_n_untrustedstring(ab, n->name->name, |
1567 | n->name_len); | 1568 | n->name_len); |
1568 | } | 1569 | } |
1569 | } else | 1570 | } else |
@@ -2026,7 +2027,7 @@ static struct audit_names *audit_alloc_name(struct audit_context *context, | |||
2026 | * Add a name to the list of audit names for this context. | 2027 | * Add a name to the list of audit names for this context. |
2027 | * Called from fs/namei.c:getname(). | 2028 | * Called from fs/namei.c:getname(). |
2028 | */ | 2029 | */ |
2029 | void __audit_getname(const char *name) | 2030 | void __audit_getname(struct filename *name) |
2030 | { | 2031 | { |
2031 | struct audit_context *context = current->audit_context; | 2032 | struct audit_context *context = current->audit_context; |
2032 | struct audit_names *n; | 2033 | struct audit_names *n; |
@@ -2040,6 +2041,11 @@ void __audit_getname(const char *name) | |||
2040 | return; | 2041 | return; |
2041 | } | 2042 | } |
2042 | 2043 | ||
2044 | #if AUDIT_DEBUG | ||
2045 | /* The filename _must_ have a populated ->name */ | ||
2046 | BUG_ON(!name->name); | ||
2047 | #endif | ||
2048 | |||
2043 | n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN); | 2049 | n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN); |
2044 | if (!n) | 2050 | if (!n) |
2045 | return; | 2051 | return; |
@@ -2059,7 +2065,7 @@ void __audit_getname(const char *name) | |||
2059 | * then we delay the putname until syscall exit. | 2065 | * then we delay the putname until syscall exit. |
2060 | * Called from include/linux/fs.h:putname(). | 2066 | * Called from include/linux/fs.h:putname(). |
2061 | */ | 2067 | */ |
2062 | void audit_putname(const char *name) | 2068 | void audit_putname(struct filename *name) |
2063 | { | 2069 | { |
2064 | struct audit_context *context = current->audit_context; | 2070 | struct audit_context *context = current->audit_context; |
2065 | 2071 | ||
@@ -2074,7 +2080,7 @@ void audit_putname(const char *name) | |||
2074 | 2080 | ||
2075 | list_for_each_entry(n, &context->names_list, list) | 2081 | list_for_each_entry(n, &context->names_list, list) |
2076 | printk(KERN_ERR "name[%d] = %p = %s\n", i, | 2082 | printk(KERN_ERR "name[%d] = %p = %s\n", i, |
2077 | n->name, n->name ?: "(null)"); | 2083 | n->name, n->name->name ?: "(null)"); |
2078 | } | 2084 | } |
2079 | #endif | 2085 | #endif |
2080 | __putname(name); | 2086 | __putname(name); |
@@ -2088,8 +2094,8 @@ void audit_putname(const char *name) | |||
2088 | " put_count=%d\n", | 2094 | " put_count=%d\n", |
2089 | __FILE__, __LINE__, | 2095 | __FILE__, __LINE__, |
2090 | context->serial, context->major, | 2096 | context->serial, context->major, |
2091 | context->in_syscall, name, context->name_count, | 2097 | context->in_syscall, name->name, |
2092 | context->put_count); | 2098 | context->name_count, context->put_count); |
2093 | dump_stack(); | 2099 | dump_stack(); |
2094 | } | 2100 | } |
2095 | } | 2101 | } |
@@ -2152,7 +2158,7 @@ void __audit_inode(const char *name, const struct dentry *dentry, | |||
2152 | 2158 | ||
2153 | list_for_each_entry_reverse(n, &context->names_list, list) { | 2159 | list_for_each_entry_reverse(n, &context->names_list, list) { |
2154 | /* does the name pointer match? */ | 2160 | /* does the name pointer match? */ |
2155 | if (n->name != name) | 2161 | if (!n->name || n->name->name != name) |
2156 | continue; | 2162 | continue; |
2157 | 2163 | ||
2158 | /* match the correct record type */ | 2164 | /* match the correct record type */ |
@@ -2175,7 +2181,7 @@ out_alloc: | |||
2175 | return; | 2181 | return; |
2176 | out: | 2182 | out: |
2177 | if (parent) { | 2183 | if (parent) { |
2178 | n->name_len = n->name ? parent_len(n->name) : AUDIT_NAME_FULL; | 2184 | n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL; |
2179 | n->type = AUDIT_TYPE_PARENT; | 2185 | n->type = AUDIT_TYPE_PARENT; |
2180 | } else { | 2186 | } else { |
2181 | n->name_len = AUDIT_NAME_FULL; | 2187 | n->name_len = AUDIT_NAME_FULL; |
@@ -2220,7 +2226,7 @@ void __audit_inode_child(const struct inode *parent, | |||
2220 | continue; | 2226 | continue; |
2221 | 2227 | ||
2222 | if (n->ino == parent->i_ino && | 2228 | if (n->ino == parent->i_ino && |
2223 | !audit_compare_dname_path(dname, n->name, n->name_len)) { | 2229 | !audit_compare_dname_path(dname, n->name->name, n->name_len)) { |
2224 | found_parent = n; | 2230 | found_parent = n; |
2225 | break; | 2231 | break; |
2226 | } | 2232 | } |
@@ -2236,8 +2242,8 @@ void __audit_inode_child(const struct inode *parent, | |||
2236 | if (found_parent && (n->name != found_parent->name)) | 2242 | if (found_parent && (n->name != found_parent->name)) |
2237 | continue; | 2243 | continue; |
2238 | 2244 | ||
2239 | if (!strcmp(dname, n->name) || | 2245 | if (!strcmp(dname, n->name->name) || |
2240 | !audit_compare_dname_path(dname, n->name, | 2246 | !audit_compare_dname_path(dname, n->name->name, |
2241 | found_parent ? | 2247 | found_parent ? |
2242 | found_parent->name_len : | 2248 | found_parent->name_len : |
2243 | AUDIT_NAME_FULL)) { | 2249 | AUDIT_NAME_FULL)) { |
diff --git a/mm/swapfile.c b/mm/swapfile.c index 14e254c768fc..90d2ed591de9 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -1483,7 +1483,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) | |||
1483 | struct file *swap_file, *victim; | 1483 | struct file *swap_file, *victim; |
1484 | struct address_space *mapping; | 1484 | struct address_space *mapping; |
1485 | struct inode *inode; | 1485 | struct inode *inode; |
1486 | char *pathname; | 1486 | struct filename *pathname; |
1487 | int oom_score_adj; | 1487 | int oom_score_adj; |
1488 | int i, type, prev; | 1488 | int i, type, prev; |
1489 | int err; | 1489 | int err; |
@@ -1498,8 +1498,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) | |||
1498 | if (IS_ERR(pathname)) | 1498 | if (IS_ERR(pathname)) |
1499 | goto out; | 1499 | goto out; |
1500 | 1500 | ||
1501 | victim = filp_open(pathname, O_RDWR|O_LARGEFILE, 0); | 1501 | victim = filp_open(pathname->name, O_RDWR|O_LARGEFILE, 0); |
1502 | putname(pathname); | ||
1503 | err = PTR_ERR(victim); | 1502 | err = PTR_ERR(victim); |
1504 | if (IS_ERR(victim)) | 1503 | if (IS_ERR(victim)) |
1505 | goto out; | 1504 | goto out; |
@@ -1936,7 +1935,7 @@ static int setup_swap_map_and_extents(struct swap_info_struct *p, | |||
1936 | SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | 1935 | SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) |
1937 | { | 1936 | { |
1938 | struct swap_info_struct *p; | 1937 | struct swap_info_struct *p; |
1939 | char *name; | 1938 | struct filename *name; |
1940 | struct file *swap_file = NULL; | 1939 | struct file *swap_file = NULL; |
1941 | struct address_space *mapping; | 1940 | struct address_space *mapping; |
1942 | int i; | 1941 | int i; |
@@ -1967,7 +1966,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
1967 | name = NULL; | 1966 | name = NULL; |
1968 | goto bad_swap; | 1967 | goto bad_swap; |
1969 | } | 1968 | } |
1970 | swap_file = filp_open(name, O_RDWR|O_LARGEFILE, 0); | 1969 | swap_file = filp_open(name->name, O_RDWR|O_LARGEFILE, 0); |
1971 | if (IS_ERR(swap_file)) { | 1970 | if (IS_ERR(swap_file)) { |
1972 | error = PTR_ERR(swap_file); | 1971 | error = PTR_ERR(swap_file); |
1973 | swap_file = NULL; | 1972 | swap_file = NULL; |
@@ -2053,7 +2052,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
2053 | 2052 | ||
2054 | printk(KERN_INFO "Adding %uk swap on %s. " | 2053 | printk(KERN_INFO "Adding %uk swap on %s. " |
2055 | "Priority:%d extents:%d across:%lluk %s%s%s\n", | 2054 | "Priority:%d extents:%d across:%lluk %s%s%s\n", |
2056 | p->pages<<(PAGE_SHIFT-10), name, p->prio, | 2055 | p->pages<<(PAGE_SHIFT-10), name->name, p->prio, |
2057 | nr_extents, (unsigned long long)span<<(PAGE_SHIFT-10), | 2056 | nr_extents, (unsigned long long)span<<(PAGE_SHIFT-10), |
2058 | (p->flags & SWP_SOLIDSTATE) ? "SS" : "", | 2057 | (p->flags & SWP_SOLIDSTATE) ? "SS" : "", |
2059 | (p->flags & SWP_DISCARDABLE) ? "D" : "", | 2058 | (p->flags & SWP_DISCARDABLE) ? "D" : "", |