git: 7f5fa76367d7 - main - dtrace: Fix DOF section-specific validation

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 06 Jul 2026 13:28:31 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=7f5fa76367d78e47d483fdf2cc72e5823d0f7807

commit 7f5fa76367d78e47d483fdf2cc72e5823d0f7807
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-07-06 13:21:43 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-07-06 13:21:43 +0000

    dtrace: Fix DOF section-specific validation
    
    The entry size of the probe section is assumed to be at least
    sizeof(dof_probe_t) by the loop further below.
    
    enoff_sec->dofs_entsize was not being validated at all.
    
    When multiplying an index by a table entry size, make sure the
    multiplication can't overflow.
    
    Fix an off-by-one when validating the translated probe argument array.
    
    Make sure that the probe argument argvs are valid string offsets
    even if the argument count is zero.
    
    Reviewed by:    christos
    MFC after:      2 weeks
    Sponsored by:   CHERI Research Centre
    Differential Revision:  https://reviews.freebsd.org/D57979
---
 .../contrib/opensolaris/uts/common/dtrace/dtrace.c | 30 +++++++++++++++++-----
 1 file changed, 23 insertions(+), 7 deletions(-)

diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index ff31d806664b..11d499953c85 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -16260,7 +16260,8 @@ dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
 	}
 
 	if (prb_sec->dofs_entsize == 0 ||
-	    prb_sec->dofs_entsize > prb_sec->dofs_size) {
+	    prb_sec->dofs_entsize > prb_sec->dofs_size ||
+	    prb_sec->dofs_entsize < sizeof (dof_probe_t)) {
 		dtrace_dof_error(dof, "invalid entry size");
 		return (-1);
 	}
@@ -16285,6 +16286,11 @@ dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
 		return (-1);
 	}
 
+	if (enoff_sec != NULL && enoff_sec->dofs_entsize != sizeof (uint32_t)) {
+		dtrace_dof_error(dof, "invalid entry size");
+		return (-1);
+	}
+
 	arg = (uint8_t *)(uintptr_t)(daddr + arg_sec->dofs_offset);
 
 	nprobes = prb_sec->dofs_size / prb_sec->dofs_entsize;
@@ -16325,7 +16331,7 @@ dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
 		if (probe->dofpr_offidx + probe->dofpr_noffs <
 		    probe->dofpr_offidx ||
 		    (probe->dofpr_offidx + probe->dofpr_noffs) *
-		    off_sec->dofs_entsize > off_sec->dofs_size) {
+		    (uint64_t) off_sec->dofs_entsize > off_sec->dofs_size) {
 			dtrace_dof_error(dof, "invalid probe offset");
 			return (-1);
 		}
@@ -16347,7 +16353,8 @@ dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
 			} else if (probe->dofpr_enoffidx +
 			    probe->dofpr_nenoffs < probe->dofpr_enoffidx ||
 			    (probe->dofpr_enoffidx + probe->dofpr_nenoffs) *
-			    enoff_sec->dofs_entsize > enoff_sec->dofs_size) {
+			    (uint64_t) enoff_sec->dofs_entsize >
+			    enoff_sec->dofs_size) {
 				dtrace_dof_error(dof, "invalid is-enabled "
 				    "offset");
 				return (-1);
@@ -16366,13 +16373,17 @@ dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
 		if (probe->dofpr_argidx + probe->dofpr_xargc <
 		    probe->dofpr_argidx ||
 		    (probe->dofpr_argidx + probe->dofpr_xargc) *
-		    arg_sec->dofs_entsize > arg_sec->dofs_size) {
+		    (uint64_t) arg_sec->dofs_entsize > arg_sec->dofs_size) {
 			dtrace_dof_error(dof, "invalid args");
 			return (-1);
 		}
 
 		typeidx = probe->dofpr_nargv;
-		typestr = strtab + probe->dofpr_nargv;
+		if (typeidx >= str_sec->dofs_size) {
+			dtrace_dof_error(dof, "bad native argument type");
+			return (-1);
+		}
+		typestr = strtab + typeidx;
 		for (k = 0; k < probe->dofpr_nargc; k++) {
 			if (typeidx >= str_sec->dofs_size) {
 				dtrace_dof_error(dof, "bad "
@@ -16391,9 +16402,14 @@ dtrace_helper_provider_validate(dof_hdr_t *dof, dof_sec_t *sec)
 		}
 
 		typeidx = probe->dofpr_xargv;
-		typestr = strtab + probe->dofpr_xargv;
+		if (typeidx >= str_sec->dofs_size) {
+			dtrace_dof_error(dof, "bad native argument type");
+			return (-1);
+		}
+		typestr = strtab + typeidx;
 		for (k = 0; k < probe->dofpr_xargc; k++) {
-			if (arg[probe->dofpr_argidx + k] > probe->dofpr_nargc) {
+			if (arg[probe->dofpr_argidx + k] >=
+			    probe->dofpr_nargc) {
 				dtrace_dof_error(dof, "bad "
 				    "native argument index");
 				return (-1);