On Mon, Jun 10, 2024 at 03:51:33PM -0700, Bart Van Assche wrote:
> 
> On 6/10/24 13:27, Mark Johnston wrote:
> > Would it be helpful for me to submit a patch?  A few of us have been
> > testing snmpd with my original patch (to tell libkvm not to open
> > /dev/kmem etc.) for a while now with no issues.
> A patch definitely would be welcome.

The patch below implements your suggestion.  That is, init_kmem() gets a
libkvm handle without opening /dev/kmem, no matter whether --with-kmem-usage
or --without-kmem-usage was specified at compile time.

Thinking about this more, users might still want --with-kmem-usage to
cause snmpd to open /dev/kmem, in the case where they have custom MIBs
implementations which require the use of klookup().  With this patch,
it's impossible to use klookup() on FreeBSD.  I believe this is fine for
the code shipped with net-snmp, but it might break some custom 3rd-party
MIBs.  I'm not too concerned about this, as the official FreeBSD
net-snmp package will be compiled with --without-kmem-usage, but perhaps
it still makes sense to leave an escape hatch.

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

    snmpd: Always open libkvm in "safe mode" on FreeBSD
    
    By specifying /dev/null as the path to kvm_openfiles(), we can get a
    libkvm descriptor which does not hold /dev/kmem open.  None of the code
    shipped with net-snmp needs a /dev/kmem handle.
    
    Make this change for both the NETSNMP_NO_KMEM_USAGE and
    !NETSNMP_NO_KMEM_USAGE cases, per a suggestion from
    Bart Van Assche <bvanass...@acm.org>.

diff --git a/agent/kernel.c b/agent/kernel.c
index 9a6d22592c..671e5244fc 100644
--- a/agent/kernel.c
+++ b/agent/kernel.c
@@ -44,7 +44,7 @@
 #include "kernel.h"
 #include <net-snmp/agent/ds_agent.h>
 
-#if defined(HAVE_KVM_H) && !defined(NETSNMP_NO_KMEM_USAGE)
+#if defined(HAVE_KVM_H) && !defined(NETSNMP_NO_KMEM_USAGE) && 
!defined(__FreeBSD__)
 kvm_t *kd;
 
 /**
@@ -130,7 +130,7 @@ free_kmem(void)
     }
 }
 
-#elif defined(HAVE_NLIST_H) && !defined(__linux__) &&   \
+#elif defined(HAVE_NLIST_H) && !defined(__linux__) && !defined(__FreeBSD__) && 
\
     !defined(NETSNMP_NO_KMEM_USAGE)
 
 static off_t    klseek(off_t);
@@ -252,7 +252,48 @@ 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;
+}
 
+/**
+ * A stub to return failure to any attempt to read kernel memory.  Our
+ * libkvm handle doesn't enable /dev/kmem access.  MIB implementations should
+ * use unprivileged to fetch information about the system.
+ */
+int
+klookup(unsigned long off, void *target, size_t siz)
+{
+    return 0;
+}
+
+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