Page MenuHomeFreeBSD

D58987.id184354.diff
No OneTemporary

D58987.id184354.diff

diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3873,6 +3873,8 @@
kern/kern_acct.c standard
kern/kern_alq.c optional alq
kern/kern_boottrace.c standard
+kern/kern_bounds.c standard
+kern/kern_bounds_test.c standard
kern/kern_clock.c standard
kern/kern_clocksource.c standard
kern/kern_condvar.c standard
diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk
--- a/sys/conf/kern.mk
+++ b/sys/conf/kern.mk
@@ -355,8 +355,14 @@
# by default, in which case the annotations expand to nothing.
#
BOUNDS_SAFETY_FILES?=
+BOUNDS_SAFETY_FLAGS= -fbounds-safety
+# BOUNDS_SAFETY_SOFT: log violations (kern.bounds_soft_violations, dtrace
+# bounds:::violation) and continue, instead of panicking on a hard trap.
+.if defined(BOUNDS_SAFETY_SOFT)
+BOUNDS_SAFETY_FLAGS+= -fbounds-safety-soft-traps=call-minimal
+.endif
.for _file in ${BOUNDS_SAFETY_FILES}
-CFLAGS.${_file}+= -fbounds-safety
+CFLAGS.${_file}+= ${BOUNDS_SAFETY_FLAGS}
.endfor
CFLAGS+= ${CWARNFLAGS:M*} ${CWARNFLAGS.${.IMPSRC:T}}
diff --git a/sys/kern/kern_bounds.c b/sys/kern/kern_bounds.c
new file mode 100644
--- /dev/null
+++ b/sys/kern/kern_bounds.c
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 2026 The FreeBSD Foundation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * This software was developed by Abhijeet Sharma <abhijeetsharma2002@gmail.com>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Runtime for -fbounds-safety soft-trap mode. A file built with
+ * -fbounds-safety-soft-traps=call-minimal calls __bounds_safety_soft_trap()
+ * on a failed check and continues, so the violation is counted and traced
+ * rather than fatal. The trap site is the return address. Interface:
+ * clang's bounds_safety_soft_traps.h.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/counter.h>
+#include <sys/kernel.h>
+#include <sys/pcpu.h>
+#include <sys/sdt.h>
+#include <sys/sysctl.h>
+
+SDT_PROVIDER_DEFINE(bounds);
+SDT_PROBE_DEFINE1(bounds, , , violation, "uintptr_t");
+
+static COUNTER_U64_DEFINE_EARLY(bounds_soft_violations);
+SYSCTL_COUNTER_U64(_kern, OID_AUTO, bounds_soft_violations, CTLFLAG_RD,
+ &bounds_soft_violations,
+ "Soft bounds-safety violations detected at run time");
+
+/* Console logging is opt-in; the counter and SDT probe are always on. */
+static int bounds_soft_trap_verbose = 0;
+SYSCTL_INT(_debug, OID_AUTO, bounds_soft_trap_verbose, CTLFLAG_RWTUN,
+ &bounds_soft_trap_verbose, 0,
+ "Log each soft bounds-safety violation to the console "
+ "(0 = counter + dtrace only)");
+
+static int bounds_soft_trap_max_pps = 5;
+SYSCTL_INT(_debug, OID_AUTO, bounds_soft_trap_max_pps, CTLFLAG_RWTUN,
+ &bounds_soft_trap_max_pps, 0,
+ "Max soft bounds-safety console messages per second (0 = unlimited)");
+
+/* Set while this CPU is in the log path, to break printf() recursion. */
+DPCPU_DEFINE_STATIC(int, bounds_soft_trap_active);
+
+/*
+ * preserve_all is only supported on arm64/amd64; keep in sync with clang's
+ * bounds_safety_soft_traps.h.
+ */
+#if __has_attribute(preserve_all) && (defined(__aarch64__) || defined(__amd64__))
+#define BOUNDS_SOFT_TRAP_CC __attribute__((preserve_all))
+#else
+#define BOUNDS_SOFT_TRAP_CC
+#endif
+
+BOUNDS_SOFT_TRAP_CC void __bounds_safety_soft_trap(void);
+
+BOUNDS_SOFT_TRAP_CC void
+__bounds_safety_soft_trap(void)
+{
+ /* Global, so the rate limit is approximate under concurrency. */
+ static struct timeval lastlog;
+ static int curpps;
+ uintptr_t site;
+
+ /* extract_return_addr strips the arm64 PAC signature from the address. */
+ site = (uintptr_t)__builtin_extract_return_addr(
+ __builtin_return_address(0));
+
+ /*
+ * A violation can fire in any context. Pin the CPU and drop nested
+ * traps so the log path cannot recurse.
+ */
+ critical_enter();
+ if (DPCPU_GET(bounds_soft_trap_active)) {
+ critical_exit();
+ return;
+ }
+ DPCPU_SET(bounds_soft_trap_active, 1);
+
+ counter_u64_add(bounds_soft_violations, 1);
+ SDT_PROBE1(bounds, , , violation, site);
+
+ /*
+ * No backtrace here: stack_print_short() takes the linker sx lock, which
+ * is illegal from a critical section. Use dtrace bounds:::violation with
+ * stack(), or symbolicate the printed site offline.
+ */
+ if (bounds_soft_trap_verbose &&
+ (bounds_soft_trap_max_pps <= 0 ||
+ ppsratecheck(&lastlog, &curpps, bounds_soft_trap_max_pps)))
+ printf("bounds-safety: soft trap near %p\n", (void *)site);
+
+ DPCPU_SET(bounds_soft_trap_active, 0);
+ critical_exit();
+}
diff --git a/sys/kern/kern_bounds_test.c b/sys/kern/kern_bounds_test.c
new file mode 100644
--- /dev/null
+++ b/sys/kern/kern_bounds_test.c
@@ -0,0 +1,42 @@
+/*-
+ * Copyright (c) 2026 The FreeBSD Foundation
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * This software was developed by Abhijeet Sharma <abhijeetsharma2002@gmail.com>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Deliberate-violation test hook for -fbounds-safety. Kept separate from the
+ * runtime in kern_bounds.c so exercising it does not instrument the handler;
+ * add kern_bounds_test.c (not kern_bounds.c) to BOUNDS_SAFETY_FILES to enable
+ * it. Writing N to debug.bounds_test reads arr[N] of a 4-element array; N is
+ * clamped to [0, 4], and N == 4 (one past the end) traps.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+
+#if __has_ptrcheck
+static int
+sysctl_debug_bounds_test(SYSCTL_HANDLER_ARGS)
+{
+ int arr[4] = { 1, 2, 3, 4 };
+ int *p;
+ int error, idx;
+
+ idx = -1;
+ error = sysctl_handle_int(oidp, &idx, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+ if (idx < 0 || idx > nitems(arr)) /* [0, 4]; 4 is the trapping index */
+ return (EINVAL);
+ p = arr;
+ printf("bounds-safety: test read arr[%d] -> %d\n", idx, p[idx]);
+ return (0);
+}
+SYSCTL_PROC(_debug, OID_AUTO, bounds_test,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
+ sysctl_debug_bounds_test, "I",
+ "Read index N (0..4) of a 4-element array under -fbounds-safety; N==4 traps");
+#endif /* __has_ptrcheck */

File Metadata

Mime Type
text/plain
Expires
Sun, Aug 23, 1:29 PM (9 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37063834
Default Alt Text
D58987.id184354.diff (5 KB)

Event Timeline