diff options
author | Andrey Ryabinin <aryabinin@virtuozzo.com> | 2016-01-20 18:00:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-20 20:09:18 -0500 |
commit | c6d308534aef6c99904bf5862066360ae067abc4 (patch) | |
tree | 0c3b9cabd10101dea1c6433f76835c17c538d5fe /lib/ubsan.h | |
parent | 68920c973254c5b71a684645c5f6f82d6732c5d6 (diff) |
UBSAN: run-time undefined behavior sanity checker
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 has this capability since 4.9.x [1] (see -fsanitize=undefined
option and its suboptions).
However GCC 5.x has more checkers implemented [2].
Article [3] has a bit more details about UBSAN in the GCC.
[1] - https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Debugging-Options.html
[2] - https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
[3] - http://developerblog.redhat.com/2014/10/16/gcc-undefined-behavior-sanitizer-ubsan/
Issues which UBSAN has found thus far are:
Found bugs:
* out-of-bounds access - 97840cb67ff5 ("netfilter: nfnetlink: fix
insufficient validation in nfnetlink_bind")
undefined shifts:
* d48458d4a768 ("jbd2: use a better hash function for the revoke
table")
* 10632008b9e1 ("clockevents: Prevent shift out of bounds")
* 'x << -1' shift in ext4 -
http://lkml.kernel.org/r/<5444EF21.8020501@samsung.com>
* undefined rol32(0) -
http://lkml.kernel.org/r/<1449198241-20654-1-git-send-email-sasha.levin@oracle.com>
* undefined dirty_ratelimit calculation -
http://lkml.kernel.org/r/<566594E2.3050306@odin.com>
* undefined roundown_pow_of_two(0) -
http://lkml.kernel.org/r/<1449156616-11474-1-git-send-email-sasha.levin@oracle.com>
* [WONTFIX] undefined shift in __bpf_prog_run -
http://lkml.kernel.org/r/<CACT4Y+ZxoR3UjLgcNdUm4fECLMx2VdtfrENMtRRCdgHB2n0bJA@mail.gmail.com>
WONTFIX here because it should be fixed in bpf program, not in kernel.
signed overflows:
* 32a8df4e0b33f ("sched: Fix odd values in effective_load()
calculations")
* mul overflow in ntp -
http://lkml.kernel.org/r/<1449175608-1146-1-git-send-email-sasha.levin@oracle.com>
* incorrect conversion into rtc_time in rtc_time64_to_tm() -
http://lkml.kernel.org/r/<1449187944-11730-1-git-send-email-sasha.levin@oracle.com>
* unvalidated timespec in io_getevents() -
http://lkml.kernel.org/r/<CACT4Y+bBxVYLQ6LtOKrKtnLthqLHcw-BMp3aqP3mjdAvr9FULQ@mail.gmail.com>
* [NOTABUG] signed overflow in ktime_add_safe() -
http://lkml.kernel.org/r/<CACT4Y+aJ4muRnWxsUe1CMnA6P8nooO33kwG-c8YZg=0Xc8rJqw@mail.gmail.com>
[akpm@linux-foundation.org: fix unused local warning]
[akpm@linux-foundation.org: fix __int128 build woes]
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sasha Levin <sasha.levin@oracle.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Michal Marek <mmarek@suse.cz>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Yury Gribov <y.gribov@samsung.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Konstantin Khlebnikov <koct9i@gmail.com>
Cc: Kostya Serebryany <kcc@google.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/ubsan.h')
-rw-r--r-- | lib/ubsan.h | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/lib/ubsan.h b/lib/ubsan.h new file mode 100644 index 000000000000..b2d18d4a53f5 --- /dev/null +++ b/lib/ubsan.h | |||
@@ -0,0 +1,84 @@ | |||
1 | #ifndef _LIB_UBSAN_H | ||
2 | #define _LIB_UBSAN_H | ||
3 | |||
4 | enum { | ||
5 | type_kind_int = 0, | ||
6 | type_kind_float = 1, | ||
7 | type_unknown = 0xffff | ||
8 | }; | ||
9 | |||
10 | struct type_descriptor { | ||
11 | u16 type_kind; | ||
12 | u16 type_info; | ||
13 | char type_name[1]; | ||
14 | }; | ||
15 | |||
16 | struct source_location { | ||
17 | const char *file_name; | ||
18 | union { | ||
19 | unsigned long reported; | ||
20 | struct { | ||
21 | u32 line; | ||
22 | u32 column; | ||
23 | }; | ||
24 | }; | ||
25 | }; | ||
26 | |||
27 | struct overflow_data { | ||
28 | struct source_location location; | ||
29 | struct type_descriptor *type; | ||
30 | }; | ||
31 | |||
32 | struct type_mismatch_data { | ||
33 | struct source_location location; | ||
34 | struct type_descriptor *type; | ||
35 | unsigned long alignment; | ||
36 | unsigned char type_check_kind; | ||
37 | }; | ||
38 | |||
39 | struct nonnull_arg_data { | ||
40 | struct source_location location; | ||
41 | struct source_location attr_location; | ||
42 | int arg_index; | ||
43 | }; | ||
44 | |||
45 | struct nonnull_return_data { | ||
46 | struct source_location location; | ||
47 | struct source_location attr_location; | ||
48 | }; | ||
49 | |||
50 | struct vla_bound_data { | ||
51 | struct source_location location; | ||
52 | struct type_descriptor *type; | ||
53 | }; | ||
54 | |||
55 | struct out_of_bounds_data { | ||
56 | struct source_location location; | ||
57 | struct type_descriptor *array_type; | ||
58 | struct type_descriptor *index_type; | ||
59 | }; | ||
60 | |||
61 | struct shift_out_of_bounds_data { | ||
62 | struct source_location location; | ||
63 | struct type_descriptor *lhs_type; | ||
64 | struct type_descriptor *rhs_type; | ||
65 | }; | ||
66 | |||
67 | struct unreachable_data { | ||
68 | struct source_location location; | ||
69 | }; | ||
70 | |||
71 | struct invalid_value_data { | ||
72 | struct source_location location; | ||
73 | struct type_descriptor *type; | ||
74 | }; | ||
75 | |||
76 | #if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__) | ||
77 | typedef __int128 s_max; | ||
78 | typedef unsigned __int128 u_max; | ||
79 | #else | ||
80 | typedef s64 s_max; | ||
81 | typedef u64 u_max; | ||
82 | #endif | ||
83 | |||
84 | #endif | ||