https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=296179

            Bug ID: 296179
           Summary: prometheus_sysctl_exporter assert: exited on signal 6:
                    non-standard label in evdev (device index)
           Product: Base System
           Version: 16.0-CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: bin
          Assignee: [email protected]
          Reporter: [email protected]

Created attachment 271998
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=271998&action=edit
prometheus_sysctl_exporter assert: fix for non-standard label (by Claude LLM,
Maintainers review required)

% uname -rUm
16.0-CURRENT amd64 1600019

% prometheus_sysctl_exporter
// skipped //
sysctl_kern_random_initial_seeding_arc4random_bypassed_before_seeding 0
sysctl_kern_random_initial_seeding_read_random_bypassed_before_seeding 0
sysctl_kern_random_initial_seeding_bypass_before_seeding 1
Assertion failed: (label[strspn(label, "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789_")] == '\0'), function oid_get_metric,
file
/usr/jails/src/src_16/src/usr.sbin/prometheus_sysctl_exporter/prometheus_sysctl_exporter.c,
line 415.
Abort

(prometheus_sysctl_e), jid 0, uid 1001: exited on signal 6

The issue was found and a patch was proposed by the Claude LLM model
(Maintainers review required!):
```
On FreeBSD 16-CURRENT, `prometheus_sysctl_exporter` exits with SIGABRT after
printing the kern.random.initial_seeding.* sysctls. 

The crash is not caused by those nodes themselves; iteration continues to the
next OID, kern.evdev.input.<N>.*, which uses the aggregation label "device
index" (contains a space). 

That label is set in sys/dev/evdev/evdev.c in evdev_sysctl_create():
```
ev_sysctl_tree = SYSCTL_ADD_NODE_WITH_LABEL(..., ev_unit_str, ...,
    "device index");
```

The exporter previously assumed all OID labels are valid Prometheus label names
and hit an assert() in oid_get_metric(). 
This worked on older releases (e.g. 15.1) because those evdev sysctls did not
exist yet. 

There are currently 112 affected OIDs under kern.evdev.input.*.
```



```
diff --git a/usr.sbin/prometheus_sysctl_exporter/prometheus_sysctl_exporter.c
b/usr.sbin/prometheus_sysctl_exporter/prometheus_sysctl_exporter.c
index e3182467be..691f7a9381 100644
--- a/usr.sbin/prometheus_sysctl_exporter/prometheus_sysctl_exporter.c
+++ b/usr.sbin/prometheus_sysctl_exporter/prometheus_sysctl_exporter.c
@@ -371,6 +371,20 @@ oid_get_name(const struct oid *o, struct oidname *on)
        on->oid = *o;
 }

+/* Appends a Prometheus identifier, mapping unsupported characters. */
+static void
+prometheus_append_ident(char *metric, size_t mlen, const char *ident)
+{
+       char buf[2];
+
+       while (*ident != '\0') {
+               snprintf(buf, sizeof(buf), "%c",
+                   isalnum((unsigned char)*ident) ? *ident : '_');
+               strlcat(metric, buf, mlen);
+               ++ident;
+       }
+}
+
 /* Populates the name and labels of an OID to a buffer. */
 static void
 oid_get_metric(const struct oidname *on, const struct oidformat *of,
@@ -387,13 +401,7 @@ oid_get_metric(const struct oidname *on, const struct
oidformat *of,
        for (i = 0; i < on->oid.len; ++i) {
                if (*label == '\0') {
                        strlcat(metric, "_", mlen);
-                       while (*name != '\0') {
-                               /* Map unsupported characters to underscores.
*/
-                               snprintf(buf, sizeof(buf), "%c",
-                                   isalnum(*name) ? *name : '_');
-                               strlcat(metric, buf, mlen);
-                               ++name;
-                       }
+                       prometheus_append_ident(metric, mlen, name);
                }
                name += strlen(name) + 1;
                label += strlen(label) + 1;
@@ -409,12 +417,10 @@ oid_get_metric(const struct oidname *on, const struct
oidformat *of,
        separator = '{';
        for (i = 0; i < on->oid.len; ++i) {
                if (*label != '\0') {
-                       assert(label[strspn(label,
-                           "abcdefghijklmnopqrstuvwxyz"
-                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                           "0123456789_")] == '\0');
-                       snprintf(buf, sizeof(buf), "%c%s=\"", separator,
label);
+                       snprintf(buf, sizeof(buf), "%c", separator);
                        strlcat(metric, buf, mlen);
+                       prometheus_append_ident(metric, mlen, label);
+                       strlcat(metric, "=\"", mlen);
                        while (*name != '\0') {
                                /* Escape backslashes and double quotes. */
                                if (*name == '\\' || *name == '"')

```

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to