@@ -5040,24 +5040,78 @@ static int copy_statmount_to_user(struct kstatmount *s)
5040
5040
return 0 ;
5041
5041
}
5042
5042
5043
- static int do_statmount (struct kstatmount * s )
5043
+ static struct mount * listmnt_next (struct mount * curr , bool reverse )
5044
5044
{
5045
- struct mount * m = real_mount (s -> mnt );
5046
- struct mnt_namespace * ns = m -> mnt_ns ;
5045
+ struct rb_node * node ;
5046
+
5047
+ if (reverse )
5048
+ node = rb_prev (& curr -> mnt_node );
5049
+ else
5050
+ node = rb_next (& curr -> mnt_node );
5051
+
5052
+ return node_to_mount (node );
5053
+ }
5054
+
5055
+ static int grab_requested_root (struct mnt_namespace * ns , struct path * root )
5056
+ {
5057
+ struct mount * first ;
5058
+
5059
+ rwsem_assert_held (& namespace_sem );
5060
+
5061
+ /* We're looking at our own ns, just use get_fs_root. */
5062
+ if (ns == current -> nsproxy -> mnt_ns ) {
5063
+ get_fs_root (current -> fs , root );
5064
+ return 0 ;
5065
+ }
5066
+
5067
+ /*
5068
+ * We have to find the first mount in our ns and use that, however it
5069
+ * may not exist, so handle that properly.
5070
+ */
5071
+ if (RB_EMPTY_ROOT (& ns -> mounts ))
5072
+ return - ENOENT ;
5073
+
5074
+ first = listmnt_next (ns -> root , false);
5075
+ if (!first )
5076
+ return - ENOENT ;
5077
+ root -> mnt = mntget (& first -> mnt );
5078
+ root -> dentry = dget (root -> mnt -> mnt_root );
5079
+ return 0 ;
5080
+ }
5081
+
5082
+ static int do_statmount (struct kstatmount * s , u64 mnt_id , u64 mnt_ns_id ,
5083
+ struct mnt_namespace * ns )
5084
+ {
5085
+ struct path root __free (path_put ) = {};
5086
+ struct mount * m ;
5047
5087
int err ;
5048
5088
5089
+ /* Has the namespace already been emptied? */
5090
+ if (mnt_ns_id && RB_EMPTY_ROOT (& ns -> mounts ))
5091
+ return - ENOENT ;
5092
+
5093
+ s -> mnt = lookup_mnt_in_ns (mnt_id , ns );
5094
+ if (!s -> mnt )
5095
+ return - ENOENT ;
5096
+
5097
+ err = grab_requested_root (ns , & root );
5098
+ if (err )
5099
+ return err ;
5100
+
5049
5101
/*
5050
5102
* Don't trigger audit denials. We just want to determine what
5051
5103
* mounts to show users.
5052
5104
*/
5053
- if (!is_path_reachable (m , m -> mnt .mnt_root , & s -> root ) &&
5105
+ m = real_mount (s -> mnt );
5106
+ if (!is_path_reachable (m , m -> mnt .mnt_root , & root ) &&
5054
5107
!ns_capable_noaudit (ns -> user_ns , CAP_SYS_ADMIN ))
5055
5108
return - EPERM ;
5056
5109
5057
5110
err = security_sb_statfs (s -> mnt -> mnt_root );
5058
5111
if (err )
5059
5112
return err ;
5060
5113
5114
+ s -> root = root ;
5061
5115
if (s -> mask & STATMOUNT_SB_BASIC )
5062
5116
statmount_sb_basic (s );
5063
5117
@@ -5096,6 +5150,9 @@ static inline bool retry_statmount(const long ret, size_t *seq_size)
5096
5150
return true;
5097
5151
}
5098
5152
5153
+ #define STATMOUNT_STRING_REQ (STATMOUNT_MNT_ROOT | STATMOUNT_MNT_POINT | \
5154
+ STATMOUNT_FS_TYPE)
5155
+
5099
5156
static int prepare_kstatmount (struct kstatmount * ks , struct mnt_id_req * kreq ,
5100
5157
struct statmount __user * buf , size_t bufsize ,
5101
5158
size_t seq_size )
@@ -5107,10 +5164,18 @@ static int prepare_kstatmount(struct kstatmount *ks, struct mnt_id_req *kreq,
5107
5164
ks -> mask = kreq -> param ;
5108
5165
ks -> buf = buf ;
5109
5166
ks -> bufsize = bufsize ;
5110
- ks -> seq .size = seq_size ;
5111
- ks -> seq .buf = kvmalloc (seq_size , GFP_KERNEL_ACCOUNT );
5112
- if (!ks -> seq .buf )
5113
- return - ENOMEM ;
5167
+
5168
+ if (ks -> mask & STATMOUNT_STRING_REQ ) {
5169
+ if (bufsize == sizeof (ks -> sm ))
5170
+ return - EOVERFLOW ;
5171
+
5172
+ ks -> seq .buf = kvmalloc (seq_size , GFP_KERNEL_ACCOUNT );
5173
+ if (!ks -> seq .buf )
5174
+ return - ENOMEM ;
5175
+
5176
+ ks -> seq .size = seq_size ;
5177
+ }
5178
+
5114
5179
return 0 ;
5115
5180
}
5116
5181
@@ -5138,45 +5203,6 @@ static int copy_mnt_id_req(const struct mnt_id_req __user *req,
5138
5203
return 0 ;
5139
5204
}
5140
5205
5141
- static struct mount * listmnt_next (struct mount * curr , bool reverse )
5142
- {
5143
- struct rb_node * node ;
5144
-
5145
- if (reverse )
5146
- node = rb_prev (& curr -> mnt_node );
5147
- else
5148
- node = rb_next (& curr -> mnt_node );
5149
-
5150
- return node_to_mount (node );
5151
- }
5152
-
5153
- static int grab_requested_root (struct mnt_namespace * ns , struct path * root )
5154
- {
5155
- struct mount * first ;
5156
-
5157
- rwsem_assert_held (& namespace_sem );
5158
-
5159
- /* We're looking at our own ns, just use get_fs_root. */
5160
- if (ns == current -> nsproxy -> mnt_ns ) {
5161
- get_fs_root (current -> fs , root );
5162
- return 0 ;
5163
- }
5164
-
5165
- /*
5166
- * We have to find the first mount in our ns and use that, however it
5167
- * may not exist, so handle that properly.
5168
- */
5169
- if (RB_EMPTY_ROOT (& ns -> mounts ))
5170
- return - ENOENT ;
5171
-
5172
- first = listmnt_next (ns -> root , false);
5173
- if (!first )
5174
- return - ENOENT ;
5175
- root -> mnt = mntget (& first -> mnt );
5176
- root -> dentry = dget (root -> mnt -> mnt_root );
5177
- return 0 ;
5178
- }
5179
-
5180
5206
/*
5181
5207
* If the user requested a specific mount namespace id, look that up and return
5182
5208
* that, or if not simply grab a passive reference on our mount namespace and
@@ -5195,9 +5221,8 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
5195
5221
unsigned int , flags )
5196
5222
{
5197
5223
struct mnt_namespace * ns __free (mnt_ns_release ) = NULL ;
5198
- struct vfsmount * mnt ;
5224
+ struct kstatmount * ks __free ( kfree ) = NULL ;
5199
5225
struct mnt_id_req kreq ;
5200
- struct kstatmount ks ;
5201
5226
/* We currently support retrieval of 3 strings. */
5202
5227
size_t seq_size = 3 * PATH_MAX ;
5203
5228
int ret ;
@@ -5217,40 +5242,21 @@ SYSCALL_DEFINE4(statmount, const struct mnt_id_req __user *, req,
5217
5242
!ns_capable_noaudit (ns -> user_ns , CAP_SYS_ADMIN ))
5218
5243
return - ENOENT ;
5219
5244
5245
+ ks = kmalloc (sizeof (* ks ), GFP_KERNEL_ACCOUNT );
5246
+ if (!ks )
5247
+ return - ENOMEM ;
5248
+
5220
5249
retry :
5221
- ret = prepare_kstatmount (& ks , & kreq , buf , bufsize , seq_size );
5250
+ ret = prepare_kstatmount (ks , & kreq , buf , bufsize , seq_size );
5222
5251
if (ret )
5223
5252
return ret ;
5224
5253
5225
- down_read (& namespace_sem );
5226
- /* Has the namespace already been emptied? */
5227
- if (kreq .mnt_ns_id && RB_EMPTY_ROOT (& ns -> mounts )) {
5228
- up_read (& namespace_sem );
5229
- kvfree (ks .seq .buf );
5230
- return - ENOENT ;
5231
- }
5232
-
5233
- mnt = lookup_mnt_in_ns (kreq .mnt_id , ns );
5234
- if (!mnt ) {
5235
- up_read (& namespace_sem );
5236
- kvfree (ks .seq .buf );
5237
- return - ENOENT ;
5238
- }
5239
-
5240
- ks .mnt = mnt ;
5241
- ret = grab_requested_root (ns , & ks .root );
5242
- if (ret ) {
5243
- up_read (& namespace_sem );
5244
- kvfree (ks .seq .buf );
5245
- return ret ;
5246
- }
5247
- ret = do_statmount (& ks );
5248
- path_put (& ks .root );
5249
- up_read (& namespace_sem );
5254
+ scoped_guard (rwsem_read , & namespace_sem )
5255
+ ret = do_statmount (ks , kreq .mnt_id , kreq .mnt_ns_id , ns );
5250
5256
5251
5257
if (!ret )
5252
- ret = copy_statmount_to_user (& ks );
5253
- kvfree (ks . seq .buf );
5258
+ ret = copy_statmount_to_user (ks );
5259
+ kvfree (ks -> seq .buf );
5254
5260
if (retry_statmount (ret , & seq_size ))
5255
5261
goto retry ;
5256
5262
return ret ;
0 commit comments