The branch releng/14.0 has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=8ad93f44a5daf804a281782271cec7423572e7c4

commit 8ad93f44a5daf804a281782271cec7423572e7c4
Author:     Domagoj Stolfa <domagoj.sto...@gmail.com>
AuthorDate: 2023-09-06 13:25:00 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2023-09-28 20:41:15 +0000

    dtrace: Fix a kernel panic in printm()
    
    When using printm(), one should always pass a scratch pointer to it.
    This is achieved by calling printm with memref
    
      BEGIN { printm(fixed_len, memref(ptr, var_len)); }
    
    which will return a pointer to the DTrace scratch space of size
    sizeof(uintptr_t) * 2. However, one can easily call printm() as follows
    
      BEGIN { printm(10, (void *)NULL); }
    
    and panic the kernel as a result. This commit does two things:
    
      (1) adds a new macro DTRACE_INSCRATCHPTR(mstate, ptr, howmany) which
          checks if a certain pointer is in the DTrace scratch space;
      (2) uses DTRACE_INSCRATCHPTR() to implement a check on printm()'s DIFO
          return value in order to avoid the panic and sets CPU_DTRACE_BADADDR
          if the address is not in the scratch space.
    
    Approved by:    re (gjb)
    Reviewed by:    markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D41722
    
    (cherry picked from commit 8527bb2aee6ca9013c34445de88217a954b6628d)
    (cherry picked from commit 49c1b353390cf498bcd9a3e548039e2a64f654fe)
---
 .../contrib/opensolaris/uts/common/dtrace/dtrace.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c 
b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
index 02a95bfab726..ce02676e0dc1 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c
@@ -515,6 +515,11 @@ do {                                                       
                \
        ((mstate)->dtms_scratch_base + (mstate)->dtms_scratch_size - \
        (mstate)->dtms_scratch_ptr >= (alloc_sz))
 
+#define DTRACE_INSCRATCHPTR(mstate, ptr, howmany) \
+       ((ptr) >= (mstate)->dtms_scratch_base && \
+       (ptr) <= \
+       ((mstate)->dtms_scratch_base + (mstate)->dtms_scratch_size - (howmany)))
+
 #define        DTRACE_LOADFUNC(bits)                                           
\
 /*CSTYLED*/                                                            \
 uint##bits##_t                                                         \
@@ -7739,9 +7744,24 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t 
arg1,
                        }
 
                        case DTRACEACT_PRINTM: {
-                               /* The DIF returns a 'memref'. */
+                               /*
+                                * printm() assumes that the DIF returns a
+                                * pointer returned by memref(). memref() is a
+                                * subroutine that is used to get around the
+                                * single-valued returns of DIF and is assumed
+                                * to always be allocated in the scratch space.
+                                * Therefore, we need to validate that the
+                                * pointer given to printm() is in the scratch
+                                * space in order to avoid a potential panic.
+                                */
                                uintptr_t *memref = (uintptr_t *)(uintptr_t) 
val;
 
+                               if (!DTRACE_INSCRATCHPTR(&mstate,
+                                   (uintptr_t)memref, 2 * sizeof(uintptr_t))) {
+                                       *flags |= CPU_DTRACE_BADADDR;
+                                       continue;
+                               }
+
                                /* Get the size from the memref. */
                                size = memref[1];
 

Reply via email to