Fix KUBSAN by adding invalid builtin detection, as needed by our current clang.
authormbuhl <mbuhl@openbsd.org>
Fri, 6 Sep 2024 13:31:59 +0000 (13:31 +0000)
committermbuhl <mbuhl@openbsd.org>
Fri, 6 Sep 2024 13:31:59 +0000 (13:31 +0000)
ok anton@

share/man/man4/kubsan.4
sys/kern/subr_kubsan.c

index 6165a1e..db3866d 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: kubsan.4,v 1.4 2024/09/06 13:30:59 mbuhl Exp $
+.\"    $OpenBSD: kubsan.4,v 1.5 2024/09/06 13:31:59 mbuhl Exp $
 .\"
 .\" Copyright (c) 2019 Anton Lindqvist <anton@openbsd.org>
 .\"
@@ -69,6 +69,8 @@ Passing
 .Dv NULL
 as the value for a function argument annotated with
 .Dv __nonnull__ .
+.It Invalid builtin
+Passing zero to a compiler builtin where not allowed.
 .It Invalid load
 Loading a value that cannot be represented by the destination type.
 .It Type mismatch
index 9655500..967140f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: subr_kubsan.c,v 1.12 2019/11/06 19:16:48 anton Exp $  */
+/*     $OpenBSD: subr_kubsan.c,v 1.13 2024/09/06 13:31:59 mbuhl Exp $  */
 
 /*
  * Copyright (c) 2019 Anton Lindqvist <anton@openbsd.org>
@@ -38,6 +38,7 @@
 struct kubsan_report {
        enum {
                KUBSAN_FLOAT_CAST_OVERFLOW,
+               KUBSAN_INVALID_BUILTIN,
                KUBSAN_INVALID_VALUE,
                KUBSAN_NEGATE_OVERFLOW,
                KUBSAN_NONNULL_ARG,
@@ -57,6 +58,10 @@ struct kubsan_report {
                        unsigned long v_val;
                } v_float_cast_overflow;
 
+               struct {
+                       const struct invalid_builtin_data *v_data;
+               } v_invalid_builtin;
+
                struct {
                        const struct invalid_value_data *v_data;
                        unsigned long v_val;
@@ -102,6 +107,7 @@ struct kubsan_report {
        } kr_u;
 };
 #define kr_float_cast_overflow         kr_u.v_float_cast_overflow
+#define kr_invalid_builtin             kr_u.v_invalid_builtin
 #define kr_invalid_value               kr_u.v_invalid_value
 #define kr_negate_overflow             kr_u.v_negate_overflow
 #define kr_nonnull_arg                 kr_u.v_nonnull_arg
@@ -129,6 +135,11 @@ struct float_cast_overflow_data {
        struct type_descriptor *d_ttype;        /* to type */
 };
 
+struct invalid_builtin_data {
+       struct source_location d_src;
+       uint8_t d_kind;
+};
+
 struct invalid_value_data {
        struct source_location d_src;
        struct type_descriptor *d_type;
@@ -264,6 +275,18 @@ __ubsan_handle_float_cast_overflow(struct float_cast_overflow_data *data,
        kubsan_defer_report(&kr);
 }
 
+void
+__ubsan_handle_invalid_builtin(struct invalid_builtin_data *data)
+{
+       struct kubsan_report kr = {
+               .kr_type                = KUBSAN_INVALID_VALUE,
+               .kr_src                 = &data->d_src,
+               .kr_invalid_builtin     = { data },
+       };
+
+       kubsan_defer_report(&kr);
+}
+
 void
 __ubsan_handle_load_invalid_value(struct invalid_value_data *data,
     unsigned long val)
@@ -562,6 +585,16 @@ again:
                        break;
                }
 
+               case KUBSAN_INVALID_BUILTIN: {
+                       const struct invalid_builtin_data *data =
+                           kr->kr_invalid_builtin.v_data;
+
+                       printf("kubsan: %s: invalid builtin: passing zero to "
+                           "%s, which is not a valid argument\n",
+                           bloc, kubsan_kind(data->d_kind));
+                       break;
+               }
+
                case KUBSAN_INVALID_VALUE: {
                        const struct invalid_value_data *data =
                            kr->kr_invalid_value.v_data;