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