linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
To: Petr Mladek <pmladek@suse.com>,
	Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	Rasmus Villemoes <linux@rasmusvillemoes.dk>,
	"Tobin C . Harding" <me@tobin.cc>, Joe Perches <joe@perches.com>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Michal Hocko <mhocko@suse.cz>,
	Sergey Senozhatsky <sergey.senozhatsky@gmail.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
Subject: Re: [PATCH v3] vsprintf: Prevent crash when dereferencing invalid pointers
Date: Wed, 14 Mar 2018 23:12:36 +0100	[thread overview]
Message-ID: <0c52c2f1-60d8-bb8a-80f2-c699d47659d3@rasmusvillemoes.dk> (raw)
In-Reply-To: <20180314140947.rs3b6i5gguzzu5wi@pathway.suse.cz>

On 2018-03-14 15:09, Petr Mladek wrote:

> diff --git a/lib/test_printf.c b/lib/test_printf.c
> index 71ebfa43ad05..61c05a352d79 100644
> --- a/lib/test_printf.c
> +++ b/lib/test_printf.c
> @@ -207,14 +207,15 @@ test_string(void)
> @@ -256,18 +259,18 @@ plain_hash(void)
>   * after an address is hashed.
>   */
>  static void __init
> -plain(void)
> +plain(void *ptr)
>  {
>  	int err;
>  
> -	err = plain_hash();
> +	err = plain_hash(ptr);
>  	if (err) {
>  		pr_warn("plain 'p' does not appear to be hashed\n");
>  		failed_tests++;
>  		return;
>  	}
>  
> -	err = plain_format();
> +	err = plain_format(ptr);
>  	if (err) {
>  		pr_warn("hashing plain 'p' has unexpected format\n");
>  		failed_tests++;
> @@ -275,6 +278,24 @@ plain(void)
>  }

Thanks for adding tests. Please increment total_tests for each test case.

>  static void __init
> +null_pointer(void)
> +{
> +	plain(NULL);
> +	test(ZEROS "00000000", "%px", NULL);
> +	test(SPACE "  (null)", "%pC", NULL);
> +}

Hm, %pC depends on CONFIG_CLOCK, not that we ever reach clock() with
these invalid pointers, but perhaps clearer to choose one whose
behaviour is not config-dependent.

> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index d7a708f82559..54b985143e07 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -520,6 +520,19 @@ char *number(char *buf, char *end, unsigned long long num,
>  	return buf;
>  }
>  
> +static const char *check_pointer_access(const void *ptr)
> +{
> +	unsigned char byte;
> +
> +	if (!ptr)
> +		return "(null)";
> +
> +	if (probe_kernel_read(&byte, ptr, 1))
> +		return "(efault)";
> +
> +	return 0;
> +}

return NULL;

> +
>  static noinline_for_stack
>  char *special_hex_number(char *buf, char *end, unsigned long long num, int size)
>  {
> @@ -586,9 +599,11 @@ char *string(char *buf, char *end, const char *s, struct printf_spec spec)
>  {
>  	int len = 0;
>  	size_t lim = spec.precision;
> +	const char *err_msg;
>  
> -	if ((unsigned long)s < PAGE_SIZE)
> -		s = "(null)";
> +	err_msg = check_pointer_access(s);
> +	if (err_msg)
> +		s = err_msg;
>  
>  	while (lim--) {
>  		char c = *s++;
> @@ -1847,16 +1862,22 @@ static noinline_for_stack
>  char *pointer(const char *fmt, char *buf, char *end, void *ptr,
>  	      struct printf_spec spec)
>  {
> +	static const char data_access_fmt[] = "RrhbMmIiEUVNadCDgGO";
>  	const int default_width = 2 * sizeof(void *);
> +	const char *err_msg = NULL;
> +
> +	/* Prevent silent crash when this is called under logbuf_lock. */
> +	if (*fmt && strchr(data_access_fmt, *fmt) != NULL)
> +		err_msg = check_pointer_access(ptr);

Can we please make this more readable and maintainable in case other
fancy %p* stuff is added. The extensions which do dereference ptr
outnumber those which don't, and a new one is also likely to fall in
that category. Something like

static bool extension_dereferences_ptr(const char *fmt)
{
  switch(*fmt) {
  case 'x':
  case 'K':
  case 'F':
  case 'f':
  case 'S':
  case 's':
  case 'B':
    return false;
  default:
    return isalnum(*fmt);
  }
}

which you could spell isalnum(*fmt) && !strchr("xKFfSsB", *fmt), but
having a switch is a closer match to the subsequent dispatching (and
would allow a more fine-grained approach should the answer depend on
fmt[1] as well).

Question: probe_kernel_read seems to allow (mapped) userspace addresses.
Is that really what we want? Sure, some %p* just format the pointed-to
bytes directly (as an IP address or raw hex dump or whatnot), but some
(e.g. %pD, and %pV could be particularly fun) do another dereference.
I'm not saying it would be easy for an attacker to get a userpointer
passed to %pV, but there's a lot of places that end up calling vsnprintf
(not just printk and friends). Isn't there some cheap address comparison
one can do to rule that out completely?

Rasmus

  reply	other threads:[~2018-03-14 22:12 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-16 21:07 [PATCH v2 1/9] lib/test_printf: Mark big constant with ULL Andy Shevchenko
2018-02-16 21:07 ` [PATCH v2 2/9] lib/vsprintf: Make dec_spec global Andy Shevchenko
2018-04-11  9:44   ` Petr Mladek
2018-02-16 21:07 ` [PATCH v2 3/9] lib/vsprintf: Make strspec global Andy Shevchenko
2018-04-11  9:44   ` Petr Mladek
2018-02-16 21:07 ` [PATCH v2 4/9] lib/vsprintf: Make flag_spec global Andy Shevchenko
2018-04-11  9:45   ` Petr Mladek
2018-02-16 21:07 ` [PATCH v2 5/9] lib/vsprintf: Move pointer_string() upper Andy Shevchenko
2018-04-11  9:45   ` Petr Mladek
2018-02-16 21:07 ` [PATCH v2 6/9] lib/vsprintf: Deduplicate pointer_string() Andy Shevchenko
2018-04-11  9:46   ` Petr Mladek
2018-02-16 21:07 ` [PATCH v2 7/9] lib/vsprintf: Replace space with '_' before crng is ready Andy Shevchenko
2018-02-20  2:57   ` [此邮件可能存在风险] " Yang, Shunyong
2018-04-11  9:47   ` Petr Mladek
2018-02-16 21:07 ` [PATCH v2 8/9] lib/vsprintf: Remove useless NULL checks Andy Shevchenko
2018-02-27 15:50   ` Petr Mladek
2018-02-27 17:35     ` Andy Shevchenko
2018-02-28 10:04       ` Petr Mladek
2018-02-28 10:42         ` Andy Shevchenko
2018-03-02 12:51           ` Petr Mladek
2018-03-02 12:53             ` [PATCH] vsprintf: Make "null" pointer dereference more robust Petr Mladek
2018-03-02 14:17               ` Andy Shevchenko
2018-03-05 14:53                 ` Petr Mladek
2018-03-29 15:13                 ` Petr Mladek
2018-03-29 16:11                   ` Joe Perches
2018-03-05 15:16               ` Rasmus Villemoes
2018-03-05 15:25                 ` Andy Shevchenko
2018-03-06  9:25                 ` Petr Mladek
2018-03-06  9:56                   ` Andy Shevchenko
2018-03-07 15:52                     ` Petr Mladek
2018-03-07 18:18                       ` Andy Shevchenko
2018-03-07 18:34                       ` Linus Torvalds
2018-03-08 14:18                         ` Petr Mladek
2018-03-08 16:45                           ` Linus Torvalds
2018-03-08 17:26                             ` Linus Torvalds
2018-03-09 15:01                               ` Petr Mladek
2018-03-09 19:05                                 ` Linus Torvalds
2018-03-14 14:09                                   ` [PATCH v3] vsprintf: Prevent crash when dereferencing invalid pointers Petr Mladek
2018-03-14 22:12                                     ` Rasmus Villemoes [this message]
2018-03-15 15:07                                       ` Petr Mladek
2018-03-15 17:07                                         ` Steven Rostedt
2018-03-15 17:06                                       ` Steven Rostedt
2018-03-15  0:57                                     ` Sergey Senozhatsky
2018-03-15  7:58                                     ` Sergey Senozhatsky
2018-03-15  8:03                                       ` Sergey Senozhatsky
2018-03-15 17:01                                         ` Steven Rostedt
2018-03-16  1:18                                           ` Sergey Senozhatsky
2018-03-16  1:35                                             ` Linus Torvalds
2018-03-16  5:53                                               ` Sergey Senozhatsky
2018-03-16  8:55                                                 ` Petr Mladek
2018-03-16 14:32                                                   ` Steven Rostedt
2018-03-17  1:29                                                   ` Sergey Senozhatsky
2018-03-15 13:07                                       ` Andy Shevchenko
2018-03-15 13:09                                     ` Andy Shevchenko
2018-03-15 15:26                                       ` Petr Mladek
2018-03-16 18:19                                         ` Andy Shevchenko
2018-03-29 14:53                                           ` Petr Mladek
2018-04-02 14:15                                             ` Andy Shevchenko
2018-04-03  1:12                                               ` Sergey Senozhatsky
2018-04-03 11:52                                                 ` Petr Mladek
2018-04-03 11:56                                                   ` Andy Shevchenko
2018-04-03 13:57                                                   ` Sergey Senozhatsky
2018-04-03 11:46                                               ` Petr Mladek
2018-04-03 11:54                                                 ` Andy Shevchenko
2018-04-03 13:13                                                   ` Petr Mladek
2018-04-03 13:40                                                     ` Andy Shevchenko
2018-04-03 14:50                                                       ` Petr Mladek
2018-03-15 14:48                                     ` kbuild test robot
2018-03-15 20:26                                     ` kbuild test robot
2018-03-06 18:11                   ` [PATCH 1/2] vsprintf: distinguish between (null), (err) and (invalid) pointer derefs Adam Borowski
2018-03-06 18:11                     ` [PATCH 2/2] vsprintf: don't dereference pointers to the first or last page Adam Borowski
2018-03-07 13:22                       ` Andy Shevchenko
2018-03-07 13:17                     ` [PATCH 1/2] vsprintf: distinguish between (null), (err) and (invalid) pointer derefs Andy Shevchenko
2018-03-07 13:42                       ` Adam Borowski
2018-03-07 13:29                     ` Andy Shevchenko
2018-03-02 14:15             ` [PATCH v2 8/9] lib/vsprintf: Remove useless NULL checks Andy Shevchenko
2018-03-05 14:57               ` Petr Mladek
2018-02-28 10:44         ` Andy Shevchenko
2018-03-01 14:56         ` Andy Shevchenko
2018-02-16 21:07 ` [PATCH v2 9/9] lib/vsprintf: Mark expected switch fall-through Andy Shevchenko
2018-04-11  9:47   ` Petr Mladek
2018-02-18 12:58 ` [PATCH v2 1/9] lib/test_printf: Mark big constant with ULL Luc Van Oostenryck
2018-02-18 14:20   ` Andy Shevchenko
2018-02-19 15:24   ` Andy Shevchenko
2018-04-11  9:41     ` Petr Mladek
2018-02-18 21:52 ` Tobin C. Harding
2018-02-18 23:55   ` Andy Shevchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0c52c2f1-60d8-bb8a-80f2-c699d47659d3@rasmusvillemoes.dk \
    --to=linux@rasmusvillemoes.dk \
    --cc=akpm@linux-foundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=joe@perches.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=me@tobin.cc \
    --cc=mhocko@suse.cz \
    --cc=pmladek@suse.com \
    --cc=rostedt@goodmis.org \
    --cc=sergey.senozhatsky.work@gmail.com \
    --cc=sergey.senozhatsky@gmail.com \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).