The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=9a30c8d347bf9aaa89277b6e5a275f737be8edce

commit 9a30c8d347bf9aaa89277b6e5a275f737be8edce
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2025-03-10 03:00:59 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2025-03-10 03:00:59 +0000

    libdtrace: Fix an off-by-one in CPU ID handling
    
    The illumos-specific _SC_CPUID_MAX is the largest CPU ID in the system.  
This
    was mapped to _SC_NPROCESSORS_CONF, which is the total number of CPUs 
recognized
    by the kernel.  If CPU IDs are contiguous, as is the case on amd64 and 
arm64,
    this value is one greater than the maximum ID.   As a result, when consuming
    per-CPU dtrace buffers, libdtrace tries to fetch from a non-existent CPU.  
This
    is mostly harmless in practice, but still wrong.
    
    As we don't have a sysconf value for the maximum CPU ID, add a wrapper which
    fetches it using the kern.smp.maxid sysctl.
    
    MFC after:      2 weeks
    Sponsored by:   Innovate UK
    Differential Revision:  https://reviews.freebsd.org/D49243
---
 .../opensolaris/lib/libdtrace/common/dt_aggregate.c        |  6 ++++--
 cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c |  8 ++++----
 cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h    |  1 +
 cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c    | 14 ++++++++++++++
 cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h     |  5 -----
 5 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c 
b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
index 643e7fae8ace..1c3131e74cb0 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_aggregate.c
@@ -1092,8 +1092,10 @@ dt_aggregate_go(dtrace_hdl_t *dtp)
        assert(agp->dtat_ncpu == 0);
        assert(agp->dtat_cpus == NULL);
 
-       agp->dtat_maxcpu = dt_sysconf(dtp, _SC_CPUID_MAX) + 1;
-       agp->dtat_ncpu = dt_sysconf(dtp, _SC_NPROCESSORS_MAX);
+       agp->dtat_maxcpu = dt_cpu_maxid(dtp) + 1;
+       if (agp->dtat_maxcpu <= 0)
+               return (-1);
+       agp->dtat_ncpu = dt_sysconf(dtp, _SC_NPROCESSORS_CONF);
        agp->dtat_cpus = malloc(agp->dtat_ncpu * sizeof (processorid_t));
 
        if (agp->dtat_cpus == NULL)
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c 
b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
index 6a32235f7e39..a760642c33bb 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_consume.c
@@ -3949,8 +3949,8 @@ dt_consume_begin(dtrace_hdl_t *dtp, FILE *fp,
                return (rval);
        }
 
-       if (max_ncpus == 0)
-               max_ncpus = dt_sysconf(dtp, _SC_CPUID_MAX) + 1;
+       if (max_ncpus == 0 && (max_ncpus = dt_cpu_maxid(dtp) + 1) <= 0)
+               return (-1);
 
        for (i = 0; i < max_ncpus; i++) {
                dtrace_bufdesc_t *nbuf;
@@ -4040,8 +4040,8 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
        if (!dtp->dt_active)
                return (dt_set_errno(dtp, EINVAL));
 
-       if (max_ncpus == 0)
-               max_ncpus = dt_sysconf(dtp, _SC_CPUID_MAX) + 1;
+       if (max_ncpus == 0 && (max_ncpus = dt_cpu_maxid(dtp) + 1) <= 0)
+               return (-1);
 
        if (pf == NULL)
                pf = (dtrace_consume_probe_f *)dt_nullprobe;
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h 
b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
index 1be984f28001..b73ecc3e57f4 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_impl.h
@@ -620,6 +620,7 @@ extern int dt_version_defined(dt_version_t);
  */
 extern char *dt_cpp_add_arg(dtrace_hdl_t *, const char *);
 extern char *dt_cpp_pop_arg(dtrace_hdl_t *);
+extern int dt_cpu_maxid(dtrace_hdl_t *);
 
 #ifdef illumos
 extern int dt_set_errno(dtrace_hdl_t *, int);
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c 
b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c
index 5976333e1b16..5dc8e1648fd3 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dt_subr.c
@@ -463,6 +463,20 @@ dt_cpp_pop_arg(dtrace_hdl_t *dtp)
        return (arg);
 }
 
+int
+dt_cpu_maxid(dtrace_hdl_t *dtp)
+{
+       size_t len;
+       u_int count;
+       int error;
+
+       len = sizeof(count);
+       error = sysctlbyname("kern.smp.maxid", &count, &len, NULL, 0);
+       if (error != 0)
+               return (dt_set_errno(dtp, errno));
+       return (count);
+}
+
 /*PRINTFLIKE1*/
 void
 dt_dprintf(const char *format, ...)
diff --git a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h 
b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
index 1f4c5a2efd6b..c9496c2df5ba 100644
--- a/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
+++ b/cddl/contrib/opensolaris/lib/libdtrace/common/dtrace.h
@@ -620,11 +620,6 @@ extern int _dtrace_debug;
 }
 #endif
 
-#ifndef illumos
-#define _SC_CPUID_MAX          _SC_NPROCESSORS_CONF
-#define _SC_NPROCESSORS_MAX    _SC_NPROCESSORS_CONF
-#endif
-
 /*
  * Values for the dt_oformat property.
  */

Reply via email to