Back to home page

LXR

 
 

    


0001 /*
0002  * UBSAN error reporting functions
0003  *
0004  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
0005  * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
0006  *
0007  * This program is free software; you can redistribute it and/or modify
0008  * it under the terms of the GNU General Public License version 2 as
0009  * published by the Free Software Foundation.
0010  *
0011  */
0012 
0013 #include <linux/bitops.h>
0014 #include <linux/bug.h>
0015 #include <linux/ctype.h>
0016 #include <linux/init.h>
0017 #include <linux/kernel.h>
0018 #include <linux/types.h>
0019 #include <linux/sched.h>
0020 
0021 #include "ubsan.h"
0022 
0023 const char *type_check_kinds[] = {
0024     "load of",
0025     "store to",
0026     "reference binding to",
0027     "member access within",
0028     "member call on",
0029     "constructor call on",
0030     "downcast of",
0031     "downcast of"
0032 };
0033 
0034 #define REPORTED_BIT 31
0035 
0036 #if (BITS_PER_LONG == 64) && defined(__BIG_ENDIAN)
0037 #define COLUMN_MASK (~(1U << REPORTED_BIT))
0038 #define LINE_MASK   (~0U)
0039 #else
0040 #define COLUMN_MASK   (~0U)
0041 #define LINE_MASK (~(1U << REPORTED_BIT))
0042 #endif
0043 
0044 #define VALUE_LENGTH 40
0045 
0046 static bool was_reported(struct source_location *location)
0047 {
0048     return test_and_set_bit(REPORTED_BIT, &location->reported);
0049 }
0050 
0051 static void print_source_location(const char *prefix,
0052                 struct source_location *loc)
0053 {
0054     pr_err("%s %s:%d:%d\n", prefix, loc->file_name,
0055         loc->line & LINE_MASK, loc->column & COLUMN_MASK);
0056 }
0057 
0058 static bool suppress_report(struct source_location *loc)
0059 {
0060     return current->in_ubsan || was_reported(loc);
0061 }
0062 
0063 static bool type_is_int(struct type_descriptor *type)
0064 {
0065     return type->type_kind == type_kind_int;
0066 }
0067 
0068 static bool type_is_signed(struct type_descriptor *type)
0069 {
0070     WARN_ON(!type_is_int(type));
0071     return  type->type_info & 1;
0072 }
0073 
0074 static unsigned type_bit_width(struct type_descriptor *type)
0075 {
0076     return 1 << (type->type_info >> 1);
0077 }
0078 
0079 static bool is_inline_int(struct type_descriptor *type)
0080 {
0081     unsigned inline_bits = sizeof(unsigned long)*8;
0082     unsigned bits = type_bit_width(type);
0083 
0084     WARN_ON(!type_is_int(type));
0085 
0086     return bits <= inline_bits;
0087 }
0088 
0089 static s_max get_signed_val(struct type_descriptor *type, unsigned long val)
0090 {
0091     if (is_inline_int(type)) {
0092         unsigned extra_bits = sizeof(s_max)*8 - type_bit_width(type);
0093         return ((s_max)val) << extra_bits >> extra_bits;
0094     }
0095 
0096     if (type_bit_width(type) == 64)
0097         return *(s64 *)val;
0098 
0099     return *(s_max *)val;
0100 }
0101 
0102 static bool val_is_negative(struct type_descriptor *type, unsigned long val)
0103 {
0104     return type_is_signed(type) && get_signed_val(type, val) < 0;
0105 }
0106 
0107 static u_max get_unsigned_val(struct type_descriptor *type, unsigned long val)
0108 {
0109     if (is_inline_int(type))
0110         return val;
0111 
0112     if (type_bit_width(type) == 64)
0113         return *(u64 *)val;
0114 
0115     return *(u_max *)val;
0116 }
0117 
0118 static void val_to_string(char *str, size_t size, struct type_descriptor *type,
0119     unsigned long value)
0120 {
0121     if (type_is_int(type)) {
0122         if (type_bit_width(type) == 128) {
0123 #if defined(CONFIG_ARCH_SUPPORTS_INT128) && defined(__SIZEOF_INT128__)
0124             u_max val = get_unsigned_val(type, value);
0125 
0126             scnprintf(str, size, "0x%08x%08x%08x%08x",
0127                 (u32)(val >> 96),
0128                 (u32)(val >> 64),
0129                 (u32)(val >> 32),
0130                 (u32)(val));
0131 #else
0132             WARN_ON(1);
0133 #endif
0134         } else if (type_is_signed(type)) {
0135             scnprintf(str, size, "%lld",
0136                 (s64)get_signed_val(type, value));
0137         } else {
0138             scnprintf(str, size, "%llu",
0139                 (u64)get_unsigned_val(type, value));
0140         }
0141     }
0142 }
0143 
0144 static bool location_is_valid(struct source_location *loc)
0145 {
0146     return loc->file_name != NULL;
0147 }
0148 
0149 static DEFINE_SPINLOCK(report_lock);
0150 
0151 static void ubsan_prologue(struct source_location *location,
0152             unsigned long *flags)
0153 {
0154     current->in_ubsan++;
0155     spin_lock_irqsave(&report_lock, *flags);
0156 
0157     pr_err("========================================"
0158         "========================================\n");
0159     print_source_location("UBSAN: Undefined behaviour in", location);
0160 }
0161 
0162 static void ubsan_epilogue(unsigned long *flags)
0163 {
0164     dump_stack();
0165     pr_err("========================================"
0166         "========================================\n");
0167     spin_unlock_irqrestore(&report_lock, *flags);
0168     current->in_ubsan--;
0169 }
0170 
0171 static void handle_overflow(struct overflow_data *data, unsigned long lhs,
0172             unsigned long rhs, char op)
0173 {
0174 
0175     struct type_descriptor *type = data->type;
0176     unsigned long flags;
0177     char lhs_val_str[VALUE_LENGTH];
0178     char rhs_val_str[VALUE_LENGTH];
0179 
0180     if (suppress_report(&data->location))
0181         return;
0182 
0183     ubsan_prologue(&data->location, &flags);
0184 
0185     val_to_string(lhs_val_str, sizeof(lhs_val_str), type, lhs);
0186     val_to_string(rhs_val_str, sizeof(rhs_val_str), type, rhs);
0187     pr_err("%s integer overflow:\n",
0188         type_is_signed(type) ? "signed" : "unsigned");
0189     pr_err("%s %c %s cannot be represented in type %s\n",
0190         lhs_val_str,
0191         op,
0192         rhs_val_str,
0193         type->type_name);
0194 
0195     ubsan_epilogue(&flags);
0196 }
0197 
0198 void __ubsan_handle_add_overflow(struct overflow_data *data,
0199                 unsigned long lhs,
0200                 unsigned long rhs)
0201 {
0202 
0203     handle_overflow(data, lhs, rhs, '+');
0204 }
0205 EXPORT_SYMBOL(__ubsan_handle_add_overflow);
0206 
0207 void __ubsan_handle_sub_overflow(struct overflow_data *data,
0208                 unsigned long lhs,
0209                 unsigned long rhs)
0210 {
0211     handle_overflow(data, lhs, rhs, '-');
0212 }
0213 EXPORT_SYMBOL(__ubsan_handle_sub_overflow);
0214 
0215 void __ubsan_handle_mul_overflow(struct overflow_data *data,
0216                 unsigned long lhs,
0217                 unsigned long rhs)
0218 {
0219     handle_overflow(data, lhs, rhs, '*');
0220 }
0221 EXPORT_SYMBOL(__ubsan_handle_mul_overflow);
0222 
0223 void __ubsan_handle_negate_overflow(struct overflow_data *data,
0224                 unsigned long old_val)
0225 {
0226     unsigned long flags;
0227     char old_val_str[VALUE_LENGTH];
0228 
0229     if (suppress_report(&data->location))
0230         return;
0231 
0232     ubsan_prologue(&data->location, &flags);
0233 
0234     val_to_string(old_val_str, sizeof(old_val_str), data->type, old_val);
0235 
0236     pr_err("negation of %s cannot be represented in type %s:\n",
0237         old_val_str, data->type->type_name);
0238 
0239     ubsan_epilogue(&flags);
0240 }
0241 EXPORT_SYMBOL(__ubsan_handle_negate_overflow);
0242 
0243 
0244 void __ubsan_handle_divrem_overflow(struct overflow_data *data,
0245                 unsigned long lhs,
0246                 unsigned long rhs)
0247 {
0248     unsigned long flags;
0249     char rhs_val_str[VALUE_LENGTH];
0250 
0251     if (suppress_report(&data->location))
0252         return;
0253 
0254     ubsan_prologue(&data->location, &flags);
0255 
0256     val_to_string(rhs_val_str, sizeof(rhs_val_str), data->type, rhs);
0257 
0258     if (type_is_signed(data->type) && get_signed_val(data->type, rhs) == -1)
0259         pr_err("division of %s by -1 cannot be represented in type %s\n",
0260             rhs_val_str, data->type->type_name);
0261     else
0262         pr_err("division by zero\n");
0263 
0264     ubsan_epilogue(&flags);
0265 }
0266 EXPORT_SYMBOL(__ubsan_handle_divrem_overflow);
0267 
0268 static void handle_null_ptr_deref(struct type_mismatch_data *data)
0269 {
0270     unsigned long flags;
0271 
0272     if (suppress_report(&data->location))
0273         return;
0274 
0275     ubsan_prologue(&data->location, &flags);
0276 
0277     pr_err("%s null pointer of type %s\n",
0278         type_check_kinds[data->type_check_kind],
0279         data->type->type_name);
0280 
0281     ubsan_epilogue(&flags);
0282 }
0283 
0284 static void handle_missaligned_access(struct type_mismatch_data *data,
0285                 unsigned long ptr)
0286 {
0287     unsigned long flags;
0288 
0289     if (suppress_report(&data->location))
0290         return;
0291 
0292     ubsan_prologue(&data->location, &flags);
0293 
0294     pr_err("%s misaligned address %p for type %s\n",
0295         type_check_kinds[data->type_check_kind],
0296         (void *)ptr, data->type->type_name);
0297     pr_err("which requires %ld byte alignment\n", data->alignment);
0298 
0299     ubsan_epilogue(&flags);
0300 }
0301 
0302 static void handle_object_size_mismatch(struct type_mismatch_data *data,
0303                     unsigned long ptr)
0304 {
0305     unsigned long flags;
0306 
0307     if (suppress_report(&data->location))
0308         return;
0309 
0310     ubsan_prologue(&data->location, &flags);
0311     pr_err("%s address %p with insufficient space\n",
0312         type_check_kinds[data->type_check_kind],
0313         (void *) ptr);
0314     pr_err("for an object of type %s\n", data->type->type_name);
0315     ubsan_epilogue(&flags);
0316 }
0317 
0318 void __ubsan_handle_type_mismatch(struct type_mismatch_data *data,
0319                 unsigned long ptr)
0320 {
0321 
0322     if (!ptr)
0323         handle_null_ptr_deref(data);
0324     else if (data->alignment && !IS_ALIGNED(ptr, data->alignment))
0325         handle_missaligned_access(data, ptr);
0326     else
0327         handle_object_size_mismatch(data, ptr);
0328 }
0329 EXPORT_SYMBOL(__ubsan_handle_type_mismatch);
0330 
0331 void __ubsan_handle_nonnull_return(struct nonnull_return_data *data)
0332 {
0333     unsigned long flags;
0334 
0335     if (suppress_report(&data->location))
0336         return;
0337 
0338     ubsan_prologue(&data->location, &flags);
0339 
0340     pr_err("null pointer returned from function declared to never return null\n");
0341 
0342     if (location_is_valid(&data->attr_location))
0343         print_source_location("returns_nonnull attribute specified in",
0344                 &data->attr_location);
0345 
0346     ubsan_epilogue(&flags);
0347 }
0348 EXPORT_SYMBOL(__ubsan_handle_nonnull_return);
0349 
0350 void __ubsan_handle_vla_bound_not_positive(struct vla_bound_data *data,
0351                     unsigned long bound)
0352 {
0353     unsigned long flags;
0354     char bound_str[VALUE_LENGTH];
0355 
0356     if (suppress_report(&data->location))
0357         return;
0358 
0359     ubsan_prologue(&data->location, &flags);
0360 
0361     val_to_string(bound_str, sizeof(bound_str), data->type, bound);
0362     pr_err("variable length array bound value %s <= 0\n", bound_str);
0363 
0364     ubsan_epilogue(&flags);
0365 }
0366 EXPORT_SYMBOL(__ubsan_handle_vla_bound_not_positive);
0367 
0368 void __ubsan_handle_out_of_bounds(struct out_of_bounds_data *data,
0369                 unsigned long index)
0370 {
0371     unsigned long flags;
0372     char index_str[VALUE_LENGTH];
0373 
0374     if (suppress_report(&data->location))
0375         return;
0376 
0377     ubsan_prologue(&data->location, &flags);
0378 
0379     val_to_string(index_str, sizeof(index_str), data->index_type, index);
0380     pr_err("index %s is out of range for type %s\n", index_str,
0381         data->array_type->type_name);
0382     ubsan_epilogue(&flags);
0383 }
0384 EXPORT_SYMBOL(__ubsan_handle_out_of_bounds);
0385 
0386 void __ubsan_handle_shift_out_of_bounds(struct shift_out_of_bounds_data *data,
0387                     unsigned long lhs, unsigned long rhs)
0388 {
0389     unsigned long flags;
0390     struct type_descriptor *rhs_type = data->rhs_type;
0391     struct type_descriptor *lhs_type = data->lhs_type;
0392     char rhs_str[VALUE_LENGTH];
0393     char lhs_str[VALUE_LENGTH];
0394 
0395     if (suppress_report(&data->location))
0396         return;
0397 
0398     ubsan_prologue(&data->location, &flags);
0399 
0400     val_to_string(rhs_str, sizeof(rhs_str), rhs_type, rhs);
0401     val_to_string(lhs_str, sizeof(lhs_str), lhs_type, lhs);
0402 
0403     if (val_is_negative(rhs_type, rhs))
0404         pr_err("shift exponent %s is negative\n", rhs_str);
0405 
0406     else if (get_unsigned_val(rhs_type, rhs) >=
0407         type_bit_width(lhs_type))
0408         pr_err("shift exponent %s is too large for %u-bit type %s\n",
0409             rhs_str,
0410             type_bit_width(lhs_type),
0411             lhs_type->type_name);
0412     else if (val_is_negative(lhs_type, lhs))
0413         pr_err("left shift of negative value %s\n",
0414             lhs_str);
0415     else
0416         pr_err("left shift of %s by %s places cannot be"
0417             " represented in type %s\n",
0418             lhs_str, rhs_str,
0419             lhs_type->type_name);
0420 
0421     ubsan_epilogue(&flags);
0422 }
0423 EXPORT_SYMBOL(__ubsan_handle_shift_out_of_bounds);
0424 
0425 
0426 void __noreturn
0427 __ubsan_handle_builtin_unreachable(struct unreachable_data *data)
0428 {
0429     unsigned long flags;
0430 
0431     ubsan_prologue(&data->location, &flags);
0432     pr_err("calling __builtin_unreachable()\n");
0433     ubsan_epilogue(&flags);
0434     panic("can't return from __builtin_unreachable()");
0435 }
0436 EXPORT_SYMBOL(__ubsan_handle_builtin_unreachable);
0437 
0438 void __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
0439                 unsigned long val)
0440 {
0441     unsigned long flags;
0442     char val_str[VALUE_LENGTH];
0443 
0444     if (suppress_report(&data->location))
0445         return;
0446 
0447     ubsan_prologue(&data->location, &flags);
0448 
0449     val_to_string(val_str, sizeof(val_str), data->type, val);
0450 
0451     pr_err("load of value %s is not a valid value for type %s\n",
0452         val_str, data->type->type_name);
0453 
0454     ubsan_epilogue(&flags);
0455 }
0456 EXPORT_SYMBOL(__ubsan_handle_load_invalid_value);