@@ -5072,13 +5072,30 @@ static int statmount_mnt_opts(struct kstatmount *s, struct seq_file *seq)
50725072 return 0 ;
50735073}
50745074
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+
50755093static int statmount_opt_array (struct kstatmount * s , struct seq_file * seq )
50765094{
50775095 struct vfsmount * mnt = s -> mnt ;
50785096 struct super_block * sb = mnt -> mnt_sb ;
50795097 size_t start = seq -> count ;
5080- char * buf_start , * buf_end , * opt_start , * opt_end ;
5081- u32 count = 0 ;
5098+ char * buf_start ;
50825099 int err ;
50835100
50845101 if (!sb -> s_op -> show_options )
@@ -5095,17 +5112,39 @@ static int statmount_opt_array(struct kstatmount *s, struct seq_file *seq)
50955112 if (seq -> count == start )
50965113 return 0 ;
50975114
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 ;
51095148 return 0 ;
51105149}
51115150
@@ -5138,6 +5177,10 @@ static int statmount_string(struct kstatmount *s, u64 flag)
51385177 sm -> opt_array = start ;
51395178 ret = statmount_opt_array (s , seq );
51405179 break ;
5180+ case STATMOUNT_OPT_SEC_ARRAY :
5181+ sm -> opt_sec_array = start ;
5182+ ret = statmount_opt_sec_array (s , seq );
5183+ break ;
51415184 case STATMOUNT_FS_SUBTYPE :
51425185 sm -> fs_subtype = start ;
51435186 statmount_fs_subtype (s , seq );
@@ -5294,6 +5337,9 @@ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id,
52945337 if (!err && s -> mask & STATMOUNT_OPT_ARRAY )
52955338 err = statmount_string (s , STATMOUNT_OPT_ARRAY );
52965339
5340+ if (!err && s -> mask & STATMOUNT_OPT_SEC_ARRAY )
5341+ err = statmount_string (s , STATMOUNT_OPT_SEC_ARRAY );
5342+
52975343 if (!err && s -> mask & STATMOUNT_FS_SUBTYPE )
52985344 err = statmount_string (s , STATMOUNT_FS_SUBTYPE );
52995345
@@ -5323,7 +5369,7 @@ static inline bool retry_statmount(const long ret, size_t *seq_size)
53235369#define STATMOUNT_STRING_REQ (STATMOUNT_MNT_ROOT | STATMOUNT_MNT_POINT | \
53245370 STATMOUNT_FS_TYPE | STATMOUNT_MNT_OPTS | \
53255371 STATMOUNT_FS_SUBTYPE | STATMOUNT_SB_SOURCE | \
5326- STATMOUNT_OPT_ARRAY)
5372+ STATMOUNT_OPT_ARRAY | STATMOUNT_OPT_SEC_ARRAY )
53275373
53285374static int prepare_kstatmount (struct kstatmount * ks , struct mnt_id_req * kreq ,
53295375 struct statmount __user * buf , size_t bufsize ,
0 commit comments