lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAM4UoyomEG0=YKQp2ALFXCmpNGriC2n6+4t=pzHyFrkttshEcw@mail.gmail.com>
Date:   Sat, 7 Jan 2023 20:20:59 +0800
From:   Quanfa Fu <quanfafu@...il.com>
To:     Christophe JAILLET <christophe.jaillet@...adoo.fr>
Cc:     rostedt@...dmis.org, mhiramat@...nel.org,
        linux-kernel@...r.kernel.org, linux-trace-kernel@...r.kernel.org
Subject: Re: [PATCH] tracing/eprobe: Replace kzalloc with kmalloc

On Sat, Jan 7, 2023 at 4:42 PM Christophe JAILLET
<christophe.jaillet@...adoo.fr> wrote:
>
> Le 07/01/2023 à 04:45, Quanfa Fu a écrit :
> > Since this memory will be filled soon below, I feel that there is
> > no need for a memory of all zeros here. 'snprintf' does not return
> > negative num according to ISO C99, so I feel that no judgment is
> > needed here.
> >
> > No functional change intended.
> >
> > Signed-off-by: Quanfa Fu <quanfafu@...il.com>
> > ---
> >   kernel/trace/trace_eprobe.c | 4 +---
> >   1 file changed, 1 insertion(+), 3 deletions(-)
> >
> > diff --git a/kernel/trace/trace_eprobe.c b/kernel/trace/trace_eprobe.c
> > index 352b65e2b910..cd1d271a74e7 100644
> > --- a/kernel/trace/trace_eprobe.c
> > +++ b/kernel/trace/trace_eprobe.c
> > @@ -917,15 +917,13 @@ static int trace_eprobe_parse_filter(struct trace_eprobe *ep, int argc, const ch
> >       for (i = 0; i < argc; i++)
> >               len += strlen(argv[i]) + 1;
> >
> > -     ep->filter_str = kzalloc(len, GFP_KERNEL);
> > +     ep->filter_str = kmalloc(len, GFP_KERNEL);
> >       if (!ep->filter_str)
> >               return -ENOMEM;
> >
> >       p = ep->filter_str;
> >       for (i = 0; i < argc; i++) {
> >               ret = snprintf(p, len, "%s ", argv[i]);
> > -             if (ret < 0)
> > -                     goto error;
> >               if (ret > len) {
>
> Hi,
>
> as per [1]:
>   * The return value is the number of characters which would be
>   * generated for the given input, excluding the trailing null,
>   * as per ISO C99.  If the return is greater than *or equal* to
>   * @size, the resulting string is truncated.
>
> So, should this test be:
>      if (ret >= len)
>             ~~~~
>
>
> Also, isn't the p[-1] = '\0' after the loop eating the last character?
>     argc = 1;
>     argv[0] = "a";
>
>     Before the loop:
>     ===============
>     len = 1 + 1 = 2;
>     ep->filter_str = 0x00 0x00
>                      ^
>                      |___ p
>
>     After the loop:
>     ===============
>     ep->filter_str = 0x61 0x00
>                           ^
>                           |___ p
>     len = 1;
>
>     After p[-1]:
>     ============
>     ep->filter_str = 0x00 0x00
>                        ~~ ^
>                           |___ p
>
> Did I miss something obvious?
> I don't know the intent here, or if it is an issue at all, but it looks odd.
>
> CJ
>
>
> [1]: https://elixir.bootlin.com/linux/v6.2-rc1/source/lib/vsprintf.c#L2925
> >                       ret = -E2BIG;
> >                       goto error;
>

I think that:

for example, argc = 2, argv = {"a", "b"};

Before the loop
===============
len = (1 + 1) + (1 + 1) = 4;
ep->filter_str = 0x00 0x00 0x00 0x00
                       ^
                        |__ p
After the loop:
===============
i = 1, snprintf write: 'a' and ' ', so ret = 2
i = 2, snprintf write: 'b' and ' ', so ret = 2
===============
ep->filter_str = 0x61 0x20 0x62 0x00    // Since the length of the
last argv is not enough to write, the space is replaced by null
                                                          ^
                                                          |__ p
p = ep->fiter_str + 2 (ret1) +2 (ret2) = ep->filter_str + 4
===============
so After p[-1] = *(ep->filter_str + 3) = '\0';
ep->filter_str = 0x61 0x20 0x62 0x00

According to ISO C99: " If the output was truncated due to this limit
hen the return value
is the number of characters (excluding the terminating null byte)
which would have been
written to the final string if enough  space  had been available"

The last snprintf will end with 'NULL', so I think p[-1] = '\0' can
also be deleted

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ