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
|
void
|
||||||
spl_setup(void)
|
spl_setup(void)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At module load time the pwd is set to '/' on a Solaris system.
|
* 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
|
* On a Linux system will be set to whatever directory the caller
|
||||||
* was in when executing insmod/modprobe.
|
* 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);
|
EXPORT_SYMBOL(spl_setup);
|
||||||
|
|
||||||
|
@ -647,9 +647,22 @@ vn_set_pwd(const char *filename)
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_2ARGS_SET_FS_PWD
|
#ifdef HAVE_2ARGS_SET_FS_PWD
|
||||||
struct path path;
|
struct path path;
|
||||||
|
#else
|
||||||
|
struct nameidata nd;
|
||||||
|
#endif /* HAVE_2ARGS_SET_FS_PWD */
|
||||||
|
mm_segment_t saved_fs;
|
||||||
int rc;
|
int rc;
|
||||||
ENTRY;
|
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);
|
rc = user_path_dir(filename, &path);
|
||||||
if (rc)
|
if (rc)
|
||||||
GOTO(out, rc);
|
GOTO(out, rc);
|
||||||
@ -663,10 +676,6 @@ vn_set_pwd(const char *filename)
|
|||||||
dput_and_out:
|
dput_and_out:
|
||||||
path_put(&path);
|
path_put(&path);
|
||||||
#else
|
#else
|
||||||
struct nameidata nd;
|
|
||||||
int rc;
|
|
||||||
ENTRY;
|
|
||||||
|
|
||||||
rc = __user_walk(filename,
|
rc = __user_walk(filename,
|
||||||
LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd);
|
LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd);
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -682,6 +691,8 @@ dput_and_out:
|
|||||||
vn_path_release(&nd);
|
vn_path_release(&nd);
|
||||||
#endif /* HAVE_2ARGS_SET_FS_PWD */
|
#endif /* HAVE_2ARGS_SET_FS_PWD */
|
||||||
out:
|
out:
|
||||||
|
set_fs(saved_fs);
|
||||||
|
|
||||||
RETURN(-rc);
|
RETURN(-rc);
|
||||||
} /* vn_set_pwd() */
|
} /* vn_set_pwd() */
|
||||||
EXPORT_SYMBOL(vn_set_pwd);
|
EXPORT_SYMBOL(vn_set_pwd);
|
||||||
|
Loading…
Reference in New Issue
Block a user