Skip to content

Commit d18516a

Browse files
Miklos Szeredibrauner
authored andcommitted
statmount: clean up unescaped option handling
Move common code from opt_array/opt_sec_array to helper. This helper does more than just unescape options, so rename to statmount_opt_process(). Handle corner case of just a single character in options. Rename some local variables to better describe their function. Signed-off-by: Miklos Szeredi <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Jeff Layton <[email protected]> Signed-off-by: Christian Brauner <[email protected]>
1 parent b3e2963 commit d18516a

File tree

1 file changed

+19
-25
lines changed

1 file changed

+19
-25
lines changed

fs/namespace.c

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5057,21 +5057,32 @@ static int statmount_mnt_opts(struct kstatmount *s, struct seq_file *seq)
50575057
return 0;
50585058
}
50595059

5060-
static inline int statmount_opt_unescape(struct seq_file *seq, char *buf_start)
5060+
static inline int statmount_opt_process(struct seq_file *seq, size_t start)
50615061
{
5062-
char *buf_end, *opt_start, *opt_end;
5062+
char *buf_end, *opt_end, *src, *dst;
50635063
int count = 0;
50645064

5065+
if (unlikely(seq_has_overflowed(seq)))
5066+
return -EAGAIN;
5067+
50655068
buf_end = seq->buf + seq->count;
5069+
dst = seq->buf + start;
5070+
src = dst + 1; /* skip initial comma */
5071+
5072+
if (src >= buf_end) {
5073+
seq->count = start;
5074+
return 0;
5075+
}
5076+
50665077
*buf_end = '\0';
5067-
for (opt_start = buf_start + 1; opt_start < buf_end; opt_start = opt_end + 1) {
5068-
opt_end = strchrnul(opt_start, ',');
5078+
for (; src < buf_end; src = opt_end + 1) {
5079+
opt_end = strchrnul(src, ',');
50695080
*opt_end = '\0';
5070-
buf_start += string_unescape(opt_start, buf_start, 0, UNESCAPE_OCTAL) + 1;
5081+
dst += string_unescape(src, dst, 0, UNESCAPE_OCTAL) + 1;
50715082
if (WARN_ON_ONCE(++count == INT_MAX))
50725083
return -EOVERFLOW;
50735084
}
5074-
seq->count = buf_start - 1 - seq->buf;
5085+
seq->count = dst - 1 - seq->buf;
50755086
return count;
50765087
}
50775088

@@ -5080,24 +5091,16 @@ static int statmount_opt_array(struct kstatmount *s, struct seq_file *seq)
50805091
struct vfsmount *mnt = s->mnt;
50815092
struct super_block *sb = mnt->mnt_sb;
50825093
size_t start = seq->count;
5083-
char *buf_start;
50845094
int err;
50855095

50865096
if (!sb->s_op->show_options)
50875097
return 0;
50885098

5089-
buf_start = seq->buf + start;
50905099
err = sb->s_op->show_options(seq, mnt->mnt_root);
50915100
if (err)
50925101
return err;
50935102

5094-
if (unlikely(seq_has_overflowed(seq)))
5095-
return -EAGAIN;
5096-
5097-
if (seq->count == start)
5098-
return 0;
5099-
5100-
err = statmount_opt_unescape(seq, buf_start);
5103+
err = statmount_opt_process(seq, start);
51015104
if (err < 0)
51025105
return err;
51035106

@@ -5110,22 +5113,13 @@ static int statmount_opt_sec_array(struct kstatmount *s, struct seq_file *seq)
51105113
struct vfsmount *mnt = s->mnt;
51115114
struct super_block *sb = mnt->mnt_sb;
51125115
size_t start = seq->count;
5113-
char *buf_start;
51145116
int err;
51155117

5116-
buf_start = seq->buf + start;
5117-
51185118
err = security_sb_show_options(seq, sb);
51195119
if (!err)
51205120
return err;
51215121

5122-
if (unlikely(seq_has_overflowed(seq)))
5123-
return -EAGAIN;
5124-
5125-
if (seq->count == start)
5126-
return 0;
5127-
5128-
err = statmount_opt_unescape(seq, buf_start);
5122+
err = statmount_opt_process(seq, start);
51295123
if (err < 0)
51305124
return err;
51315125

0 commit comments

Comments
 (0)