I'm quite new to net-snmp, so apologies in advance if this is the wrong
place to discuss patches.

Currently, when one runs snmpd on FreeBSD, it keeps /dev/mem and
/dev/kmem open.  This is a result of using kvm_openfiles() to get a kvm
descriptor, which is used to implement various MIBs (via kvm_getprocs(),
kvm_getswapinfo(), etc.).  However, the libkvm interfaces used by
net-snmp don't actually require /dev/mem or /dev/kmem - they are all
implemented using sysctls.

I would like to have snmpd not hold /dev/(k)mem open.  I can of course
compile using --without-kmem-usage, but that disables the use of libkvm,
so all of that code (used to implement the hostres MIB, for instance)
would need to be rewritten.  However, it turns out that one can ask
kvm_openfiles() to not open /dev/mem and /dev/kmem, by passing
"/dev/null" as the path.  In fact, snmpd already contains code to do
this, but it's only done in a fallback path in init_kmem().

I would like to introduce the patch below, which gets compiled when
--without-kmem-usage is specified.  In this case, snmpd will still use
libkvm, but won't open /dev/(k)mem.  In my testing so far, this works
perfectly.  Does anyone have any thoughts on this patch/approach?  Would
the net-snmp project be willing to accept the patch?  Thank you in
advance for any feedback or guidance.

commit 1c7881da5963508bcbcbd4ac44a60192fec4f7d8
Author: Mark Johnston <ma...@freebsd.org>
Date:   Thu Apr 4 16:34:26 2024 -0400

    snmpd: Enable the use of libkvm without kmem access on FreeBSD

diff --git a/agent/kernel.c b/agent/kernel.c
index 285a603a77..164a6a8ca2 100644
--- a/agent/kernel.c
+++ b/agent/kernel.c
@@ -259,7 +259,37 @@ free_kmem(void)
         kmem = -1;
     }
 }
+#elif defined(__FreeBSD__)
+kvm_t *kd;
+
+/**
+ * Initialize the libkvm descriptor. On FreeBSD we can use most of libkvm
+ * without requiring /dev/kmem access.  Only kvm_nlist() and kvm_read() need
+ * that, and we don't use them.
+ *
+ * @return TRUE upon success; FALSE upon failure.
+ */
+int
+init_kmem(const char *file)
+{
+    char err[4096];
 
+    kd = kvm_openfiles(NULL, "/dev/null", NULL, O_RDONLY, err);
+    if (!kd) {
+        snmp_log(LOG_CRIT, "init_kmem: kvm_openfiles failed: %s\n", err);
+        return FALSE;
+    }
+    return TRUE;
+}
+
+void
+free_kmem(void)
+{
+    if (kd != NULL) {
+        (void)kvm_close(kd);
+        kd = NULL;
+    }
+}
 #else
 int
 init_kmem(const char *file)


_______________________________________________
Net-snmp-coders mailing list
Net-snmp-coders@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to