mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-11-17 10:01:01 +03:00
Update vn_set_pwd() to allow user|kernal address for filename
During module init spl_setup()->The vn_set_pwd("/") was failing with -EFAULT because user_path_dir() and __user_walk() both expect 'filename' to be a user space address and it's not in this case. To handle this the data segment size is increased to to ensure strncpy_from_user() does not fail with -EFAULT. Additionally, I've added a printk() warning to catch this and log it to the console if it ever reoccurs. I thought everything was working properly here because there consequences of this failing are subtle and usually non-critical.
This commit is contained in:
parent
ef6c136884
commit
82a358d9c0
@ -444,12 +444,16 @@ spl_fini(void)
|
||||
void
|
||||
spl_setup(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* At module load time the pwd is set to '/' on a Solaris system.
|
||||
* On a Linux system will be set to whatever directory the caller
|
||||
* was in when executing insmod/modprobe.
|
||||
*/
|
||||
vn_set_pwd("/");
|
||||
rc = vn_set_pwd("/");
|
||||
if (rc)
|
||||
printk("SPL: Warning unable to set pwd to '/': %d\n", rc);
|
||||
}
|
||||
EXPORT_SYMBOL(spl_setup);
|
||||
|
||||
|
@ -647,9 +647,22 @@ vn_set_pwd(const char *filename)
|
||||
{
|
||||
#ifdef HAVE_2ARGS_SET_FS_PWD
|
||||
struct path path;
|
||||
#else
|
||||
struct nameidata nd;
|
||||
#endif /* HAVE_2ARGS_SET_FS_PWD */
|
||||
mm_segment_t saved_fs;
|
||||
int rc;
|
||||
ENTRY;
|
||||
|
||||
/*
|
||||
* user_path_dir() and __user_walk() both expect 'filename' to be
|
||||
* a user space address so we must briefly increase the data segment
|
||||
* size to ensure strncpy_from_user() does not fail with -EFAULT.
|
||||
*/
|
||||
saved_fs = get_fs();
|
||||
set_fs(get_ds());
|
||||
|
||||
#ifdef HAVE_2ARGS_SET_FS_PWD
|
||||
rc = user_path_dir(filename, &path);
|
||||
if (rc)
|
||||
GOTO(out, rc);
|
||||
@ -663,10 +676,6 @@ vn_set_pwd(const char *filename)
|
||||
dput_and_out:
|
||||
path_put(&path);
|
||||
#else
|
||||
struct nameidata nd;
|
||||
int rc;
|
||||
ENTRY;
|
||||
|
||||
rc = __user_walk(filename,
|
||||
LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd);
|
||||
if (rc)
|
||||
@ -682,6 +691,8 @@ dput_and_out:
|
||||
vn_path_release(&nd);
|
||||
#endif /* HAVE_2ARGS_SET_FS_PWD */
|
||||
out:
|
||||
set_fs(saved_fs);
|
||||
|
||||
RETURN(-rc);
|
||||
} /* vn_set_pwd() */
|
||||
EXPORT_SYMBOL(vn_set_pwd);
|
||||
|
Loading…
Reference in New Issue
Block a user