Skip to content

Commit

Permalink
ubsan: include bug type in report header
Browse files Browse the repository at this point in the history
When syzbot tries to figure out how to deduplicate bug reports, it prefers
seeing a hint about a specific bug type (we can do better than just
"UBSAN").  This lifts the handler reason into the UBSAN report line that
includes the file path that tripped a check.  Unfortunately, UBSAN does
not provide function names.

Suggested-by: Dmitry Vyukov <[email protected]>
Signed-off-by: Kees Cook <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Cc: Alexander Potapenko <[email protected]>
Cc: Andrey Konovalov <[email protected]>
Cc: Andrey Ryabinin <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Dan Carpenter <[email protected]>
Cc: Elena Petrova <[email protected]>
Cc: "Gustavo A. R. Silva" <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Link: https://lore.kernel.org/lkml/CACT4Y+bsLJ-wFx_TaXqax3JByUOWB3uk787LsyMVcfW6JzzGvg@mail.gmail.com
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
kees authored and torvalds committed Apr 7, 2020
1 parent 1d2252f commit ef06565
Showing 1 changed file with 15 additions and 21 deletions.
36 changes: 15 additions & 21 deletions lib/ubsan.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,6 @@ static bool was_reported(struct source_location *location)
return test_and_set_bit(REPORTED_BIT, &location->reported);
}

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 & LINE_MASK, loc->column & COLUMN_MASK);
}

static bool suppress_report(struct source_location *loc)
{
return current->in_ubsan || was_reported(loc);
Expand Down Expand Up @@ -140,13 +133,14 @@ static void val_to_string(char *str, size_t size, struct type_descriptor *type,
}
}

static void ubsan_prologue(struct source_location *location)
static void ubsan_prologue(struct source_location *loc, const char *reason)
{
current->in_ubsan++;

pr_err("========================================"
"========================================\n");
print_source_location("UBSAN: Undefined behaviour in", location);
pr_err("UBSAN: %s in %s:%d:%d\n", reason, loc->file_name,
loc->line & LINE_MASK, loc->column & COLUMN_MASK);
}

static void ubsan_epilogue(void)
Expand Down Expand Up @@ -180,12 +174,12 @@ static void handle_overflow(struct overflow_data *data, void *lhs,
if (suppress_report(&data->location))
return;

ubsan_prologue(&data->location);
ubsan_prologue(&data->location, type_is_signed(type) ?
"signed-integer-overflow" :
"unsigned-integer-overflow");

val_to_string(lhs_val_str, sizeof(lhs_val_str), type, lhs);
val_to_string(rhs_val_str, sizeof(rhs_val_str), type, rhs);
pr_err("%s integer overflow:\n",
type_is_signed(type) ? "signed" : "unsigned");
pr_err("%s %c %s cannot be represented in type %s\n",
lhs_val_str,
op,
Expand Down Expand Up @@ -225,7 +219,7 @@ void __ubsan_handle_negate_overflow(struct overflow_data *data,
if (suppress_report(&data->location))
return;

ubsan_prologue(&data->location);
ubsan_prologue(&data->location, "negation-overflow");

val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);

Expand All @@ -245,7 +239,7 @@ void __ubsan_handle_divrem_overflow(struct overflow_data *data,
if (suppress_report(&data->location))
return;

ubsan_prologue(&data->location);
ubsan_prologue(&data->location, "division-overflow");

val_to_string(rhs_val_str, sizeof(rhs_val_str), data->type, rhs);

Expand All @@ -264,7 +258,7 @@ static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
if (suppress_report(data->location))
return;

ubsan_prologue(data->location);
ubsan_prologue(data->location, "null-ptr-deref");

pr_err("%s null pointer of type %s\n",
type_check_kinds[data->type_check_kind],
Expand All @@ -279,7 +273,7 @@ static void handle_misaligned_access(struct type_mismatch_data_common *data,
if (suppress_report(data->location))
return;

ubsan_prologue(data->location);
ubsan_prologue(data->location, "misaligned-access");

pr_err("%s misaligned address %p for type %s\n",
type_check_kinds[data->type_check_kind],
Expand All @@ -295,7 +289,7 @@ static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
if (suppress_report(data->location))
return;

ubsan_prologue(data->location);
ubsan_prologue(data->location, "object-size-mismatch");
pr_err("%s address %p with insufficient space\n",
type_check_kinds[data->type_check_kind],
(void *) ptr);
Expand Down Expand Up @@ -354,7 +348,7 @@ void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data, void *index)
if (suppress_report(&data->location))
return;

ubsan_prologue(&data->location);
ubsan_prologue(&data->location, "array-index-out-of-bounds");

val_to_string(index_str, sizeof(index_str), data->index_type, index);
pr_err("index %s is out of range for type %s\n", index_str,
Expand All @@ -375,7 +369,7 @@ void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
if (suppress_report(&data->location))
goto out;

ubsan_prologue(&data->location);
ubsan_prologue(&data->location, "shift-out-of-bounds");

val_to_string(rhs_str, sizeof(rhs_str), rhs_type, rhs);
val_to_string(lhs_str, sizeof(lhs_str), lhs_type, lhs);
Expand Down Expand Up @@ -407,7 +401,7 @@ EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);

void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
{
ubsan_prologue(&data->location);
ubsan_prologue(&data->location, "unreachable");
pr_err("calling __builtin_unreachable()\n");
ubsan_epilogue();
panic("can't return from __builtin_unreachable()");
Expand All @@ -422,7 +416,7 @@ void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
if (suppress_report(&data->location))
return;

ubsan_prologue(&data->location);
ubsan_prologue(&data->location, "invalid-load");

val_to_string(val_str, sizeof(val_str), data->type, val);

Expand Down

0 comments on commit ef06565

Please sign in to comment.