Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167534983
D58987.id184354.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D58987.id184354.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D58987: kern: add bounds-safety soft-trap runtime
Attached
Detach File
Event Timeline
Log In to Comment