@@ -5072,13 +5072,30 @@ static int statmount_mnt_opts(struct kstatmount *s, struct seq_file *seq)
5072
5072
return 0 ;
5073
5073
}
5074
5074
5075
+ static inline int statmount_opt_unescape (struct seq_file * seq , char * buf_start )
5076
+ {
5077
+ char * buf_end , * opt_start , * opt_end ;
5078
+ int count = 0 ;
5079
+
5080
+ buf_end = seq -> buf + seq -> count ;
5081
+ * buf_end = '\0' ;
5082
+ for (opt_start = buf_start + 1 ; opt_start < buf_end ; opt_start = opt_end + 1 ) {
5083
+ opt_end = strchrnul (opt_start , ',' );
5084
+ * opt_end = '\0' ;
5085
+ buf_start += string_unescape (opt_start , buf_start , 0 , UNESCAPE_OCTAL ) + 1 ;
5086
+ if (WARN_ON_ONCE (++ count == INT_MAX ))
5087
+ return - EOVERFLOW ;
5088
+ }
5089
+ seq -> count = buf_start - 1 - seq -> buf ;
5090
+ return count ;
5091
+ }
5092
+
5075
5093
static int statmount_opt_array (struct kstatmount * s , struct seq_file * seq )
5076
5094
{
5077
5095
struct vfsmount * mnt = s -> mnt ;
5078
5096
struct super_block * sb = mnt -> mnt_sb ;
5079
5097
size_t start = seq -> count ;
5080
- char * buf_start , * buf_end , * opt_start , * opt_end ;
5081
- u32 count = 0 ;
5098
+ char * buf_start ;
5082
5099
int err ;
5083
5100
5084
5101
if (!sb -> s_op -> show_options )
@@ -5095,17 +5112,39 @@ static int statmount_opt_array(struct kstatmount *s, struct seq_file *seq)
5095
5112
if (seq -> count == start )
5096
5113
return 0 ;
5097
5114
5098
- buf_end = seq -> buf + seq -> count ;
5099
- * buf_end = '\0' ;
5100
- for (opt_start = buf_start + 1 ; opt_start < buf_end ; opt_start = opt_end + 1 ) {
5101
- opt_end = strchrnul (opt_start , ',' );
5102
- * opt_end = '\0' ;
5103
- buf_start += string_unescape (opt_start , buf_start , 0 , UNESCAPE_OCTAL ) + 1 ;
5104
- if (WARN_ON_ONCE (++ count == 0 ))
5105
- return - EOVERFLOW ;
5106
- }
5107
- seq -> count = buf_start - 1 - seq -> buf ;
5108
- s -> sm .opt_num = count ;
5115
+ err = statmount_opt_unescape (seq , buf_start );
5116
+ if (err < 0 )
5117
+ return err ;
5118
+
5119
+ s -> sm .opt_num = err ;
5120
+ return 0 ;
5121
+ }
5122
+
5123
+ static int statmount_opt_sec_array (struct kstatmount * s , struct seq_file * seq )
5124
+ {
5125
+ struct vfsmount * mnt = s -> mnt ;
5126
+ struct super_block * sb = mnt -> mnt_sb ;
5127
+ size_t start = seq -> count ;
5128
+ char * buf_start ;
5129
+ int err ;
5130
+
5131
+ buf_start = seq -> buf + start ;
5132
+
5133
+ err = security_sb_show_options (seq , sb );
5134
+ if (!err )
5135
+ return err ;
5136
+
5137
+ if (unlikely (seq_has_overflowed (seq )))
5138
+ return - EAGAIN ;
5139
+
5140
+ if (seq -> count == start )
5141
+ return 0 ;
5142
+
5143
+ err = statmount_opt_unescape (seq , buf_start );
5144
+ if (err < 0 )
5145
+ return err ;
5146
+
5147
+ s -> sm .opt_sec_num = err ;
5109
5148
return 0 ;
5110
5149
}
5111
5150
@@ -5138,6 +5177,10 @@ static int statmount_string(struct kstatmount *s, u64 flag)
5138
5177
sm -> opt_array = start ;
5139
5178
ret = statmount_opt_array (s , seq );
5140
5179
break ;
5180
+ case STATMOUNT_OPT_SEC_ARRAY :
5181
+ sm -> opt_sec_array = start ;
5182
+ ret = statmount_opt_sec_array (s , seq );
5183
+ break ;
5141
5184
case STATMOUNT_FS_SUBTYPE :
5142
5185
sm -> fs_subtype = start ;
5143
5186
statmount_fs_subtype (s , seq );
@@ -5294,6 +5337,9 @@ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id,
5294
5337
if (!err && s -> mask & STATMOUNT_OPT_ARRAY )
5295
5338
err = statmount_string (s , STATMOUNT_OPT_ARRAY );
5296
5339
5340
+ if (!err && s -> mask & STATMOUNT_OPT_SEC_ARRAY )
5341
+ err = statmount_string (s , STATMOUNT_OPT_SEC_ARRAY );
5342
+
5297
5343
if (!err && s -> mask & STATMOUNT_FS_SUBTYPE )
5298
5344
err = statmount_string (s , STATMOUNT_FS_SUBTYPE );
5299
5345
@@ -5323,7 +5369,7 @@ static inline bool retry_statmount(const long ret, size_t *seq_size)
5323
5369
#define STATMOUNT_STRING_REQ (STATMOUNT_MNT_ROOT | STATMOUNT_MNT_POINT | \
5324
5370
STATMOUNT_FS_TYPE | STATMOUNT_MNT_OPTS | \
5325
5371
STATMOUNT_FS_SUBTYPE | STATMOUNT_SB_SOURCE | \
5326
- STATMOUNT_OPT_ARRAY)
5372
+ STATMOUNT_OPT_ARRAY | STATMOUNT_OPT_SEC_ARRAY )
5327
5373
5328
5374
static int prepare_kstatmount (struct kstatmount * ks , struct mnt_id_req * kreq ,
5329
5375
struct statmount __user * buf , size_t bufsize ,
0 commit comments