@@ -4683,6 +4683,287 @@ int show_path(struct seq_file *m, struct dentry *root)
46834683 return 0 ;
46844684}
46854685
4686+ static struct vfsmount * lookup_mnt_in_ns (u64 id , struct mnt_namespace * ns )
4687+ {
4688+ struct mount * mnt = mnt_find_id_at (ns , id );
4689+
4690+ if (!mnt || mnt -> mnt_id_unique != id )
4691+ return NULL ;
4692+
4693+ return & mnt -> mnt ;
4694+ }
4695+
4696+ struct kstatmount {
4697+ struct statmount __user * const buf ;
4698+ size_t const bufsize ;
4699+ struct vfsmount * const mnt ;
4700+ u64 const mask ;
4701+ struct seq_file seq ;
4702+ struct path root ;
4703+ struct statmount sm ;
4704+ size_t pos ;
4705+ int err ;
4706+ };
4707+
4708+ typedef int (* statmount_func_t )(struct kstatmount * );
4709+
4710+ static int statmount_string_seq (struct kstatmount * s , statmount_func_t func )
4711+ {
4712+ size_t rem = s -> bufsize - s -> pos - sizeof (s -> sm );
4713+ struct seq_file * seq = & s -> seq ;
4714+ int ret ;
4715+
4716+ seq -> count = 0 ;
4717+ seq -> size = min (seq -> size , rem );
4718+ seq -> buf = kvmalloc (seq -> size , GFP_KERNEL_ACCOUNT );
4719+ if (!seq -> buf )
4720+ return - ENOMEM ;
4721+
4722+ ret = func (s );
4723+ if (ret )
4724+ return ret ;
4725+
4726+ if (seq_has_overflowed (seq )) {
4727+ if (seq -> size == rem )
4728+ return - EOVERFLOW ;
4729+ seq -> size *= 2 ;
4730+ if (seq -> size > MAX_RW_COUNT )
4731+ return - ENOMEM ;
4732+ kvfree (seq -> buf );
4733+ return 0 ;
4734+ }
4735+
4736+ /* Done */
4737+ return 1 ;
4738+ }
4739+
4740+ static void statmount_string (struct kstatmount * s , u64 mask , statmount_func_t func ,
4741+ u32 * str )
4742+ {
4743+ int ret = s -> pos + sizeof (s -> sm ) >= s -> bufsize ? - EOVERFLOW : 0 ;
4744+ struct statmount * sm = & s -> sm ;
4745+ struct seq_file * seq = & s -> seq ;
4746+
4747+ if (s -> err || !(s -> mask & mask ))
4748+ return ;
4749+
4750+ seq -> size = PAGE_SIZE ;
4751+ while (!ret )
4752+ ret = statmount_string_seq (s , func );
4753+
4754+ if (ret < 0 ) {
4755+ s -> err = ret ;
4756+ } else {
4757+ seq -> buf [seq -> count ++ ] = '\0' ;
4758+ if (copy_to_user (s -> buf -> str + s -> pos , seq -> buf , seq -> count )) {
4759+ s -> err = - EFAULT ;
4760+ } else {
4761+ * str = s -> pos ;
4762+ s -> pos += seq -> count ;
4763+ }
4764+ }
4765+ kvfree (seq -> buf );
4766+ sm -> mask |= mask ;
4767+ }
4768+
4769+ static void statmount_numeric (struct kstatmount * s , u64 mask , statmount_func_t func )
4770+ {
4771+ if (s -> err || !(s -> mask & mask ))
4772+ return ;
4773+
4774+ s -> err = func (s );
4775+ s -> sm .mask |= mask ;
4776+ }
4777+
4778+ static u64 mnt_to_attr_flags (struct vfsmount * mnt )
4779+ {
4780+ unsigned int mnt_flags = READ_ONCE (mnt -> mnt_flags );
4781+ u64 attr_flags = 0 ;
4782+
4783+ if (mnt_flags & MNT_READONLY )
4784+ attr_flags |= MOUNT_ATTR_RDONLY ;
4785+ if (mnt_flags & MNT_NOSUID )
4786+ attr_flags |= MOUNT_ATTR_NOSUID ;
4787+ if (mnt_flags & MNT_NODEV )
4788+ attr_flags |= MOUNT_ATTR_NODEV ;
4789+ if (mnt_flags & MNT_NOEXEC )
4790+ attr_flags |= MOUNT_ATTR_NOEXEC ;
4791+ if (mnt_flags & MNT_NODIRATIME )
4792+ attr_flags |= MOUNT_ATTR_NODIRATIME ;
4793+ if (mnt_flags & MNT_NOSYMFOLLOW )
4794+ attr_flags |= MOUNT_ATTR_NOSYMFOLLOW ;
4795+
4796+ if (mnt_flags & MNT_NOATIME )
4797+ attr_flags |= MOUNT_ATTR_NOATIME ;
4798+ else if (mnt_flags & MNT_RELATIME )
4799+ attr_flags |= MOUNT_ATTR_RELATIME ;
4800+ else
4801+ attr_flags |= MOUNT_ATTR_STRICTATIME ;
4802+
4803+ if (is_idmapped_mnt (mnt ))
4804+ attr_flags |= MOUNT_ATTR_IDMAP ;
4805+
4806+ return attr_flags ;
4807+ }
4808+
4809+ static u64 mnt_to_propagation_flags (struct mount * m )
4810+ {
4811+ u64 propagation = 0 ;
4812+
4813+ if (IS_MNT_SHARED (m ))
4814+ propagation |= MS_SHARED ;
4815+ if (IS_MNT_SLAVE (m ))
4816+ propagation |= MS_SLAVE ;
4817+ if (IS_MNT_UNBINDABLE (m ))
4818+ propagation |= MS_UNBINDABLE ;
4819+ if (!propagation )
4820+ propagation |= MS_PRIVATE ;
4821+
4822+ return propagation ;
4823+ }
4824+
4825+ static int statmount_sb_basic (struct kstatmount * s )
4826+ {
4827+ struct super_block * sb = s -> mnt -> mnt_sb ;
4828+
4829+ s -> sm .sb_dev_major = MAJOR (sb -> s_dev );
4830+ s -> sm .sb_dev_minor = MINOR (sb -> s_dev );
4831+ s -> sm .sb_magic = sb -> s_magic ;
4832+ s -> sm .sb_flags = sb -> s_flags & (SB_RDONLY |SB_SYNCHRONOUS |SB_DIRSYNC |SB_LAZYTIME );
4833+
4834+ return 0 ;
4835+ }
4836+
4837+ static int statmount_mnt_basic (struct kstatmount * s )
4838+ {
4839+ struct mount * m = real_mount (s -> mnt );
4840+
4841+ s -> sm .mnt_id = m -> mnt_id_unique ;
4842+ s -> sm .mnt_parent_id = m -> mnt_parent -> mnt_id_unique ;
4843+ s -> sm .mnt_id_old = m -> mnt_id ;
4844+ s -> sm .mnt_parent_id_old = m -> mnt_parent -> mnt_id ;
4845+ s -> sm .mnt_attr = mnt_to_attr_flags (& m -> mnt );
4846+ s -> sm .mnt_propagation = mnt_to_propagation_flags (m );
4847+ s -> sm .mnt_peer_group = IS_MNT_SHARED (m ) ? m -> mnt_group_id : 0 ;
4848+ s -> sm .mnt_master = IS_MNT_SLAVE (m ) ? m -> mnt_master -> mnt_group_id : 0 ;
4849+
4850+ return 0 ;
4851+ }
4852+
4853+ static int statmount_propagate_from (struct kstatmount * s )
4854+ {
4855+ struct mount * m = real_mount (s -> mnt );
4856+
4857+ if (!IS_MNT_SLAVE (m ))
4858+ return 0 ;
4859+
4860+ s -> sm .propagate_from = get_dominating_id (m , & current -> fs -> root );
4861+
4862+ return 0 ;
4863+ }
4864+
4865+ static int statmount_mnt_root (struct kstatmount * s )
4866+ {
4867+ struct seq_file * seq = & s -> seq ;
4868+ int err = show_path (seq , s -> mnt -> mnt_root );
4869+
4870+ if (!err && !seq_has_overflowed (seq )) {
4871+ seq -> buf [seq -> count ] = '\0' ;
4872+ seq -> count = string_unescape_inplace (seq -> buf , UNESCAPE_OCTAL );
4873+ }
4874+ return err ;
4875+ }
4876+
4877+ static int statmount_mnt_point (struct kstatmount * s )
4878+ {
4879+ struct vfsmount * mnt = s -> mnt ;
4880+ struct path mnt_path = { .dentry = mnt -> mnt_root , .mnt = mnt };
4881+ int err = seq_path_root (& s -> seq , & mnt_path , & s -> root , "" );
4882+
4883+ return err == SEQ_SKIP ? 0 : err ;
4884+ }
4885+
4886+ static int statmount_fs_type (struct kstatmount * s )
4887+ {
4888+ struct seq_file * seq = & s -> seq ;
4889+ struct super_block * sb = s -> mnt -> mnt_sb ;
4890+
4891+ seq_puts (seq , sb -> s_type -> name );
4892+ return 0 ;
4893+ }
4894+
4895+ static int do_statmount (struct kstatmount * s )
4896+ {
4897+ struct statmount * sm = & s -> sm ;
4898+ struct mount * m = real_mount (s -> mnt );
4899+ size_t copysize = min_t (size_t , s -> bufsize , sizeof (* sm ));
4900+ int err ;
4901+
4902+ /*
4903+ * Don't trigger audit denials. We just want to determine what
4904+ * mounts to show users.
4905+ */
4906+ if (!is_path_reachable (m , m -> mnt .mnt_root , & s -> root ) &&
4907+ !ns_capable_noaudit (& init_user_ns , CAP_SYS_ADMIN ))
4908+ return - EPERM ;
4909+
4910+ err = security_sb_statfs (s -> mnt -> mnt_root );
4911+ if (err )
4912+ return err ;
4913+
4914+ statmount_numeric (s , STATMOUNT_SB_BASIC , statmount_sb_basic );
4915+ statmount_numeric (s , STATMOUNT_MNT_BASIC , statmount_mnt_basic );
4916+ statmount_numeric (s , STATMOUNT_PROPAGATE_FROM , statmount_propagate_from );
4917+ statmount_string (s , STATMOUNT_FS_TYPE , statmount_fs_type , & sm -> fs_type );
4918+ statmount_string (s , STATMOUNT_MNT_ROOT , statmount_mnt_root , & sm -> mnt_root );
4919+ statmount_string (s , STATMOUNT_MNT_POINT , statmount_mnt_point , & sm -> mnt_point );
4920+
4921+ if (s -> err )
4922+ return s -> err ;
4923+
4924+ /* Return the number of bytes copied to the buffer */
4925+ sm -> size = copysize + s -> pos ;
4926+
4927+ if (copy_to_user (s -> buf , sm , copysize ))
4928+ return - EFAULT ;
4929+
4930+ return 0 ;
4931+ }
4932+
4933+ SYSCALL_DEFINE4 (statmount , const struct mnt_id_req __user * , req ,
4934+ struct statmount __user * , buf , size_t , bufsize ,
4935+ unsigned int , flags )
4936+ {
4937+ struct vfsmount * mnt ;
4938+ struct mnt_id_req kreq ;
4939+ int ret ;
4940+
4941+ if (flags )
4942+ return - EINVAL ;
4943+
4944+ if (copy_from_user (& kreq , req , sizeof (kreq )))
4945+ return - EFAULT ;
4946+
4947+ down_read (& namespace_sem );
4948+ mnt = lookup_mnt_in_ns (kreq .mnt_id , current -> nsproxy -> mnt_ns );
4949+ ret = - ENOENT ;
4950+ if (mnt ) {
4951+ struct kstatmount s = {
4952+ .mask = kreq .request_mask ,
4953+ .buf = buf ,
4954+ .bufsize = bufsize ,
4955+ .mnt = mnt ,
4956+ };
4957+
4958+ get_fs_root (current -> fs , & s .root );
4959+ ret = do_statmount (& s );
4960+ path_put (& s .root );
4961+ }
4962+ up_read (& namespace_sem );
4963+
4964+ return ret ;
4965+ }
4966+
46864967static void __init init_mount_tree (void )
46874968{
46884969 struct vfsmount * mnt ;
0 commit comments