Re: [PATCH] VFS: Suppress automount on [l]stat, [l]getxattr, etc.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



David Howells <dhowells@xxxxxxxxxx> writes:

> Directly suppress automount on the following:
>
> 	[l]stat
> 	[l]getxattr
> 	[l]setxattr
> 	[l]listxattr
> 	[l]removexattr
> 	name_to_handle_at
> 	fstatat
> 	statfs
> 	utimes
>
> But provide an AT_AUTOMOUNT_FOLLOW path where possible to override that
> behaviour.
>
> This changes the behaviour back to before the in-VFS automount patches were
> applied, thus, for example, preventing stat() from causing automounting, but
> allows it to be overridden where possible.
>
> However, what about the following:
>
> 	umount
> 	faccessat
> 	fchmodat, chmod
> 	fchownat, lchown, chown
>
> Should these or should these not cause automounting?

It probably doesn't matter.  Old kernels used to not automount on these
and it didn't cause problems, but I'm quite sure that if they do
automount that will not cause problems either.

>
> It's possible that with these additions, the whole decision point in
> follow_automount() can be reduced to just a check of LOOKUP_NO_AUTOMOUNT.
>
> Signed-off-by: David Howells <dhowells@xxxxxxxxxx>
> ---
>
>  fs/fhandle.c          |    2 +-
>  fs/stat.c             |    8 ++++----
>  fs/statfs.c           |    3 ++-
>  fs/utimes.c           |   10 +++++++---
>  fs/xattr.c            |   20 ++++++++++++--------
>  include/linux/fcntl.h |    1 +
>  6 files changed, 27 insertions(+), 17 deletions(-)
>
> diff --git a/fs/fhandle.c b/fs/fhandle.c
> index 6b08864..bc0f327 100644
> --- a/fs/fhandle.c
> +++ b/fs/fhandle.c
> @@ -92,7 +92,7 @@ SYSCALL_DEFINE5(name_to_handle_at, int, dfd, const char __user *, name,
>  		int, flag)
>  {
>  	struct path path;
> -	int lookup_flags;
> +	int lookup_flags = LOOKUP_NO_AUTOMOUNT;

lookup_flags is going to be reinitialized later, so this has no affect.

Otherwise looks good.

Thanks,
Miklos

>  	int err;
>  
>  	if ((flag & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
> diff --git a/fs/stat.c b/fs/stat.c
> index ba5316f..e39b489 100644
> --- a/fs/stat.c
> +++ b/fs/stat.c
> @@ -73,16 +73,16 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
>  {
>  	struct path path;
>  	int error = -EINVAL;
> -	int lookup_flags = 0;
> +	int lookup_flags = LOOKUP_NO_AUTOMOUNT;
>  
>  	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
> -		      AT_EMPTY_PATH)) != 0)
> +		      AT_EMPTY_PATH | AT_AUTOMOUNT_FOLLOW)) != 0)
>  		goto out;
>  
>  	if (!(flag & AT_SYMLINK_NOFOLLOW))
>  		lookup_flags |= LOOKUP_FOLLOW;
> -	if (flag & AT_NO_AUTOMOUNT)
> -		lookup_flags |= LOOKUP_NO_AUTOMOUNT;
> +	if (!(flag & AT_AUTOMOUNT_FOLLOW))
> +		lookup_flags &= ~LOOKUP_NO_AUTOMOUNT;
>  	if (flag & AT_EMPTY_PATH)
>  		lookup_flags |= LOOKUP_EMPTY;
>  
> diff --git a/fs/statfs.c b/fs/statfs.c
> index 8244924..fe64701 100644
> --- a/fs/statfs.c
> +++ b/fs/statfs.c
> @@ -76,7 +76,8 @@ EXPORT_SYMBOL(vfs_statfs);
>  int user_statfs(const char __user *pathname, struct kstatfs *st)
>  {
>  	struct path path;
> -	int error = user_path(pathname, &path);
> +	int error = user_path_at(AT_FDCWD, pathname, LOOKUP_NO_AUTOMOUNT,
> +				 &path);
>  	if (!error) {
>  		error = vfs_statfs(&path, st);
>  		path_put(&path);
> diff --git a/fs/utimes.c b/fs/utimes.c
> index ba653f3..e9bf196 100644
> --- a/fs/utimes.c
> +++ b/fs/utimes.c
> @@ -136,13 +136,15 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
>  		goto out;
>  	}
>  
> -	if (flags & ~AT_SYMLINK_NOFOLLOW)
> +	if (flags & ~(AT_SYMLINK_NOFOLLOW |
> +		      AT_NO_AUTOMOUNT | AT_AUTOMOUNT_FOLLOW))
>  		goto out;
>  
>  	if (filename == NULL && dfd != AT_FDCWD) {
>  		struct file *file;
>  
> -		if (flags & AT_SYMLINK_NOFOLLOW)
> +		if (flags & (AT_SYMLINK_NOFOLLOW |
> +			     AT_NO_AUTOMOUNT | AT_AUTOMOUNT_FOLLOW))
>  			goto out;
>  
>  		file = fget(dfd);
> @@ -154,10 +156,12 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
>  		fput(file);
>  	} else {
>  		struct path path;
> -		int lookup_flags = 0;
> +		int lookup_flags = LOOKUP_NO_AUTOMOUNT;
>  
>  		if (!(flags & AT_SYMLINK_NOFOLLOW))
>  			lookup_flags |= LOOKUP_FOLLOW;
> +		if (flags & AT_AUTOMOUNT_FOLLOW)
> +			lookup_flags &= ~LOOKUP_NO_AUTOMOUNT;
>  
>  		error = user_path_at(dfd, filename, lookup_flags, &path);
>  		if (error)
> diff --git a/fs/xattr.c b/fs/xattr.c
> index f060663..7c462ae 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -290,7 +290,8 @@ SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
>  	struct path path;
>  	int error;
>  
> -	error = user_path(pathname, &path);
> +	error = user_path_at(AT_FDCWD, pathname,
> +			     LOOKUP_FOLLOW | LOOKUP_NO_AUTOMOUNT, &path);
>  	if (error)
>  		return error;
>  	error = mnt_want_write(path.mnt);
> @@ -309,7 +310,7 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
>  	struct path path;
>  	int error;
>  
> -	error = user_lpath(pathname, &path);
> +	error = user_path_at(AT_FDCWD, pathname, LOOKUP_NO_AUTOMOUNT, &path);
>  	if (error)
>  		return error;
>  	error = mnt_want_write(path.mnt);
> @@ -386,7 +387,8 @@ SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
>  	struct path path;
>  	ssize_t error;
>  
> -	error = user_path(pathname, &path);
> +	error = user_path_at(AT_FDCWD, pathname,
> +			     LOOKUP_FOLLOW | LOOKUP_NO_AUTOMOUNT, &path);
>  	if (error)
>  		return error;
>  	error = getxattr(path.dentry, name, value, size);
> @@ -400,7 +402,7 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
>  	struct path path;
>  	ssize_t error;
>  
> -	error = user_lpath(pathname, &path);
> +	error = user_path_at(AT_FDCWD, pathname, LOOKUP_NO_AUTOMOUNT, &path);
>  	if (error)
>  		return error;
>  	error = getxattr(path.dentry, name, value, size);
> @@ -459,7 +461,8 @@ SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
>  	struct path path;
>  	ssize_t error;
>  
> -	error = user_path(pathname, &path);
> +	error = user_path_at(AT_FDCWD, pathname,
> +			     LOOKUP_FOLLOW | LOOKUP_NO_AUTOMOUNT, &path);
>  	if (error)
>  		return error;
>  	error = listxattr(path.dentry, list, size);
> @@ -473,7 +476,7 @@ SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
>  	struct path path;
>  	ssize_t error;
>  
> -	error = user_lpath(pathname, &path);
> +	error = user_path_at(AT_FDCWD, pathname, LOOKUP_NO_AUTOMOUNT, &path);
>  	if (error)
>  		return error;
>  	error = listxattr(path.dentry, list, size);
> @@ -519,7 +522,8 @@ SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
>  	struct path path;
>  	int error;
>  
> -	error = user_path(pathname, &path);
> +	error = user_path_at(AT_FDCWD, pathname,
> +			     LOOKUP_FOLLOW | LOOKUP_NO_AUTOMOUNT, &path);
>  	if (error)
>  		return error;
>  	error = mnt_want_write(path.mnt);
> @@ -537,7 +541,7 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
>  	struct path path;
>  	int error;
>  
> -	error = user_lpath(pathname, &path);
> +	error = user_path_at(AT_FDCWD, pathname, LOOKUP_NO_AUTOMOUNT, &path);
>  	if (error)
>  		return error;
>  	error = mnt_want_write(path.mnt);
> diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
> index f550f89..768fb66 100644
> --- a/include/linux/fcntl.h
> +++ b/include/linux/fcntl.h
> @@ -47,6 +47,7 @@
>  #define AT_SYMLINK_FOLLOW	0x400   /* Follow symbolic links.  */
>  #define AT_NO_AUTOMOUNT		0x800	/* Suppress terminal automount traversal */
>  #define AT_EMPTY_PATH		0x1000	/* Allow empty relative pathname */
> +#define AT_AUTOMOUNT_FOLLOW	0x2000	/* Follow terminal automounts */
>  
>  #ifdef __KERNEL__
>  
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux