Re: [PATCH v3] vsprintf: Prevent crash when dereferencing invalid pointers

Petr Mladek
2018-03-16T08:56:01Z

On Fri 2018-03-16 14:53:46, Sergey Senozhatsky wrote:
> On (03/15/18 18:35), Linus Torvalds wrote:
> > On Thu, Mar 15, 2018 at 6:18 PM, Sergey Senozhatsky
> > <sergey.senozhatsky.work@gmail.com> wrote:
> > >
> > > Hm, may be sizeof(ptr) still won't suffice. It would be great if we
> > > could always look at spec.field_width, which can be up to 2 * sizeof(void *),
> > > and then just probe_kernel_read(spec.field_width). E.g., %b/%bl prints out a
> > > bitmap, accessing max_t(int, spec.field_width, 0) bits, which is good. But,
> > > for instance, %U (uuid printout) doesn't look at spec.field_width, and reads
> > > in 16 bytes from the given memory address. Then we have ipv4/ipv6, mac, etc.
> > > So I think that checking just 1 byte or sizeof(ptr) is not really enough if
> > > we want to fix vsprintf. What do you think?
> >
> > Honestly, I think it would be better to move the whole logic to the
> > functions that actually do the printout.
>
> > Would it be a few more lines? Yes. But it would also clarify the code
> > and get all the cases right. Look at hex_string() for example, and
> > imagine fetching a byte at a time and just getting the corner cases
> > automatically right.

I am learning every day. I like this idea and am happy that
it is acceptable to others.

> So, basically, what I tried to say - any byte past the first sizeof(ptr)
> bytes or past the first byte that we check_access() can cause problems,
> which this patch is trying to address. As an example, FORMAT_TYPE_STR
> case
>
> printk("%.*s\n", p->buf)
> vsnprintf()
> string()
>
> Where ->buf is a _nearly always_ properly nul terminated char buf[128]
> array in struct foo. So moving that check_access() to every function that
> does printout sounds good to me, as well as checking every byte we access
> [assuming that we want to cure vsprintf], not just the first one or the
> first sizeof(ptr) bytes.

I am not sure if it is worth it. I think that we would catch 99% of
problems by checking the first byte.

This patch was motivated by a code clean up rather than bug reports.
The original patch removed two more strict checks and kept only
the check for pure NULL. I suggested that it was the wrong way to
go...

I do not want to go suddenly to the other extreme. I suggest to start
with simple check for the first byte and see how often it helps
in the real life. We could always extend it later.

Best Regards,
Petr