Re: [PATCH] vsprintf: Make "null" pointer dereference more robust

Andy Shevchenko
2018-03-07T18:18:14Z

On Wed, 2018-03-07 at 16:52 +0100, Petr Mladek wrote:
> On Tue 2018-03-06 11:56:25, Andy Shevchenko wrote:

> Anyway, I have discussed this with my colleagues. Different people had
> different opinions. But I liked the following.

I discussed as well, and...

> We already prevent crash when derefencing some obviously broken
> pointers. The handling is not consistent. Sometimes we print "(null)"
> only for pure NULL pointer, sometimes for pointers in the first
> page and sometimes also for pointers in the last page (error codes).

> In general, we should do our best to get useful message from printk().
> This patch tries to find a wide range of invalid strings using
> probe_kernel_read(). Also it makes the handling unified. We print:

...they are considering not crashing is a bad idea from debugging point
of view.

So, what is can be done is to:
- print "(null)" only for null pointers
- print error codes for IS_ERR() part
- crash on everything else

which partially what does my patch 1.

> Note that we could not print the exact pointer value from security
> reasons.

If it's invalid we need to fix the code, not to hide a problem, right?

> Developers need print the pointer using %px to get the real value.

But how developer will know (w/o traceback) where to look for?

> + if (probe_kernel_read(&byte, ptr, 1))
> + return "(efault)";

There is couple of flaws here:

- If we asked to print 0 bytes of the value of pointer or something
from extension (%*ph, %*pE, etc), we don't know if pointer valid or not,
because we are going to print nothing. So, for now there is a
ZERO_OR_NULL_PTR() check for them, but in reality I wouldn't know what
the best to do in such case. So, the question is what we would like to
know more: the pointer is invalid, or the spec.width is 0 and caller
doesn't care in this case?

- For IS_ERR() case it might be better to print an actual value of err,
(4 chars + parens + 2 chars left, like (e:dddd) or similar.
Unfortunately it doesn't scale good (ffff is a last error value we may
print). So, perhaps printing as %p in this case is a good enough and
scalable.

--
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Intel Finland Oy