root/lib/ubsan.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. was_reported
  2. print_source_location
  3. suppress_report
  4. type_is_int
  5. type_is_signed
  6. type_bit_width
  7. is_inline_int
  8. get_signed_val
  9. val_is_negative
  10. get_unsigned_val
  11. val_to_string
  12. ubsan_prologue
  13. ubsan_epilogue
  14. handle_overflow
  15. __ubsan_handle_add_overflow
  16. __ubsan_handle_sub_overflow
  17. __ubsan_handle_mul_overflow
  18. __ubsan_handle_negate_overflow
  19. __ubsan_handle_divrem_overflow
  20. handle_null_ptr_deref
  21. handle_misaligned_access
  22. handle_object_size_mismatch
  23. ubsan_type_mismatch_common
  24. __ubsan_handle_type_mismatch
  25. __ubsan_handle_type_mismatch_v1
  26. __ubsan_handle_out_of_bounds
  27. __ubsan_handle_shift_out_of_bounds
  28. __ubsan_handle_builtin_unreachable
  29. __ubsan_handle_load_invalid_value

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * UBSAN error reporting functions
   4  *
   5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
   6  * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
   7  */
   8 
   9 #include <linux/bitops.h>
  10 #include <linux/bug.h>
  11 #include <linux/ctype.h>
  12 #include <linux/init.h>
  13 #include <linux/kernel.h>
  14 #include <linux/types.h>
  15 #include <linux/sched.h>
  16 #include <linux/uaccess.h>
  17 
  18 #include "ubsan.h"
  19 
  20 const char *type_check_kinds[] = {
  21         "load of",
  22         "store to",
  23         "reference binding to",
  24         "member access within",
  25         "member call on",
  26         "constructor call on",
  27         "downcast of",
  28         "downcast of"
  29 };
  30 
  31 #define REPORTED_BIT 31
  32 
  33 #if (BITS_PER_LONG == 64) && defined(__BIG_ENDIAN)
  34 #define COLUMN_MASK (~(1U << REPORTED_BIT))
  35 #define LINE_MASK   (~0U)
  36 #else
  37 #define COLUMN_MASK   (~0U)
  38 #define LINE_MASK (~(1U << REPORTED_BIT))
  39 #endif
  40 
  41 #define VALUE_LENGTH 40
  42 
  43 static bool was_reported(struct source_location *location)
  44 {
  45         return test_and_set_bit(REPORTED_BIT, &location->reported);
  46 }
  47 
  48 static void print_source_location(const char *prefix,
  49                                 struct source_location *loc)
  50 {
  51         pr_err("%s %s:%d:%d\n", prefix, loc->file_name,
  52                 loc->line & LINE_MASK, loc->column & COLUMN_MASK);
  53 }
  54 
  55 static bool suppress_report(struct source_location *loc)
  56 {
  57         return current->in_ubsan || was_reported(loc);
  58 }
  59 
  60 static bool type_is_int(struct type_descriptor *type)
  61 {
  62         return type->type_kind == type_kind_int;
  63 }
  64 
  65 static bool type_is_signed(struct type_descriptor *type)
  66 {
  67         WARN_ON(!type_is_int(type));
  68         return  type->type_info & 1;
  69 }
  70 
  71 static unsigned type_bit_width(struct type_descriptor *type)
  72 {
  73         return 1 << (type->type_info >> 1);
  74 }
  75 
  76 static bool is_inline_int(struct type_descriptor *type)
  77 {
  78         unsigned inline_bits = sizeof(unsigned long)*8;
  79         unsigned bits = type_bit_width(type);
  80 
  81         WARN_ON(!type_is_int(type));
  82 
  83         return bits <= inline_bits;
  84 }
  85 
  86 static s_max get_signed_val(struct type_descriptor *type, void *val)
  87 {
  88         if (is_inline_int(type)) {
  89                 unsigned extra_bits = sizeof(s_max)*8 - type_bit_width(type);
  90                 unsigned long ulong_val = (unsigned long)val;
  91 
  92                 return ((s_max)ulong_val) << extra_bits >> extra_bits;
  93         }
  94 
  95         if (type_bit_width(type) == 64)
  96                 return *(s64 *)val;
  97 
  98         return *(s_max *)val;
  99 }
 100 
 101 static bool val_is_negative(struct type_descriptor *type, void *val)
 102 {
 103         return type_is_signed(type) && get_signed_val(type, val) < 0;
 104 }
 105 
 106 static u_max get_unsigned_val(struct type_descriptor *type, void *val)
 107 {
 108         if (is_inline_int(type))
 109                 return (unsigned long)val;
 110 
 111         if (type_bit_width(type) == 64)
 112                 return *(u64 *)val;
 113 
 114         return *(u_max *)val;
 115 }
 116 
 117 static void val_to_string(char *str, size_t size, struct type_descriptor *type,
 118                         void *value)
 119 {
 120         if (type_is_int(type)) {
 121                 if (type_bit_width(type) == 128) {
 122 #if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__)
 123                         u_max val = get_unsigned_val(type, value);
 124 
 125                         scnprintf(str, size, "0x%08x%08x%08x%08x",
 126                                 (u32)(val >> 96),
 127                                 (u32)(val >> 64),
 128                                 (u32)(val >> 32),
 129                                 (u32)(val));
 130 #else
 131                         WARN_ON(1);
 132 #endif
 133                 } else if (type_is_signed(type)) {
 134                         scnprintf(str, size, "%lld",
 135                                 (s64)get_signed_val(type, value));
 136                 } else {
 137                         scnprintf(str, size, "%llu",
 138                                 (u64)get_unsigned_val(type, value));
 139                 }
 140         }
 141 }
 142 
 143 static void ubsan_prologue(struct source_location *location)
 144 {
 145         current->in_ubsan++;
 146 
 147         pr_err("========================================"
 148                 "========================================\n");
 149         print_source_location("UBSAN: Undefined behaviour in", location);
 150 }
 151 
 152 static void ubsan_epilogue(void)
 153 {
 154         dump_stack();
 155         pr_err("========================================"
 156                 "========================================\n");
 157 
 158         current->in_ubsan--;
 159 }
 160 
 161 static void handle_overflow(struct overflow_data *data, void *lhs,
 162                         void *rhs, char op)
 163 {
 164 
 165         struct type_descriptor *type = data->type;
 166         char lhs_val_str[VALUE_LENGTH];
 167         char rhs_val_str[VALUE_LENGTH];
 168 
 169         if (suppress_report(&data->location))
 170                 return;
 171 
 172         ubsan_prologue(&data->location);
 173 
 174         val_to_string(lhs_val_str, sizeof(lhs_val_str), type, lhs);
 175         val_to_string(rhs_val_str, sizeof(rhs_val_str), type, rhs);
 176         pr_err("%s integer overflow:\n",
 177                 type_is_signed(type) ? "signed" : "unsigned");
 178         pr_err("%s %c %s cannot be represented in type %s\n",
 179                 lhs_val_str,
 180                 op,
 181                 rhs_val_str,
 182                 type->type_name);
 183 
 184         ubsan_epilogue();
 185 }
 186 
 187 void __ubsan_handle_add_overflow(struct overflow_data *data,
 188                                 void *lhs, void *rhs)
 189 {
 190 
 191         handle_overflow(data, lhs, rhs, '+');
 192 }
 193 EXPORT_SYMBOL(__ubsan_handle_add_overflow);
 194 
 195 void __ubsan_handle_sub_overflow(struct overflow_data *data,
 196                                 void *lhs, void *rhs)
 197 {
 198         handle_overflow(data, lhs, rhs, '-');
 199 }
 200 EXPORT_SYMBOL(__ubsan_handle_sub_overflow);
 201 
 202 void __ubsan_handle_mul_overflow(struct overflow_data *data,
 203                                 void *lhs, void *rhs)
 204 {
 205         handle_overflow(data, lhs, rhs, '*');
 206 }
 207 EXPORT_SYMBOL(__ubsan_handle_mul_overflow);
 208 
 209 void __ubsan_handle_negate_overflow(struct overflow_data *data,
 210                                 void *old_val)
 211 {
 212         char old_val_str[VALUE_LENGTH];
 213 
 214         if (suppress_report(&data->location))
 215                 return;
 216 
 217         ubsan_prologue(&data->location);
 218 
 219         val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);
 220 
 221         pr_err("negation of %s cannot be represented in type %s:\n",
 222                 old_val_str, data->type->type_name);
 223 
 224         ubsan_epilogue();
 225 }
 226 EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
 227 
 228 
 229 void __ubsan_handle_divrem_overflow(struct overflow_data *data,
 230                                 void *lhs, void *rhs)
 231 {
 232         char rhs_val_str[VALUE_LENGTH];
 233 
 234         if (suppress_report(&data->location))
 235                 return;
 236 
 237         ubsan_prologue(&data->location);
 238 
 239         val_to_string(rhs_val_str, sizeof(rhs_val_str), data->type, rhs);
 240 
 241         if (type_is_signed(data->type) && get_signed_val(data->type, rhs) == -1)
 242                 pr_err("division of %s by -1 cannot be represented in type %s\n",
 243                         rhs_val_str, data->type->type_name);
 244         else
 245                 pr_err("division by zero\n");
 246 
 247         ubsan_epilogue();
 248 }
 249 EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
 250 
 251 static void handle_null_ptr_deref(struct type_mismatch_data_common *data)
 252 {
 253         if (suppress_report(data->location))
 254                 return;
 255 
 256         ubsan_prologue(data->location);
 257 
 258         pr_err("%s null pointer of type %s\n",
 259                 type_check_kinds[data->type_check_kind],
 260                 data->type->type_name);
 261 
 262         ubsan_epilogue();
 263 }
 264 
 265 static void handle_misaligned_access(struct type_mismatch_data_common *data,
 266                                 unsigned long ptr)
 267 {
 268         if (suppress_report(data->location))
 269                 return;
 270 
 271         ubsan_prologue(data->location);
 272 
 273         pr_err("%s misaligned address %p for type %s\n",
 274                 type_check_kinds[data->type_check_kind],
 275                 (void *)ptr, data->type->type_name);
 276         pr_err("which requires %ld byte alignment\n", data->alignment);
 277 
 278         ubsan_epilogue();
 279 }
 280 
 281 static void handle_object_size_mismatch(struct type_mismatch_data_common *data,
 282                                         unsigned long ptr)
 283 {
 284         if (suppress_report(data->location))
 285                 return;
 286 
 287         ubsan_prologue(data->location);
 288         pr_err("%s address %p with insufficient space\n",
 289                 type_check_kinds[data->type_check_kind],
 290                 (void *) ptr);
 291         pr_err("for an object of type %s\n", data->type->type_name);
 292         ubsan_epilogue();
 293 }
 294 
 295 static void ubsan_type_mismatch_common(struct type_mismatch_data_common *data,
 296                                 unsigned long ptr)
 297 {
 298         unsigned long flags = user_access_save();
 299 
 300         if (!ptr)
 301                 handle_null_ptr_deref(data);
 302         else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
 303                 handle_misaligned_access(data, ptr);
 304         else
 305                 handle_object_size_mismatch(data, ptr);
 306 
 307         user_access_restore(flags);
 308 }
 309 
 310 void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
 311                                 void *ptr)
 312 {
 313         struct type_mismatch_data_common common_data = {
 314                 .location = &data->location,
 315                 .type = data->type,
 316                 .alignment = data->alignment,
 317                 .type_check_kind = data->type_check_kind
 318         };
 319 
 320         ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
 321 }
 322 EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
 323 
 324 void __ubsan_handle_type_mismatch_v1(struct type_mismatch_data_v1 *data,
 325                                 void *ptr)
 326 {
 327 
 328         struct type_mismatch_data_common common_data = {
 329                 .location = &data->location,
 330                 .type = data->type,
 331                 .alignment = 1UL << data->log_alignment,
 332                 .type_check_kind = data->type_check_kind
 333         };
 334 
 335         ubsan_type_mismatch_common(&common_data, (unsigned long)ptr);
 336 }
 337 EXPORT_SYMBOL(__ubsan_handle_type_mismatch_v1);
 338 
 339 void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data, void *index)
 340 {
 341         char index_str[VALUE_LENGTH];
 342 
 343         if (suppress_report(&data->location))
 344                 return;
 345 
 346         ubsan_prologue(&data->location);
 347 
 348         val_to_string(index_str, sizeof(index_str), data->index_type, index);
 349         pr_err("index %s is out of range for type %s\n", index_str,
 350                 data->array_type->type_name);
 351         ubsan_epilogue();
 352 }
 353 EXPORT_SYMBOL(__ubsan_handle_out_of_bounds);
 354 
 355 void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
 356                                         void *lhs, void *rhs)
 357 {
 358         struct type_descriptor *rhs_type = data->rhs_type;
 359         struct type_descriptor *lhs_type = data->lhs_type;
 360         char rhs_str[VALUE_LENGTH];
 361         char lhs_str[VALUE_LENGTH];
 362         unsigned long ua_flags = user_access_save();
 363 
 364         if (suppress_report(&data->location))
 365                 goto out;
 366 
 367         ubsan_prologue(&data->location);
 368 
 369         val_to_string(rhs_str, sizeof(rhs_str), rhs_type, rhs);
 370         val_to_string(lhs_str, sizeof(lhs_str), lhs_type, lhs);
 371 
 372         if (val_is_negative(rhs_type, rhs))
 373                 pr_err("shift exponent %s is negative\n", rhs_str);
 374 
 375         else if (get_unsigned_val(rhs_type, rhs) >=
 376                 type_bit_width(lhs_type))
 377                 pr_err("shift exponent %s is too large for %u-bit type %s\n",
 378                         rhs_str,
 379                         type_bit_width(lhs_type),
 380                         lhs_type->type_name);
 381         else if (val_is_negative(lhs_type, lhs))
 382                 pr_err("left shift of negative value %s\n",
 383                         lhs_str);
 384         else
 385                 pr_err("left shift of %s by %s places cannot be"
 386                         " represented in type %s\n",
 387                         lhs_str, rhs_str,
 388                         lhs_type->type_name);
 389 
 390         ubsan_epilogue();
 391 out:
 392         user_access_restore(ua_flags);
 393 }
 394 EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
 395 
 396 
 397 void __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
 398 {
 399         ubsan_prologue(&data->location);
 400         pr_err("calling __builtin_unreachable()\n");
 401         ubsan_epilogue();
 402         panic("can't return from __builtin_unreachable()");
 403 }
 404 EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
 405 
 406 void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
 407                                 void *val)
 408 {
 409         char val_str[VALUE_LENGTH];
 410 
 411         if (suppress_report(&data->location))
 412                 return;
 413 
 414         ubsan_prologue(&data->location);
 415 
 416         val_to_string(val_str, sizeof(val_str), data->type, val);
 417 
 418         pr_err("load of value %s is not a valid value for type %s\n",
 419                 val_str, data->type->type_name);
 420 
 421         ubsan_epilogue();
 422 }
 423 EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);

/* [<][>][^][v][top][bottom][index][help] */