Page MenuHomeFreeBSD

D60831.diff
No OneTemporary

D60831.diff

diff --git a/sys/kern/kern_bounds_test.c b/sys/kern/kern_bounds_test.c
--- a/sys/kern/kern_bounds_test.c
+++ b/sys/kern/kern_bounds_test.c
@@ -11,8 +11,8 @@
* 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.
- * debug.bounds_mtod_test takes a case number and exercises mtod() and
- * mtod_len().
+ * debug.bounds_mtod_test and debug.bounds_dataptr_test take a case number
+ * and exercise mtod(), mtod_len() and m_dataptr().
*/
#include <sys/param.h>
@@ -124,4 +124,75 @@
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
sysctl_debug_bounds_mtod_test, "I",
"Exercise the checked mbuf accessors; modes 2 and 4-8 trap");
+
+static int
+sysctl_debug_bounds_dataptr_test(SYSCTL_HANDLER_ARGS)
+{
+ struct mbuf *m;
+ char *p;
+ u_int realsize;
+ int error, mode;
+ volatile char sink;
+
+ mode = -1;
+ error = sysctl_handle_int(oidp, &mode, 0, req);
+ if (error != 0 || req->newptr == NULL)
+ return (error);
+ if (mode < 0 || mode > 8)
+ return (EINVAL);
+
+ m = m_getcl(M_WAITOK, MT_DATA, 0);
+ m->m_len = 64;
+ realsize = m->m_ext.ext_size;
+ memset(mtod(m, char *), 0x5a, realsize);
+ p = NULL;
+ sink = 0;
+
+ switch (mode) {
+ case 0:
+ p = m_dataptr(m, 0, 64);
+ sink = p[63];
+ break;
+ case 1:
+ p = m_dataptr(m, 16, 48);
+ sink = p[47];
+ break;
+ case 2:
+ p = m_dataptr(m, 16, 8);
+ sink = p[8];
+ break;
+ case 3:
+ p = m_dataptr(m, 0, 65);
+ break;
+ case 4:
+ p = m_dataptr(m, 60, 8);
+ break;
+ case 5:
+ p = m_dataptr(m, -1, 4);
+ break;
+ case 6:
+ p = m_dataptr(m, 0, -1);
+ break;
+ case 7:
+ m->m_flags |= M_EXTPG;
+ p = m_dataptr(m, 0, 4);
+ m->m_flags &= ~M_EXTPG;
+ break;
+ case 8:
+ m->m_ext.ext_size = TESTCAP;
+ m->m_len = TESTCAP + 16;
+ p = m_dataptr(m, 0, TESTCAP + 16);
+ sink = p[0];
+ break;
+ }
+ m->m_ext.ext_size = realsize;
+ printf("bounds-safety: dataptr test mode %d -> %s %d\n", mode,
+ p == NULL ? "NULL" : "ptr", (int)sink);
+ m_freem(m);
+ return (0);
+}
+SYSCTL_PROC(_debug, OID_AUTO, bounds_dataptr_test,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0,
+ sysctl_debug_bounds_dataptr_test, "I",
+ "Exercise m_dataptr(); modes 2 and 8 trap, 3-7 return NULL");
#endif /* __has_ptrcheck */
diff --git a/sys/sys/mbuf.h b/sys/sys/mbuf.h
--- a/sys/sys/mbuf.h
+++ b/sys/sys/mbuf.h
@@ -1257,6 +1257,20 @@
}
#endif
+/*
+ * Return a pointer to len bytes at off in the data of m, or NULL if m does
+ * not hold them. Under -fbounds-safety the result is bounded to len bytes.
+ */
+static __inline void * __sized_by_or_null(len)
+m_dataptr(const struct mbuf *m, int off, int len)
+{
+
+ if ((m->m_flags & M_EXTPG) != 0 || off < 0 || len < 0 ||
+ off > m->m_len || len > m->m_len - off)
+ return (NULL);
+ return (mtodo(m, off));
+}
+
/*
* Set the m_data pointer of a newly allocated mbuf to place an object of the
* specified size at the end of the mbuf, longword aligned.

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 19, 3:09 AM (13 h, 22 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41029693
Default Alt Text
D60831.diff (2 KB)

Event Timeline