#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/ctype.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/ubsan.h>
#include <kunit/test-bug.h>
#include "ubsan.h"
#ifdef CONFIG_UBSAN_TRAP
const char *report_ubsan_failure(struct pt_regs *regs, u32 check_type)
{
switch (check_type) {
#ifdef CONFIG_UBSAN_BOUNDS
case ubsan_out_of_bounds:
return "UBSAN: array index out of bounds";
#endif
#ifdef CONFIG_UBSAN_SHIFT
case ubsan_shift_out_of_bounds:
return "UBSAN: shift out of bounds";
#endif
#if defined(CONFIG_UBSAN_DIV_ZERO) || defined(CONFIG_UBSAN_SIGNED_WRAP)
case ubsan_divrem_overflow:
return "UBSAN: divide/remainder overflow";
#endif
#ifdef CONFIG_UBSAN_UNREACHABLE
case ubsan_builtin_unreachable:
return "UBSAN: unreachable code";
#endif
#if defined(CONFIG_UBSAN_BOOL) || defined(CONFIG_UBSAN_ENUM)
case ubsan_load_invalid_value:
return "UBSAN: loading invalid value";
#endif
#ifdef CONFIG_UBSAN_ALIGNMENT
case ubsan_alignment_assumption:
return "UBSAN: alignment assumption";
case ubsan_type_mismatch:
return "UBSAN: type mismatch";
#endif
#ifdef CONFIG_UBSAN_SIGNED_WRAP
case ubsan_add_overflow:
return "UBSAN: integer addition overflow";
case ubsan_sub_overflow:
return "UBSAN: integer subtraction overflow";
case ubsan_mul_overflow:
return "UBSAN: integer multiplication overflow";
#endif
default:
return "UBSAN: unrecognized failure code";
}
}
#else
static const char * const type_check_kinds[] = …;
#define REPORTED_BIT …
#if (BITS_PER_LONG == 64) && defined(__BIG_ENDIAN)
#define COLUMN_MASK …
#define LINE_MASK …
#else
#define COLUMN_MASK …
#define LINE_MASK …
#endif
#define VALUE_LENGTH …
static bool was_reported(struct source_location *location)
{ … }
static bool suppress_report(struct source_location *loc)
{ … }
static bool type_is_int(struct type_descriptor *type)
{ … }
static bool type_is_signed(struct type_descriptor *type)
{ … }
static unsigned type_bit_width(struct type_descriptor *type)
{ … }
static bool is_inline_int(struct type_descriptor *type)
{ … }
static s_max get_signed_val(struct type_descriptor *type, void *val)
{ … }
static bool val_is_negative(struct type_descriptor *type, void *val)
{ … }
static u_max get_unsigned_val(struct type_descriptor *type, void *val)
{ … }
static void val_to_string(char *str, size_t size, struct type_descriptor *type,
void *value)
{ … }
static void ubsan_prologue(struct source_location *loc, const char *reason)
{ … }
static void ubsan_epilogue(void)
{ … }
static void handle_overflow(struct overflow_data *data, void *lhs,
void *rhs, char op)
{ … }
void __ubsan_handle_add_overflow(void *data,
void *lhs, void *rhs)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_sub_overflow(void *data,
void *lhs, void *rhs)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_mul_overflow(void *data,
void *lhs, void *rhs)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_negate_overflow(void *_data, void *old_val)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
{ … }
EXPORT_SYMBOL(…);
static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
{ … }
static void handle_misaligned_access(struct type_mismatch_data_common *data,
unsigned long ptr)
{ … }
static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
unsigned long ptr)
{ … }
static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
unsigned long ptr)
{ … }
void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
void *ptr)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_out_of_bounds(void *_data, void *index)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_builtin_unreachable(void *_data)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_load_invalid_value(void *_data, void *val)
{ … }
EXPORT_SYMBOL(…);
void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
unsigned long align,
unsigned long offset)
{ … }
EXPORT_SYMBOL(…);
#endif