Re: [PATCH 1/2] tracing/user_events: Fix non-spaced field matching

From: Beau Belgrave
Date: Mon Apr 22 2024 - 17:55:40 EST


On Sat, Apr 20, 2024 at 09:50:52PM +0900, Masami Hiramatsu wrote:
> On Fri, 19 Apr 2024 14:13:34 -0700
> Beau Belgrave <beaub@xxxxxxxxxxxxxxxxxxx> wrote:
>
> > On Fri, Apr 19, 2024 at 11:33:05AM +0900, Masami Hiramatsu wrote:
> > > On Tue, 16 Apr 2024 22:41:01 +0000
> > > Beau Belgrave <beaub@xxxxxxxxxxxxxxxxxxx> wrote:

*SNIP*

> > > nit: This loop can be simpler, because we are sure fixed has enough length;
> > >
> > > /* insert a space after ';' if there is no space. */
> > > while(*args) {
> > > *pos = *args++;
> > > if (*pos++ == ';' && !isspace(*args))
> > > *pos++ = ' ';
> > > }
> > >
> >
> > I was worried that if count_semis_no_space() ever had different logic
> > (maybe after this commit) that it could cause an overflow if the count
> > was wrong, etc.
> >
> > I don't have an issue making it shorter, but I was trying to be more on
> > the safe side, since this isn't a fast path (event register).
>
> OK, anyway current code looks correct. But note that I don't think
> "pos++; len--;" is safer, since it is not atomic. This pattern
> easily loose "len--;" in my experience. So please carefully use it ;)
>

I'll stick with your loop. Perhaps others will chime in on the v2 and
state a stronger opinion.

You scared me with the atomic comment, I went back and looked at all the
paths for this. In the user_events IOCTL the buffer is copied from user
to kernel, so it cannot change (and no other threads access it). I also
checked trace_parse_run_command() which is the same. So at least in this
context the non-atomic part is OK.

> >
> > > > +
> > > > + /*
> > > > + * len is the length of the copy excluding the null.
> > > > + * This ensures we always have room for a null.
> > > > + */
> > > > + *pos = '\0';
> > > > +
> > > > + return fixed;
> > > > +}
> > > > +
> > > > +static char **user_event_argv_split(char *args, int *argc)
> > > > +{
> > > > + /* Count how many ';' without a trailing space */
> > > > + int count = count_semis_no_space(args);
> > > > +
> > > > + if (count) {
> > >
> > > nit: it is better to exit fast, so
> > >
> > > if (!count)
> > > return argv_split(GFP_KERNEL, args, argc);
> > >
> > > ...
> >
> > Sure, will fix in a v2.
> >
> > >
> > > Thank you,
> > >
> > > OT: BTW, can this also simplify synthetic events?
> > >
> >
> > I'm not sure, I'll check when I have some time. I want to get this fix
> > in sooner rather than later.
>
> Ah, nevermind. Synthetic event parses the field by strsep(';') first
> and argv_split(). So it does not have this issue.
>

Ok, seems unrelated. Thanks for checking.

Thanks,
-Beau

> Thank you,
>
> >
> > Thanks,
> > -Beau
> >

*SNIP*

> > > Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx>
>
>
> --
> Masami Hiramatsu (Google) <mhiramat@xxxxxxxxxx>