mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Sasha Levin <sasha.levin@oracle.com>
To: Andrey Ryabinin <a.ryabinin@samsung.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Michal Marek <mmarek@suse.cz>,
	x86@kernel.org, linux-kbuild@vger.kernel.org,
	linux-kernel@vger.kernel.org
Cc: "Theodore Ts'o" <tytso@mit.edu>,
	Andreas Dilger <adilger.kernel@dilger.ca>,
	Dmitry Vyukov <dvyukov@google.com>,
	Konstantin Khlebnikov <koct9i@gmail.com>
Subject: Re: [RFC PATCH] UBSan: run-time undefined behavior sanity checker
Date: Mon, 20 Oct 2014 15:35:43 -0400	[thread overview]
Message-ID: <5445640F.10000@oracle.com> (raw)
In-Reply-To: <1413802499-17928-2-git-send-email-a.ryabinin@samsung.com>

On 10/20/2014 06:54 AM, Andrey Ryabinin wrote:
> 
> UBSan uses compile-time instrumentation to catch undefined behavior (UB).
> Compiler inserts code that perform certain kinds of
> checks before operations that could cause UB.
> If check fails (i.e. UB detected) __ubsan_handle_* function called.
> to print error message.
> 
> So the most of the work is done by compiler.
> This patch just implements ubsan handlers printing errors.
> 
> GCC supports this since 4.9, however upcoming GCC 5.0 has
> more checkers implemented.
> 
> Different kinds of checks could be enabled via boot parameter:
> ubsan_handle=OEAINVBSLF.
> If ubsan_handle not present in cmdline default options are used: ELNVBSLF
> 
> 	O - different kinds of overflows
> 	E - negation overflow, division overflow, division by zero.
> 	A - misaligned memory access.
> 	I - load from/store to an object with insufficient space.
> 	N - null argument declared with nonnull attribute,
> 	  returned null from function which never returns null, null ptr dereference.
> 	V - variable size array with non-positive length
> 	B - out-of-bounds accesses.
> 	S - shifting out-of-bounds.
> 	L - load of invalid value (value out of range for the enum type, loading other then 0/1 to bool type)
> 	F - call to function through pointer with incorrect function type
> 	    (AFAIK this is not implemented in gcc yet, probably works with clang, though
> 	    	   I didn't check ubsan with clang at all).
> 
> Instrumentation in kernel/printk/printk.c is disabled because struct printk_log is not properly aligned,
> therefore we are recursively taking logbuf_lock while trying to print error in __ubsan_handle*().
> 
> Signed-off-by: Andrey Ryabinin <a.ryabinin@samsung.com>
> ---
>  Makefile                              |  12 +-
>  arch/x86/Kconfig                      |   1 +
>  arch/x86/boot/Makefile                |   1 +
>  arch/x86/boot/compressed/Makefile     |   1 +
>  arch/x86/realmode/rm/Makefile         |   1 +
>  arch/x86/vdso/Makefile                |   2 +
>  drivers/firmware/efi/libstub/Makefile |   1 +
>  include/linux/sched.h                 |   4 +
>  kernel/printk/Makefile                |   1 +
>  lib/Kconfig.debug                     |  23 ++
>  lib/Makefile                          |   3 +
>  lib/ubsan.c                           | 559 ++++++++++++++++++++++++++++++++++
>  lib/ubsan.h                           |  84 +++++
>  scripts/Makefile.lib                  |   6 +
>  14 files changed, 698 insertions(+), 1 deletion(-)
>  create mode 100644 lib/ubsan.c
>  create mode 100644 lib/ubsan.h
> 
> diff --git a/Makefile b/Makefile
> index 05d67af..d3e23f9 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -377,6 +377,9 @@ LDFLAGS_MODULE  =
>  CFLAGS_KERNEL	=
>  AFLAGS_KERNEL	=
>  CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage
> +CFLAGS_UBSAN	= $(call cc-option, -fsanitize=undefined) \
> +			$(call cc-option, -fno-sanitize=unreachable) \
> +			$(call cc-option, -fno-sanitize=float-cast-overflow)

What's the reason behind those two -fno-sanitize?

[snip]

> +config HAVE_ARCH_UBSAN_SANTIZE_ALL
> +	bool
> +
> +config UBSAN
> +	bool "Undefined behaviour sanity checker"
> +	help
> +	  This option enables undefined behaviour sanity checker
> +	  Compile-time instrumentataion used to detect various undefined
		       instrumentation
> +	  behaviours in runtime. Different kinds of checks could be enabled
> +	  via boot parameter ubsan_handle (see: Documentation/ubsan.txt).
> +	  (TODO: write docs).
> +
> +config UBSAN_SANITIZE_ALL
> +	bool "Enable instrumentation for the entire kernel"
> +	depends on UBSAN
> +	depends on HAVE_ARCH_UBSAN_SANTIZE_ALL
> +	default y
> +	help
> +	  This option acitivates instrumentation for the entire kernel.
                      activates
> +	  If you don't enable this option, you have to explicitly specify
> +	  UBSAN_SANITIZE := y for the files/directories you want to check for UB.
> +
> +
[snip

> +/* By default enable everything except signed overflows and
> + * misaligned accesses
> + */

Why those two are disabled? Maybe we should be fixing them rather
than ignoring?

> +static unsigned long ubsan_handle = GENMASK(HANDLERS_END, 0) &
> +	~(BIT_MASK(SUM_OVERFLOW) | BIT_MASK(SUB_OVERFLOW) |
> +		BIT_MASK(NEG_OVERFLOW) | BIT_MASK(ALIGNMENT));
> +
> +static void enable_handler(unsigned int handler)
> +{
> +	set_bit(handler, &ubsan_handle);
> +}
> +
> +static bool handler_enabled(unsigned int handler)
> +{
> +	return test_bit(handler, &ubsan_handle);
> +}
> +
> +#define REPORTED_BIT 31
> +#define COLUMN_MASK (~(1U << REPORTED_BIT))
> +
> +static bool is_disabled(struct source_location *location)
> +{
> +	return test_and_set_bit(REPORTED_BIT,
> +				(unsigned long *)&location->column);
> +}
> +
> +static void print_source_location(const char *prefix, struct source_location *loc)
> +{
> +	pr_err("%s %s:%d:%d\n", prefix, loc->file_name,
> +		loc->line, loc->column & COLUMN_MASK);
> +}
> +
> +static bool type_is_int(struct type_descriptor *type)
> +{
> +	return type->type_kind == type_kind_int;
> +}
> +
> +static bool type_is_signed(struct type_descriptor *type)
> +{
> +	return type_is_int(type) && (type->type_info & 1);
> +}
> +
> +static unsigned type_bit_width(struct type_descriptor *type)
> +{
> +	return 1 << (type->type_info >> 1);
> +}
> +
> +static bool is_inline_int(struct type_descriptor *type)
> +{
> +	unsigned inline_bits = sizeof(unsigned long)*8;
> +	unsigned bits = type_bit_width(type);
> +

Shouldn't we check type_is_int() here as well?

> +	return bits <= inline_bits;
> +}

[snip]

> +void __ubsan_handle_negate_overflow(struct overflow_data *data,
> +				unsigned long old_val)
> +{
> +
> +	char old_val_str[60];
> +
> +	if (!handler_enabled(NEG_OVERFLOW))
> +		return;
> +
> +	if (current->in_ubsan)
> +		return;
> +
> +	if (is_disabled(&data->location))
> +		return;

This pattern of 3 if()s is repeating itself couple of times, maybe
it deserves a function of it's own?

> +	ubsan_prologue(&data->location);
> +
> +	val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);
> +
> +	pr_err("negation of %s cannot be represented in type %s:\n",
> +		old_val_str, data->type->type_name);
> +
> +	ubsan_epilogue();
> +}
> +EXPORT_SYMBOL(__ubsan_handle_negate_overflow);


Thanks,
Sasha


  reply	other threads:[~2014-10-20 19:36 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-20 10:54 [RFC] " Andrey Ryabinin
2014-10-20 10:54 ` [RFC PATCH] " Andrey Ryabinin
2014-10-20 19:35   ` Sasha Levin [this message]
2014-10-21  8:03     ` Andrey Ryabinin
2014-10-24  8:31       ` y.gribov
2014-10-24 10:36         ` Andrey Ryabinin
2014-10-21  9:47   ` Peter Zijlstra
2014-10-21 10:09     ` Andrey Ryabinin
2014-10-24 10:30       ` Peter Zijlstra
2014-10-21 17:06   ` Randy Dunlap
2014-10-22  9:58   ` Rasmus Villemoes
2014-10-22 11:16     ` Andrey Ryabinin
2014-10-20 11:03 ` drivers: random: Shift out-of-bounds in _mix_pool_bytes Andrey Ryabinin
2014-10-20 12:49   ` Theodore Ts'o
2014-10-20 13:58     ` Andrey Ryabinin
2014-10-20 14:08       ` Theodore Ts'o
2014-10-20 14:09       ` Daniel Borkmann
2014-10-20 14:13         ` Sasha Levin
2014-10-20 14:16         ` Theodore Ts'o
2014-10-20 14:42           ` Andrey Ryabinin
2014-10-24 10:01           ` Peter Zijlstra
2014-10-24 10:16             ` Andrey Ryabinin
2014-10-24 13:23             ` Sasha Levin
2014-10-24 13:42               ` Peter Zijlstra
2014-10-24 15:04                 ` Sasha Levin
2014-10-24 15:10                   ` Dmitry Vyukov
2014-10-24 21:05                     ` One Thousand Gnomes
2014-10-24 22:23                       ` H. Peter Anvin
2014-10-24 22:09                     ` Andreas Dilger
2014-10-24 22:22                       ` H. Peter Anvin
2014-10-25  0:50                         ` Sasha Levin
2014-10-25 20:30                           ` One Thousand Gnomes
2014-10-25 20:49                             ` Andrey Ryabinin
2014-10-20 11:07 ` kernel: clockevents: shift out-of-bounds Andrey Ryabinin
2014-10-24 10:25   ` Peter Zijlstra
2014-10-20 11:16 ` fs: ext4: mballoc: negative shift exponent Andrey Ryabinin
2014-10-20 11:23 ` jbd2: revoke: negative shift exponent in hash() Andrey Ryabinin

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=5445640F.10000@oracle.com \
    --to=sasha.levin@oracle.com \
    --cc=a.ryabinin@samsung.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=akpm@linux-foundation.org \
    --cc=dvyukov@google.com \
    --cc=hpa@zytor.com \
    --cc=koct9i@gmail.com \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=mmarek@suse.cz \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=tytso@mit.edu \
    --cc=x86@kernel.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

Powered by JetHome