Commit 91a27b2a authored by Jeff Layton's avatar Jeff Layton Committed by Al Viro

vfs: define struct filename and have getname() return it

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: default avatarJeff Layton <jlayton@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 8e377d15
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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:
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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:
......
......@@ -34,14 +34,14 @@
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);
......
......@@ -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);
......
......@@ -60,14 +60,14 @@
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:
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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 *)
......
......@@ -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 *)
......
......@@ -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);
......
......@@ -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();
......
......@@ -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;
......
......@@ -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;
......
......@@ -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:
......
......@@ -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);