ubsan.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. #ifndef _LIB_UBSAN_H
  3. #define _LIB_UBSAN_H
  4. /*
  5. * ABI defined by Clang's UBSAN enum SanitizerHandler:
  6. * https://github.com/llvm/llvm-project/blob/release/16.x/clang/lib/CodeGen/CodeGenFunction.h#L113
  7. */
  8. enum ubsan_checks {
  9. ubsan_add_overflow,
  10. ubsan_builtin_unreachable,
  11. ubsan_cfi_check_fail,
  12. ubsan_divrem_overflow,
  13. ubsan_dynamic_type_cache_miss,
  14. ubsan_float_cast_overflow,
  15. ubsan_function_type_mismatch,
  16. ubsan_implicit_conversion,
  17. ubsan_invalid_builtin,
  18. ubsan_invalid_objc_cast,
  19. ubsan_load_invalid_value,
  20. ubsan_missing_return,
  21. ubsan_mul_overflow,
  22. ubsan_negate_overflow,
  23. ubsan_nullability_arg,
  24. ubsan_nullability_return,
  25. ubsan_nonnull_arg,
  26. ubsan_nonnull_return,
  27. ubsan_out_of_bounds,
  28. ubsan_pointer_overflow,
  29. ubsan_shift_out_of_bounds,
  30. ubsan_sub_overflow,
  31. ubsan_type_mismatch,
  32. ubsan_alignment_assumption,
  33. ubsan_vla_bound_not_positive,
  34. };
  35. enum {
  36. type_kind_int = 0,
  37. type_kind_float = 1,
  38. type_unknown = 0xffff
  39. };
  40. struct type_descriptor {
  41. u16 type_kind;
  42. u16 type_info;
  43. char type_name[];
  44. };
  45. struct source_location {
  46. const char *file_name;
  47. union {
  48. unsigned long reported;
  49. struct {
  50. u32 line;
  51. u32 column;
  52. };
  53. };
  54. };
  55. struct overflow_data {
  56. struct source_location location;
  57. struct type_descriptor *type;
  58. };
  59. struct type_mismatch_data {
  60. struct source_location location;
  61. struct type_descriptor *type;
  62. unsigned long alignment;
  63. unsigned char type_check_kind;
  64. };
  65. struct type_mismatch_data_v1 {
  66. struct source_location location;
  67. struct type_descriptor *type;
  68. unsigned char log_alignment;
  69. unsigned char type_check_kind;
  70. };
  71. struct type_mismatch_data_common {
  72. struct source_location *location;
  73. struct type_descriptor *type;
  74. unsigned long alignment;
  75. unsigned char type_check_kind;
  76. };
  77. struct nonnull_arg_data {
  78. struct source_location location;
  79. struct source_location attr_location;
  80. int arg_index;
  81. };
  82. struct out_of_bounds_data {
  83. struct source_location location;
  84. struct type_descriptor *array_type;
  85. struct type_descriptor *index_type;
  86. };
  87. struct shift_out_of_bounds_data {
  88. struct source_location location;
  89. struct type_descriptor *lhs_type;
  90. struct type_descriptor *rhs_type;
  91. };
  92. struct unreachable_data {
  93. struct source_location location;
  94. };
  95. struct invalid_value_data {
  96. struct source_location location;
  97. struct type_descriptor *type;
  98. };
  99. struct alignment_assumption_data {
  100. struct source_location location;
  101. struct source_location assumption_location;
  102. struct type_descriptor *type;
  103. };
  104. #if defined(CONFIG_ARCH_SUPPORTS_INT128)
  105. typedef __int128 s_max;
  106. typedef unsigned __int128 u_max;
  107. #else
  108. typedef s64 s_max;
  109. typedef u64 u_max;
  110. #endif
  111. /*
  112. * When generating Runtime Calls, Clang doesn't respect the -mregparm=3
  113. * option used on i386: https://github.com/llvm/llvm-project/issues/89670
  114. * Fix this for earlier Clang versions by forcing the calling convention
  115. * to use non-register arguments.
  116. */
  117. #if defined(CONFIG_X86_32) && \
  118. defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 190000
  119. # define ubsan_linkage asmlinkage
  120. #else
  121. # define ubsan_linkage
  122. #endif
  123. void ubsan_linkage __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs);
  124. void ubsan_linkage __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs);
  125. void ubsan_linkage __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs);
  126. void ubsan_linkage __ubsan_handle_negate_overflow(void *_data, void *old_val);
  127. void ubsan_linkage __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs);
  128. void ubsan_linkage __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr);
  129. void ubsan_linkage __ubsan_handle_type_mismatch_v1(void *_data, void *ptr);
  130. void ubsan_linkage __ubsan_handle_out_of_bounds(void *_data, void *index);
  131. void ubsan_linkage __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs);
  132. void ubsan_linkage __ubsan_handle_builtin_unreachable(void *_data);
  133. void ubsan_linkage __ubsan_handle_load_invalid_value(void *_data, void *val);
  134. void ubsan_linkage __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr,
  135. unsigned long align,
  136. unsigned long offset);
  137. #endif