]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
vfs: define struct filename and have getname() return it
authorJeff Layton <jlayton@redhat.com>
Wed, 10 Oct 2012 19:25:28 +0000 (15:25 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 11 Oct 2012 15:43:41 +0000 (11:43 -0400)
getname() is intended to copy pathname strings from userspace into a
kernel buffer. The result is just a string in kernel space. It would
however be quite helpful to be able to attach some ancillary info to
the string.

For instance, we could attach some audit-related info to reduce the
amount of audit-related processing needed. When auditing is enabled,
we could also call getname() on the string more than once and not
need to recopy it from userspace.

This patchset converts the getname()/putname() interfaces to return
a struct instead of a string. For now, the struct just tracks the
string in kernel space and the original userland pointer for it.

Later, we'll add other information to the struct as it becomes
convenient.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
46 files changed:
arch/alpha/kernel/osf_sys.c
arch/arm64/kernel/sys.c
arch/arm64/kernel/sys_compat.c
arch/avr32/kernel/process.c
arch/blackfin/kernel/process.c
arch/c6x/kernel/process.c
arch/cris/arch-v10/kernel/process.c
arch/cris/arch-v32/kernel/process.c
arch/frv/kernel/process.c
arch/h8300/kernel/process.c
arch/hexagon/kernel/syscall.c
arch/ia64/kernel/process.c
arch/m32r/kernel/process.c
arch/m68k/kernel/process.c
arch/microblaze/kernel/sys_microblaze.c
arch/mips/kernel/linux32.c
arch/mips/kernel/syscall.c
arch/mn10300/kernel/process.c
arch/openrisc/kernel/process.c
arch/parisc/hpux/fs.c
arch/parisc/kernel/process.c
arch/parisc/kernel/sys_parisc32.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/sys_ppc32.c
arch/score/kernel/sys_score.c
arch/sh/kernel/process_32.c
arch/sh/kernel/process_64.c
arch/sparc/kernel/process_32.c
arch/sparc/kernel/process_64.c
arch/sparc/kernel/sys_sparc32.c
arch/tile/kernel/process.c
arch/unicore32/kernel/sys.c
arch/xtensa/kernel/process.c
fs/compat.c
fs/exec.c
fs/filesystems.c
fs/namei.c
fs/namespace.c
fs/open.c
fs/quota/quota.c
include/linux/audit.h
include/linux/fs.h
ipc/mqueue.c
kernel/acct.c
kernel/auditsc.c
mm/swapfile.c

index 63e77e3944ced280724c964b7690502341383695..9eb090582cf1eb2c557e03025bafc73846fde02f 100644 (file)
@@ -449,7 +449,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
 {
        int retval;
        struct cdfs_args tmp;
-       char *devname;
+       struct filename *devname;
 
        retval = -EFAULT;
        if (copy_from_user(&tmp, args, sizeof(tmp)))
@@ -458,7 +458,7 @@ osf_ufs_mount(char *dirname, struct ufs_args __user *args, int flags)
        retval = PTR_ERR(devname);
        if (IS_ERR(devname))
                goto out;
-       retval = do_mount(devname, dirname, "ext2", flags, NULL);
+       retval = do_mount(devname->name, dirname, "ext2", flags, NULL);
        putname(devname);
  out:
        return retval;
@@ -469,7 +469,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
 {
        int retval;
        struct cdfs_args tmp;
-       char *devname;
+       struct filename *devname;
 
        retval = -EFAULT;
        if (copy_from_user(&tmp, args, sizeof(tmp)))
@@ -478,7 +478,7 @@ osf_cdfs_mount(char *dirname, struct cdfs_args __user *args, int flags)
        retval = PTR_ERR(devname);
        if (IS_ERR(devname))
                goto out;
-       retval = do_mount(devname, dirname, "iso9660", flags, NULL);
+       retval = do_mount(devname->name, dirname, "iso9660", flags, NULL);
        putname(devname);
  out:
        return retval;
@@ -499,7 +499,7 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
                int, flag, void __user *, data)
 {
        int retval;
-       char *name;
+       struct filename *name;
 
        name = getname(path);
        retval = PTR_ERR(name);
@@ -507,13 +507,13 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
                goto out;
        switch (typenr) {
        case 1:
-               retval = osf_ufs_mount(name, data, flag);
+               retval = osf_ufs_mount(name->name, data, flag);
                break;
        case 6:
-               retval = osf_cdfs_mount(name, data, flag);
+               retval = osf_cdfs_mount(name->name, data, flag);
                break;
        case 9:
-               retval = osf_procfs_mount(name, data, flag);
+               retval = osf_procfs_mount(name->name, data, flag);
                break;
        default:
                retval = -EINVAL;
index 905fcfb0ddd0b284b42237e82da9041e3050cee3..b120df37de3552e5a68479294ef9e6b037ea97fb 100644 (file)
@@ -50,13 +50,13 @@ asmlinkage long sys_execve(const char __user *filenamei,
                           struct pt_regs *regs)
 {
        long error;
-       char * filename;
+       struct filename *filename;
 
        filename = getname(filenamei);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
 out:
        return error;
index 93f10e27dc796764d50d6c4d18b7310cd36cbeb5..e521087cb0c424df4f628bbef6cb6e184098e487 100644 (file)
@@ -56,14 +56,14 @@ asmlinkage int compat_sys_execve(const char __user *filenamei,
                                 struct pt_regs *regs)
 {
        int error;
-       char * filename;
+       struct filename *filename;
 
        filename = getname(filenamei);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = compat_do_execve(filename, compat_ptr(argv), compat_ptr(envp),
-                                regs);
+       error = compat_do_execve(filename->name, compat_ptr(argv),
+                                       compat_ptr(envp), regs);
        putname(filename);
 out:
        return error;
index 92c5af98a6f76be5f762b2e8c05936ddde5dfdc4..1bb0a8abd79b5078267ad4e6c9c84832033d0e92 100644 (file)
@@ -388,14 +388,14 @@ asmlinkage int sys_execve(const char __user *ufilename,
                          struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(ufilename);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename, uargv, uenvp, regs);
+       error = do_execve(filename->name, uargv, uenvp, regs);
        putname(filename);
 
 out:
index 62bcea7dcc6dff30bdaa5a4793ab336aef5ed688..bb1cc721fcf7e18ee26b5bf7a7bc0b2912815ad6 100644 (file)
@@ -213,14 +213,14 @@ asmlinkage int sys_execve(const char __user *name,
                          const char __user *const __user *envp)
 {
        int error;
-       char *filename;
+       struct filename *filename;
        struct pt_regs *regs = (struct pt_regs *)((&name) + 6);
 
        filename = getname(name);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                return error;
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
        return error;
 }
index 45e924a636a0c6772f0ae31cc27599d31ba437c7..0291325c4e8ef541c234c86afe0dab6ebd91b49e 100644 (file)
@@ -230,14 +230,14 @@ SYSCALL_DEFINE4(c6x_execve, const char __user *, name,
                struct pt_regs *, regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(name);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
 out:
        return error;
index bee8df43c201848e6c20439b88811efae05dfdd8..15ac7150371f719965479c9447a4bfd70b600512 100644 (file)
@@ -212,14 +212,14 @@ asmlinkage int sys_execve(const char *fname,
                          struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(fname);
        error = PTR_ERR(filename);
 
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
  out:
        return error;
index 0570e8ce603d1575943e24271cbb1f597d2dfe73..4e9992246359ee7a21e9052f56f60e589b8c72a8 100644 (file)
@@ -224,7 +224,7 @@ sys_execve(const char *fname,
           struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(fname);
        error = PTR_ERR(filename);
@@ -232,7 +232,7 @@ sys_execve(const char *fname,
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
  out:
        return error;
index 2eb7fa5bf9d8d48386ea7583dd1731dd92eff7a8..b496f5bd409641673c3dd012eadd9e7102be82fa 100644 (file)
@@ -226,13 +226,13 @@ asmlinkage int sys_execve(const char __user *name,
                          const char __user *const __user *envp)
 {
        int error;
-       char * filename;
+       struct filename *filename;
 
        filename = getname(name);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                return error;
-       error = do_execve(filename, argv, envp, __frame);
+       error = do_execve(filename->name, argv, envp, __frame);
        putname(filename);
        return error;
 }
index f153ed1a4c080bf73fb4be51389fec566910825d..e8dc1393a13a9c646f382b02d6111e085442012b 100644 (file)
@@ -217,14 +217,14 @@ asmlinkage int sys_execve(const char *name,
                          int dummy, ...)
 {
        int error;
-       char * filename;
+       struct filename *filename;
        struct pt_regs *regs = (struct pt_regs *) ((unsigned char *)&dummy-4);
 
        filename = getname(name);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                return error;
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
        return error;
 }
index 553cd60ee659d8bcc13fff4dbde40cd646a2c86c..25a9bfe3445d941f3386e05dd8ae5c0c2ece0f95 100644 (file)
@@ -40,7 +40,7 @@ asmlinkage int sys_execve(char __user *ufilename,
                          const char __user *const __user *envp)
 {
        struct pt_regs *pregs = current_thread_info()->regs;
-       char *filename;
+       struct filename *filename;
        int retval;
 
        filename = getname(ufilename);
@@ -48,7 +48,7 @@ asmlinkage int sys_execve(char __user *ufilename,
        if (IS_ERR(filename))
                return retval;
 
-       retval = do_execve(filename, argv, envp, pregs);
+       retval = do_execve(filename->name, argv, envp, pregs);
        putname(filename);
 
        return retval;
index ee31fe9b310e3d93de0e46ab29486e920b51763a..35e106f2ed13e81a8509d9db0d0285cba10a0e8f 100644 (file)
@@ -614,14 +614,14 @@ sys_execve (const char __user *filename,
            const char __user *const __user *envp,
            struct pt_regs *regs)
 {
-       char *fname;
+       struct filename *fname;
        int error;
 
        fname = getname(filename);
        error = PTR_ERR(fname);
        if (IS_ERR(fname))
                goto out;
-       error = do_execve(fname, argv, envp, regs);
+       error = do_execve(fname->name, argv, envp, regs);
        putname(fname);
 out:
        return error;
index 384e63f3a4c4e96ea2ea3cf54c76058c54edf88b..e7366276ef30067ad22f9fd4b9db3252d69f8b66 100644 (file)
@@ -296,14 +296,14 @@ asmlinkage int sys_execve(const char __user *ufilename,
                          unsigned long r6, struct pt_regs regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(ufilename);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename, uargv, uenvp, &regs);
+       error = do_execve(filename->name, uargv, uenvp, &regs);
        putname(filename);
 out:
        return error;
index ac2892e49c7c9107734044925caad596e56988bc..b5408d3035aa1384ddbc9c200eaaac912e813b67 100644 (file)
@@ -345,14 +345,14 @@ asmlinkage int sys_execve(const char __user *name,
                          const char __user *const __user *envp)
 {
        int error;
-       char * filename;
+       struct filename *filename;
        struct pt_regs *regs = (struct pt_regs *) &name;
 
        filename = getname(name);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                return error;
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
        return error;
 }
index e5b154f24f85e059229544cde92714fa7e8caa54..404c0f24bd41a7acaf5496e86120b15f9e715cd8 100644 (file)
@@ -54,13 +54,13 @@ asmlinkage long microblaze_execve(const char __user *filenamei,
                                  struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(filenamei);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
 out:
        return error;
index 922a554cd10802336aa5c23ce030dcbf8432c017..3a21acedf88231403703c3ca842916f325f88a6f 100644 (file)
@@ -83,13 +83,13 @@ out:
 asmlinkage int sys32_execve(nabi_no_regargs struct pt_regs regs)
 {
        int error;
-       char * filename;
+       struct filename *filename;
 
        filename = getname(compat_ptr(regs.regs[4]));
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = compat_do_execve(filename, compat_ptr(regs.regs[5]),
+       error = compat_do_execve(filename->name, compat_ptr(regs.regs[5]),
                                 compat_ptr(regs.regs[6]), &regs);
        putname(filename);
 
index b08220c82113ccd4a30a2dceac6832e2c199fabc..2bd561bc05ae2b4e7b814ac866d21faaddd046a2 100644 (file)
@@ -133,13 +133,13 @@ _sys_clone(nabi_no_regargs struct pt_regs regs)
 asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs)
 {
        int error;
-       char * filename;
+       struct filename *filename;
 
        filename = getname((const char __user *) (long)regs.regs[4]);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename,
+       error = do_execve(filename->name,
                          (const char __user *const __user *) (long)regs.regs[5],
                          (const char __user *const __user *) (long)regs.regs[6],
                          &regs);
index e9cceba193b6510f50acd8419a4a2498f82ff64f..606ae928b62ab6b4bf3dbb529baee92820d8ac12 100644 (file)
@@ -306,14 +306,14 @@ asmlinkage long sys_execve(const char __user *name,
                           const char __user *const __user *argv,
                           const char __user *const __user *envp)
 {
-       char *filename;
+       struct filename *filename;
        int error;
 
        filename = getname(name);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                return error;
-       error = do_execve(filename, argv, envp, current_frame());
+       error = do_execve(filename->name, argv, envp, current_frame());
        putname(filename);
        return error;
 }
index 55210f37d1a3e2a74ed1a30cc8cad3e6c600231f..c35f3ab1a8d34749d3f32648e82d826f27f350e1 100644 (file)
@@ -271,7 +271,7 @@ asmlinkage long _sys_execve(const char __user *name,
                            struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(name);
        error = PTR_ERR(filename);
@@ -279,7 +279,7 @@ asmlinkage long _sys_execve(const char __user *name,
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
 
 out:
index 6785de7bd2a0298c58f025bda474b037e3ea07f9..a0760b87fd4ec8c5c8531de43833a12fdd97bad1 100644 (file)
 int hpux_execve(struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname((const char __user *) regs->gr[26]);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename,
+       error = do_execve(filename->name,
                          (const char __user *const __user *) regs->gr[25],
                          (const char __user *const __user *) regs->gr[24],
                          regs);
index 8c6b6b6561f0de7025ea5a24b6fed7cb2e6dc677..cbc37216bf90f2fa5c64b5b1956272b9db237b8f 100644 (file)
@@ -342,13 +342,13 @@ unsigned long thread_saved_pc(struct task_struct *t)
 asmlinkage int sys_execve(struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname((const char __user *) regs->gr[26]);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename,
+       error = do_execve(filename->name,
                          (const char __user *const __user *) regs->gr[25],
                          (const char __user *const __user *) regs->gr[24],
                          regs);
index dc9a624623233e0e9f084e3659e65e37bf28df47..bf5b93a885d3cc6eb1b6ccd2ded74223b6cd2d32 100644 (file)
 asmlinkage int sys32_execve(struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26]));
        filename = getname((const char __user *) regs->gr[26]);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = compat_do_execve(filename, compat_ptr(regs->gr[25]),
+       error = compat_do_execve(filename->name, compat_ptr(regs->gr[25]),
                                 compat_ptr(regs->gr[24]), regs);
        putname(filename);
 out:
index d5ad666efd8b9a5fde3b93541fb774ae8459881f..49eba6c191d5df3a281613cdd9b680518c313d4f 100644 (file)
@@ -1060,7 +1060,7 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
               struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname((const char __user *) a0);
        error = PTR_ERR(filename);
@@ -1069,7 +1069,7 @@ int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        flush_fp_to_thread(current);
        flush_altivec_to_thread(current);
        flush_spe_to_thread(current);
-       error = do_execve(filename,
+       error = do_execve(filename->name,
                          (const char __user *const __user *) a1,
                          (const char __user *const __user *) a2, regs);
        putname(filename);
index abd1112da54f40b1b24a08a6a0732373ad95ef0e..a3de472b7246b9625e8c2762b8c866834269bc8c 100644 (file)
@@ -161,7 +161,7 @@ long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
                  struct pt_regs *regs)
 {
        int error;
-       char * filename;
+       struct filename *filename;
        
        filename = getname((char __user *) a0);
        error = PTR_ERR(filename);
@@ -170,7 +170,8 @@ long compat_sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
        flush_fp_to_thread(current);
        flush_altivec_to_thread(current);
 
-       error = compat_do_execve(filename, compat_ptr(a1), compat_ptr(a2), regs);
+       error = compat_do_execve(filename->name, compat_ptr(a1),
+                               compat_ptr(a2), regs);
 
        putname(filename);
 
index 21e8679740667c8d1a2e314252f7f35cad143159..d45cf00a33511aee8c6616fc419569714bc6ebf8 100644 (file)
@@ -92,14 +92,14 @@ asmlinkage long
 score_execve(struct pt_regs *regs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname((char __user*)regs->regs[4]);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                return error;
 
-       error = do_execve(filename,
+       error = do_execve(filename->name,
                          (const char __user *const __user *)regs->regs[5],
                          (const char __user *const __user *)regs->regs[6],
                          regs);
index 59521e8a164dae01da367f2f60aef2e0a737551e..ba7345f37bc9d0c6a1e4cc62760ca5e34fe65342 100644 (file)
@@ -298,14 +298,14 @@ asmlinkage int sys_execve(const char __user *ufilename,
 {
        struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(ufilename);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename, uargv, uenvp, regs);
+       error = do_execve(filename->name, uargv, uenvp, regs);
        putname(filename);
 out:
        return error;
index 602545b12a8678857c8752407be691a1bd511baa..98a709f0c3c45c1f6ece40d34b79a69cd4de4e2c 100644 (file)
@@ -491,14 +491,14 @@ asmlinkage int sys_execve(const char *ufilename, char **uargv,
                          struct pt_regs *pregs)
 {
        int error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname((char __user *)ufilename);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
 
-       error = do_execve(filename,
+       error = do_execve(filename->name,
                          (const char __user *const __user *)uargv,
                          (const char __user *const __user *)uenvp,
                          pregs);
index 14006d8aca2849899d2ce1821f70f42d8ac50633..487bffb36f5eb4a2792808e317e845cdaa8553d1 100644 (file)
@@ -482,7 +482,7 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
 asmlinkage int sparc_execve(struct pt_regs *regs)
 {
        int error, base = 0;
-       char *filename;
+       struct filename *filename;
 
        /* Check for indirect call. */
        if(regs->u_regs[UREG_G1] == 0)
@@ -492,7 +492,7 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
        error = PTR_ERR(filename);
        if(IS_ERR(filename))
                goto out;
-       error = do_execve(filename,
+       error = do_execve(filename->name,
                          (const char __user *const  __user *)
                          regs->u_regs[base + UREG_I1],
                          (const char __user *const  __user *)
index aff0c72fac0999b70a4407179aad99eebfe84c29..fcaa59421126edf297d4e14dbbf2b90239d5d406 100644 (file)
@@ -722,7 +722,7 @@ EXPORT_SYMBOL(dump_fpu);
 asmlinkage int sparc_execve(struct pt_regs *regs)
 {
        int error, base = 0;
-       char *filename;
+       struct filename *filename;
 
        /* User register window flush is done by entry.S */
 
@@ -734,7 +734,7 @@ asmlinkage int sparc_execve(struct pt_regs *regs)
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename,
+       error = do_execve(filename->name,
                          (const char __user *const __user *)
                          regs->u_regs[base + UREG_I1],
                          (const char __user *const __user *)
index d862499eb01ccfe298b7101190dfc29f3ebcf44d..c3239811a1b5775903c77e64057e78d01130fdd0 100644 (file)
@@ -403,7 +403,7 @@ asmlinkage long compat_sys_rt_sigaction(int sig,
 asmlinkage long sparc32_execve(struct pt_regs *regs)
 {
        int error, base = 0;
-       char *filename;
+       struct filename *filename;
 
        /* User register window flush is done by entry.S */
 
@@ -416,7 +416,7 @@ asmlinkage long sparc32_execve(struct pt_regs *regs)
        if (IS_ERR(filename))
                goto out;
 
-       error = compat_do_execve(filename,
+       error = compat_do_execve(filename->name,
                                 compat_ptr(regs->u_regs[base + UREG_I1]),
                                 compat_ptr(regs->u_regs[base + UREG_I2]), regs);
 
index 6be7991505019a30ce3ff6268c275a931a088644..622560030a5839c1e93d0fb5a1753809f2e0db5e 100644 (file)
@@ -594,13 +594,13 @@ SYSCALL_DEFINE4(execve, const char __user *, path,
                struct pt_regs *, regs)
 {
        long error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(path);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
        if (error == 0)
                single_step_execve();
@@ -615,13 +615,13 @@ long compat_sys_execve(const char __user *path,
                       struct pt_regs *regs)
 {
        long error;
-       char *filename;
+       struct filename *filename;
 
        filename = getname(path);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = compat_do_execve(filename, argv, envp, regs);
+       error = compat_do_execve(filename->name, argv, envp, regs);
        putname(filename);
        if (error == 0)
                single_step_execve();
index 5fd9af773e15f2752002555b1af787c6a610d334..fabdee96110b46821c911fa9de0be5ba30460b57 100644 (file)
@@ -51,13 +51,13 @@ asmlinkage long __sys_execve(const char __user *filename,
                          struct pt_regs *regs)
 {
        int error;
-       char *fn;
+       struct filename *fn;
 
        fn = getname(filename);
        error = PTR_ERR(fn);
        if (IS_ERR(fn))
                goto out;
-       error = do_execve(fn, argv, envp, regs);
+       error = do_execve(fn->name, argv, envp, regs);
        putname(fn);
 out:
        return error;
index bc44311aa18cc7207dd0e4bde95585cc6b81c3c0..bc020825cce55197e6aaf7dfc127203a143e3553 100644 (file)
@@ -328,13 +328,13 @@ long xtensa_execve(const char __user *name,
                    struct pt_regs *regs)
 {
        long error;
-       char * filename;
+       struct filename *filename;
 
        filename = getname(name);
        error = PTR_ERR(filename);
        if (IS_ERR(filename))
                goto out;
-       error = do_execve(filename, argv, envp, regs);
+       error = do_execve(filename->name, argv, envp, regs);
        putname(filename);
 out:
        return error;
index b7a24d0ca30df9d82beee3866b0dc30861946c0f..015e1e1f87c649ff48df282c6c04780569c3192d 100644 (file)
@@ -776,16 +776,16 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
        char *kernel_type;
        unsigned long data_page;
        char *kernel_dev;
-       char *dir_page;
+       struct filename *dir;
        int retval;
 
        retval = copy_mount_string(type, &kernel_type);
        if (retval < 0)
                goto out;
 
-       dir_page = getname(dir_name);
-       retval = PTR_ERR(dir_page);
-       if (IS_ERR(dir_page))
+       dir = getname(dir_name);
+       retval = PTR_ERR(dir);
+       if (IS_ERR(dir))
                goto out1;
 
        retval = copy_mount_string(dev_name, &kernel_dev);
@@ -807,7 +807,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
                }
        }
 
-       retval = do_mount(kernel_dev, dir_page, kernel_type,
+       retval = do_mount(kernel_dev, dir->name, kernel_type,
                        flags, (void*)data_page);
 
  out4:
@@ -815,7 +815,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name,
  out3:
        kfree(kernel_dev);
  out2:
-       putname(dir_page);
+       putname(dir);
  out1:
        kfree(kernel_type);
  out:
index ca434534ae9abd43ee320e308b22199fb2d53849..4e591e20e1085e4f7bfd7f987231e25dc1088820 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -105,7 +105,7 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
 SYSCALL_DEFINE1(uselib, const char __user *, library)
 {
        struct file *file;
-       char *tmp = getname(library);
+       struct filename *tmp = getname(library);
        int error = PTR_ERR(tmp);
        static const struct open_flags uselib_flags = {
                .open_flag = O_LARGEFILE | O_RDONLY | __FMODE_EXEC,
@@ -116,7 +116,7 @@ SYSCALL_DEFINE1(uselib, const char __user *, library)
        if (IS_ERR(tmp))
                goto out;
 
-       file = do_filp_open(AT_FDCWD, tmp, &uselib_flags, LOOKUP_FOLLOW);
+       file = do_filp_open(AT_FDCWD, tmp->name, &uselib_flags, LOOKUP_FOLLOW);
        putname(tmp);
        error = PTR_ERR(file);
        if (IS_ERR(file))
@@ -1664,10 +1664,10 @@ SYSCALL_DEFINE3(execve,
                const char __user *const __user *, argv,
                const char __user *const __user *, envp)
 {
-       const char *path = getname(filename);
+       struct filename *path = getname(filename);
        int error = PTR_ERR(path);
        if (!IS_ERR(path)) {
-               error = do_execve(path, argv, envp, current_pt_regs());
+               error = do_execve(path->name, argv, envp, current_pt_regs());
                putname(path);
        }
        return error;
@@ -1677,10 +1677,11 @@ asmlinkage long compat_sys_execve(const char __user * filename,
        const compat_uptr_t __user * argv,
        const compat_uptr_t __user * envp)
 {
-       const char *path = getname(filename);
+       struct filename *path = getname(filename);
        int error = PTR_ERR(path);
        if (!IS_ERR(path)) {
-               error = compat_do_execve(path, argv, envp, current_pt_regs());
+               error = compat_do_execve(path->name, argv, envp,
+                                                       current_pt_regs());
                putname(path);
        }
        return error;
index 96f24286667adf1aefe4a4c2b4fc2fc67eb19880..da165f6adcbfa67a12f9f19363692ab6c5d00d19 100644 (file)
@@ -124,7 +124,7 @@ EXPORT_SYMBOL(unregister_filesystem);
 static int fs_index(const char __user * __name)
 {
        struct file_system_type * tmp;
-       char * name;
+       struct filename *name;
        int err, index;
 
        name = getname(__name);
@@ -135,7 +135,7 @@ static int fs_index(const char __user * __name)
        err = -EINVAL;
        read_lock(&file_systems_lock);
        for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
-               if (strcmp(tmp->name,name) == 0) {
+               if (strcmp(tmp->name, name->name) == 0) {
                        err = index;
                        break;
                }
index 9cc0fce7fc91e998f1945df5475e70a14cd9a0a2..ec638d27642f2016cd354dd0972022f46ee92728 100644 (file)
  * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
  * PATH_MAX includes the nul terminator --RR.
  */
-static char *getname_flags(const char __user *filename, int flags, int *empty)
+void final_putname(struct filename *name)
 {
-       char *result = __getname(), *err;
+       __putname(name->name);
+       kfree(name);
+}
+
+static struct filename *
+getname_flags(const char __user *filename, int flags, int *empty)
+{
+       struct filename *result, *err;
+       char *kname;
        int len;
 
+       /* FIXME: create dedicated slabcache? */
+       result = kzalloc(sizeof(*result), GFP_KERNEL);
        if (unlikely(!result))
                return ERR_PTR(-ENOMEM);
 
-       len = strncpy_from_user(result, filename, PATH_MAX);
-       err = ERR_PTR(len);
-       if (unlikely(len < 0))
+       kname = __getname();
+       if (unlikely(!kname)) {
+               err = ERR_PTR(-ENOMEM);
+               goto error_free_name;
+       }
+
+       result->name = kname;
+       result->uptr = filename;
+       len = strncpy_from_user(kname, filename, PATH_MAX);
+       if (unlikely(len < 0)) {
+               err = ERR_PTR(len);
                goto error;
+       }
 
        /* The empty path is special. */
        if (unlikely(!len)) {
@@ -146,22 +165,25 @@ static char *getname_flags(const char __user *filename, int flags, int *empty)
        }
 
 error:
-       __putname(result);
+       __putname(kname);
+error_free_name:
+       kfree(result);
        return err;
 }
 
-char *getname(const char __user * filename)
+struct filename *
+getname(const char __user * filename)
 {
        return getname_flags(filename, 0, NULL);
 }
+EXPORT_SYMBOL(getname);
 
 #ifdef CONFIG_AUDITSYSCALL
-void putname(const char *name)
+void putname(struct filename *name)
 {
        if (unlikely(!audit_dummy_context()))
-               audit_putname(name);
-       else
-               __putname(name);
+               return audit_putname(name);
+       final_putname(name);
 }
 #endif
 
@@ -2093,13 +2115,13 @@ int user_path_at_empty(int dfd, const char __user *name, unsigned flags,
                 struct path *path, int *empty)
 {
        struct nameidata nd;
-       char *tmp = getname_flags(name, flags, empty);
+       struct filename *tmp = getname_flags(name, flags, empty);
        int err = PTR_ERR(tmp);
        if (!IS_ERR(tmp)) {
 
                BUG_ON(flags & LOOKUP_PARENT);
 
-               err = do_path_lookup(dfd, tmp, flags, &nd);
+               err = do_path_lookup(dfd, tmp->name, flags, &nd);
                putname(tmp);
                if (!err)
                        *path = nd.path;
@@ -2113,22 +2135,22 @@ int user_path_at(int dfd, const char __user *name, unsigned flags,
        return user_path_at_empty(dfd, name, flags, path, NULL);
 }
 
-static int user_path_parent(int dfd, const char __user *path,
-                       struct nameidata *nd, char **name)
+static struct filename *
+user_path_parent(int dfd, const char __user *path, struct nameidata *nd)
 {
-       char *s = getname(path);
+       struct filename *s = getname(path);
        int error;
 
        if (IS_ERR(s))
-               return PTR_ERR(s);
+               return s;
 
-       error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd);
-       if (error)
+       error = do_path_lookup(dfd, s->name, LOOKUP_PARENT, nd);
+       if (error) {
                putname(s);
-       else
-               *name = s;
+               return ERR_PTR(error);
+       }
 
-       return error;
+       return s;
 }
 
 /*
@@ -3039,11 +3061,11 @@ EXPORT_SYMBOL(done_path_create);
 
 struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir)
 {
-       char *tmp = getname(pathname);
+       struct filename *tmp = getname(pathname);
        struct dentry *res;
        if (IS_ERR(tmp))
                return ERR_CAST(tmp);
-       res = kern_path_create(dfd, tmp, path, is_dir);
+       res = kern_path_create(dfd, tmp->name, path, is_dir);
        putname(tmp);
        return res;
 }
@@ -3248,13 +3270,13 @@ out:
 static long do_rmdir(int dfd, const char __user *pathname)
 {
        int error = 0;
-       char * name;
+       struct filename *name;
        struct dentry *dentry;
        struct nameidata nd;
 
-       error = user_path_parent(dfd, pathname, &nd, &name);
-       if (error)
-               return error;
+       name = user_path_parent(dfd, pathname, &nd);
+       if (IS_ERR(name))
+               return PTR_ERR(name);
 
        switch(nd.last_type) {
        case LAST_DOTDOT:
@@ -3343,14 +3365,14 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
 static long do_unlinkat(int dfd, const char __user *pathname)
 {
        int error;
-       char *name;
+       struct filename *name;
        struct dentry *dentry;
        struct nameidata nd;
        struct inode *inode = NULL;
 
-       error = user_path_parent(dfd, pathname, &nd, &name);
-       if (error)
-               return error;
+       name = user_path_parent(dfd, pathname, &nd);
+       if (IS_ERR(name))
+               return PTR_ERR(name);
 
        error = -EISDIR;
        if (nd.last_type != LAST_NORM)
@@ -3434,7 +3456,7 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
                int, newdfd, const char __user *, newname)
 {
        int error;
-       char *from;
+       struct filename *from;
        struct dentry *dentry;
        struct path path;
 
@@ -3447,9 +3469,9 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
        if (IS_ERR(dentry))
                goto out_putname;
 
-       error = security_path_symlink(&path, dentry, from);
+       error = security_path_symlink(&path, dentry, from->name);
        if (!error)
-               error = vfs_symlink(path.dentry->d_inode, dentry, from);
+               error = vfs_symlink(path.dentry->d_inode, dentry, from->name);
        done_path_create(&path, dentry);
 out_putname:
        putname(from);
@@ -3729,17 +3751,21 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
        struct dentry *old_dentry, *new_dentry;
        struct dentry *trap;
        struct nameidata oldnd, newnd;
-       char *from;
-       char *to;
+       struct filename *from;
+       struct filename *to;
        int error;
 
-       error = user_path_parent(olddfd, oldname, &oldnd, &from);
-       if (error)
+       from = user_path_parent(olddfd, oldname, &oldnd);
+       if (IS_ERR(from)) {
+               error = PTR_ERR(from);
                goto exit;
+       }
 
-       error = user_path_parent(newdfd, newname, &newnd, &to);
-       if (error)
+       to = user_path_parent(newdfd, newname, &newnd);
+       if (IS_ERR(to)) {
+               error = PTR_ERR(to);
                goto exit1;
+       }
 
        error = -EXDEV;
        if (oldnd.path.mnt != newnd.path.mnt)
index fc33207e28adb7af647b64ebc82bcf1e6f7cee37..24960626bb6bfc7b9eff78631876d4eb7ca7a40e 100644 (file)
@@ -2408,7 +2408,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
 {
        int ret;
        char *kernel_type;
-       char *kernel_dir;
+       struct filename *kernel_dir;
        char *kernel_dev;
        unsigned long data_page;
 
@@ -2430,7 +2430,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
        if (ret < 0)
                goto out_data;
 
-       ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags,
+       ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags,
                (void *) data_page);
 
        free_page(data_page);
index a015437e1535d3aae42edf8fbf94adafeed903be..81dd92ac10ffa97513630a955108c3bb8a15aee0 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -895,13 +895,13 @@ long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode)
 {
        struct open_flags op;
        int lookup = build_open_flags(flags, mode, &op);
-       char *tmp = getname(filename);
+       struct filename *tmp = getname(filename);
        int fd = PTR_ERR(tmp);
 
        if (!IS_ERR(tmp)) {
                fd = get_unused_fd_flags(flags);
                if (fd >= 0) {
-                       struct file *f = do_filp_open(dfd, tmp, &op, lookup);
+                       struct file *f = do_filp_open(dfd, tmp->name, &op, lookup);
                        if (IS_ERR(f)) {
                                put_unused_fd(fd);
                                fd = PTR_ERR(f);
index ff0135d6bc51a5d8ddbe1eb16f845a2b9d37c009..af1661f7a54f1700faa9a129ec76dad81e7e0961 100644 (file)
@@ -331,11 +331,11 @@ static struct super_block *quotactl_block(const char __user *special, int cmd)
 #ifdef CONFIG_BLOCK
        struct block_device *bdev;
        struct super_block *sb;
-       char *tmp = getname(special);
+       struct filename *tmp = getname(special);
 
        if (IS_ERR(tmp))
                return ERR_CAST(tmp);
-       bdev = lookup_bdev(tmp);
+       bdev = lookup_bdev(tmp->name);
        putname(tmp);
        if (IS_ERR(bdev))
                return ERR_CAST(bdev);
index 3df643d1ac5bb31bca1168b7a06856ec5fe03646..7ab2898a8e52d4d4315ffad4007e13d7f2edd837 100644 (file)
@@ -461,6 +461,8 @@ extern int audit_classify_arch(int arch);
 #define        AUDIT_TYPE_CHILD_CREATE 4       /* a child being created */
 
 #ifdef CONFIG_AUDITSYSCALL
+struct filename;
+
 /* These are defined in auditsc.c */
                                /* Public API */
 extern int  audit_alloc(struct task_struct *task);
@@ -469,8 +471,8 @@ extern void __audit_syscall_entry(int arch,
                                  int major, unsigned long a0, unsigned long a1,
                                  unsigned long a2, unsigned long a3);
 extern void __audit_syscall_exit(int ret_success, long ret_value);
-extern void __audit_getname(const char *name);
-extern void audit_putname(const char *name);
+extern void __audit_getname(struct filename *name);
+extern void audit_putname(struct filename *name);
 extern void __audit_inode(const char *name, const struct dentry *dentry,
                                unsigned int parent);
 extern void __audit_inode_child(const struct inode *parent,
@@ -505,7 +507,7 @@ static inline void audit_syscall_exit(void *pt_regs)
                __audit_syscall_exit(success, return_code);
        }
 }
-static inline void audit_getname(const char *name)
+static inline void audit_getname(struct filename *name)
 {
        if (unlikely(!audit_dummy_context()))
                __audit_getname(name);
@@ -663,9 +665,9 @@ static inline int audit_dummy_context(void)
 {
        return 1;
 }
-static inline void audit_getname(const char *name)
+static inline void audit_getname(struct filename *name)
 { }
-static inline void audit_putname(const char *name)
+static inline void audit_putname(struct filename *name)
 { }
 static inline void __audit_inode(const char *name, const struct dentry *dentry,
                                        unsigned int parent)
index 6bac43113dac61f5f9ec9f126217d8621ce2753d..3611caa818e2269487551c0da8c24d2aee23febb 100644 (file)
@@ -2192,6 +2192,10 @@ static inline int break_lease(struct inode *inode, unsigned int mode)
 #endif /* CONFIG_FILE_LOCKING */
 
 /* fs/open.c */
+struct filename {
+       const char *name;               /* pointer to actual string */
+       const __user char *uptr;        /* original userland pointer */
+};
 
 extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs,
                       struct file *filp);
@@ -2204,7 +2208,9 @@ extern struct file *file_open_root(struct dentry *, struct vfsmount *,
                                   const char *, int);
 extern struct file * dentry_open(const struct path *, int, const struct cred *);
 extern int filp_close(struct file *, fl_owner_t id);
-extern char * getname(const char __user *);
+
+extern struct filename *getname(const char __user *);
+
 enum {
        FILE_CREATED = 1,
        FILE_OPENED = 2
@@ -2224,12 +2230,14 @@ extern void __init vfs_caches_init(unsigned long);
 
 extern struct kmem_cache *names_cachep;
 
+extern void final_putname(struct filename *name);
+
 #define __getname()            kmem_cache_alloc(names_cachep, GFP_KERNEL)
 #define __putname(name)                kmem_cache_free(names_cachep, (void *)(name))
 #ifndef CONFIG_AUDITSYSCALL
-#define putname(name)   __putname(name)
+#define putname(name)          final_putname(name)
 #else
-extern void putname(const char *name);
+extern void putname(struct filename *name);
 #endif
 
 #ifdef CONFIG_BLOCK
index 9553ed006042016dd79543aeb234ee9ff9622678..6c5d9dcc9030271276ed752efa80ec82c8d2da6d 100644 (file)
@@ -772,7 +772,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
 {
        struct path path;
        struct file *filp;
-       char *name;
+       struct filename *name;
        struct mq_attr attr;
        int fd, error;
        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,
        ro = mnt_want_write(mnt);       /* we'll drop it in any case */
        error = 0;
        mutex_lock(&root->d_inode->i_mutex);
-       path.dentry = lookup_one_len(name, root, strlen(name));
+       path.dentry = lookup_one_len(name->name, root, strlen(name->name));
        if (IS_ERR(path.dentry)) {
                error = PTR_ERR(path.dentry);
                goto out_putfd;
@@ -804,7 +804,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
 
        if (oflag & O_CREAT) {
                if (path.dentry->d_inode) {     /* entry already exists */
-                       audit_inode(name, path.dentry, 0);
+                       audit_inode(name->name, path.dentry, 0);
                        if (oflag & O_EXCL) {
                                error = -EEXIST;
                                goto out;
@@ -824,7 +824,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
                        error = -ENOENT;
                        goto out;
                }
-               audit_inode(name, path.dentry, 0);
+               audit_inode(name->name, path.dentry, 0);
                filp = do_open(&path, oflag);
        }
 
@@ -849,7 +849,7 @@ out_putname:
 SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
 {
        int err;
-       char *name;
+       struct filename *name;
        struct dentry *dentry;
        struct inode *inode = NULL;
        struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
@@ -863,7 +863,8 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
        if (err)
                goto out_name;
        mutex_lock_nested(&mnt->mnt_root->d_inode->i_mutex, I_MUTEX_PARENT);
-       dentry = lookup_one_len(name, mnt->mnt_root, strlen(name));
+       dentry = lookup_one_len(name->name, mnt->mnt_root,
+                               strlen(name->name));
        if (IS_ERR(dentry)) {
                err = PTR_ERR(dentry);
                goto out_unlock;
index 5be01017d30febe251e8fe5a6906414e7ba5568d..08354195eeccee94a5e7eea225fbe6a1e01ed3d9 100644 (file)
@@ -260,10 +260,10 @@ SYSCALL_DEFINE1(acct, const char __user *, name)
                return -EPERM;
 
        if (name) {
-               char *tmp = getname(name);
+               struct filename *tmp = getname(name);
                if (IS_ERR(tmp))
                        return (PTR_ERR(tmp));
-               error = acct_on(tmp);
+               error = acct_on(tmp->name);
                putname(tmp);
        } else {
                struct bsd_acct_struct *acct;
index d147585e9ef3a06ae3b22c3c832e5819b22e3cec..d4d82319eed58264410c0669bd7efc7a2fd31ff4 100644 (file)
@@ -103,28 +103,29 @@ struct audit_cap_data {
  * we don't let putname() free it (instead we free all of the saved
  * pointers at syscall exit time).
  *
- * Further, in fs/namei.c:path_lookup() we store the inode and device. */
+ * Further, in fs/namei.c:path_lookup() we store the inode and device.
+ */
 struct audit_names {
-       struct list_head list;          /* audit_context->names_list */
-       const char      *name;
-       unsigned long   ino;
-       dev_t           dev;
-       umode_t         mode;
-       kuid_t          uid;
-       kgid_t          gid;
-       dev_t           rdev;
-       u32             osid;
-       struct audit_cap_data fcap;
-       unsigned int    fcap_ver;
-       int             name_len;       /* number of name's characters to log */
-       unsigned char   type;           /* record type */
-       bool            name_put;       /* call __putname() for this name */
+       struct list_head        list;           /* audit_context->names_list */
+       struct filename *name;
+       unsigned long           ino;
+       dev_t                   dev;
+       umode_t                 mode;
+       kuid_t                  uid;
+       kgid_t                  gid;
+       dev_t                   rdev;
+       u32                     osid;
+       struct audit_cap_data    fcap;
+       unsigned int            fcap_ver;
+       int                     name_len;       /* number of name's characters to log */
+       unsigned char           type;           /* record type */
+       bool                    name_put;       /* call __putname() for this name */
        /*
         * This was an allocated audit_names and not from the array of
         * names allocated in the task audit context.  Thus this name
         * should be freed on syscall exit
         */
-       bool            should_free;
+       bool                    should_free;
 };
 
 struct audit_aux_data {
@@ -996,7 +997,7 @@ static inline void audit_free_names(struct audit_context *context)
                       context->ino_count);
                list_for_each_entry(n, &context->names_list, list) {
                        printk(KERN_ERR "names[%d] = %p = %s\n", i,
-                              n->name, n->name ?: "(null)");
+                              n->name, n->name->name ?: "(null)");
                }
                dump_stack();
                return;
@@ -1553,7 +1554,7 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
                case AUDIT_NAME_FULL:
                        /* log the full path */
                        audit_log_format(ab, " name=");
-                       audit_log_untrustedstring(ab, n->name);
+                       audit_log_untrustedstring(ab, n->name->name);
                        break;
                case 0:
                        /* 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,
                default:
                        /* log the name's directory component */
                        audit_log_format(ab, " name=");
-                       audit_log_n_untrustedstring(ab, n->name,
+                       audit_log_n_untrustedstring(ab, n->name->name,
                                                    n->name_len);
                }
        } else
@@ -2026,7 +2027,7 @@ static struct audit_names *audit_alloc_name(struct audit_context *context,
  * Add a name to the list of audit names for this context.
  * Called from fs/namei.c:getname().
  */
-void __audit_getname(const char *name)
+void __audit_getname(struct filename *name)
 {
        struct audit_context *context = current->audit_context;
        struct audit_names *n;
@@ -2040,6 +2041,11 @@ void __audit_getname(const char *name)
                return;
        }
 
+#if AUDIT_DEBUG
+       /* The filename _must_ have a populated ->name */
+       BUG_ON(!name->name);
+#endif
+
        n = audit_alloc_name(context, AUDIT_TYPE_UNKNOWN);
        if (!n)
                return;
@@ -2059,7 +2065,7 @@ void __audit_getname(const char *name)
  * then we delay the putname until syscall exit.
  * Called from include/linux/fs.h:putname().
  */
-void audit_putname(const char *name)
+void audit_putname(struct filename *name)
 {
        struct audit_context *context = current->audit_context;
 
@@ -2074,7 +2080,7 @@ void audit_putname(const char *name)
 
                        list_for_each_entry(n, &context->names_list, list)
                                printk(KERN_ERR "name[%d] = %p = %s\n", i,
-                                      n->name, n->name ?: "(null)");
+                                      n->name, n->name->name ?: "(null)");
                        }
 #endif
                __putname(name);
@@ -2088,8 +2094,8 @@ void audit_putname(const char *name)
                               " put_count=%d\n",
                               __FILE__, __LINE__,
                               context->serial, context->major,
-                              context->in_syscall, name, context->name_count,
-                              context->put_count);
+                              context->in_syscall, name->name,
+                              context->name_count, context->put_count);
                        dump_stack();
                }
        }
@@ -2152,7 +2158,7 @@ void __audit_inode(const char *name, const struct dentry *dentry,
 
        list_for_each_entry_reverse(n, &context->names_list, list) {
                /* does the name pointer match? */
-               if (n->name != name)
+               if (!n->name || n->name->name != name)
                        continue;
 
                /* match the correct record type */
@@ -2175,7 +2181,7 @@ out_alloc:
                return;
 out:
        if (parent) {
-               n->name_len = n->name ? parent_len(n->name) : AUDIT_NAME_FULL;
+               n->name_len = n->name ? parent_len(n->name->name) : AUDIT_NAME_FULL;
                n->type = AUDIT_TYPE_PARENT;
        } else {
                n->name_len = AUDIT_NAME_FULL;
@@ -2220,7 +2226,7 @@ void __audit_inode_child(const struct inode *parent,
                        continue;
 
                if (n->ino == parent->i_ino &&
-                   !audit_compare_dname_path(dname, n->name, n->name_len)) {
+                   !audit_compare_dname_path(dname, n->name->name, n->name_len)) {
                        found_parent = n;
                        break;
                }
@@ -2236,8 +2242,8 @@ void __audit_inode_child(const struct inode *parent,
                if (found_parent && (n->name != found_parent->name))
                        continue;
 
-               if (!strcmp(dname, n->name) ||
-                   !audit_compare_dname_path(dname, n->name,
+               if (!strcmp(dname, n->name->name) ||
+                   !audit_compare_dname_path(dname, n->name->name,
                                                found_parent ?
                                                found_parent->name_len :
                                                AUDIT_NAME_FULL)) {
index 14e254c768fc5090e9c2276085b3c6f96c6255f6..90d2ed591de90a0b9bad355864a054f210601241 100644 (file)
@@ -1483,7 +1483,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
        struct file *swap_file, *victim;
        struct address_space *mapping;
        struct inode *inode;
-       char *pathname;
+       struct filename *pathname;
        int oom_score_adj;
        int i, type, prev;
        int err;
@@ -1498,8 +1498,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
        if (IS_ERR(pathname))
                goto out;
 
-       victim = filp_open(pathname, O_RDWR|O_LARGEFILE, 0);
-       putname(pathname);
+       victim = filp_open(pathname->name, O_RDWR|O_LARGEFILE, 0);
        err = PTR_ERR(victim);
        if (IS_ERR(victim))
                goto out;
@@ -1936,7 +1935,7 @@ static int setup_swap_map_and_extents(struct swap_info_struct *p,
 SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
 {
        struct swap_info_struct *p;
-       char *name;
+       struct filename *name;
        struct file *swap_file = NULL;
        struct address_space *mapping;
        int i;
@@ -1967,7 +1966,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
                name = NULL;
                goto bad_swap;
        }
-       swap_file = filp_open(name, O_RDWR|O_LARGEFILE, 0);
+       swap_file = filp_open(name->name, O_RDWR|O_LARGEFILE, 0);
        if (IS_ERR(swap_file)) {
                error = PTR_ERR(swap_file);
                swap_file = NULL;
@@ -2053,7 +2052,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
 
        printk(KERN_INFO "Adding %uk swap on %s.  "
                        "Priority:%d extents:%d across:%lluk %s%s%s\n",
-               p->pages<<(PAGE_SHIFT-10), name, p->prio,
+               p->pages<<(PAGE_SHIFT-10), name->name, p->prio,
                nr_extents, (unsigned long long)span<<(PAGE_SHIFT-10),
                (p->flags & SWP_SOLIDSTATE) ? "SS" : "",
                (p->flags & SWP_DISCARDABLE) ? "D" : "",