git: 296e3fd54ca8 - main - bsnmp: validate the lower bound of error_index in responses

From: Maxim Konovalov <maxim_at_FreeBSD.org>
Date: Tue, 22 Sep 2026 21:50:10 UTC
The branch main has been updated by maxim:

URL: https://cgit.FreeBSD.org/src/commit/?id=296e3fd54ca8972fa6696974097a2f2705f8dfc4

commit 296e3fd54ca8972fa6696974097a2f2705f8dfc4
Author:     Maxim Konovalov <maxim@FreeBSD.org>
AuthorDate: 2026-09-22 21:32:43 +0000
Commit:     Maxim Konovalov <maxim@FreeBSD.org>
CommitDate: 2026-09-22 21:32:43 +0000

    bsnmp: validate the lower bound of error_index in responses
    
    Check if the response's error_index is within a sane interval.
    Otherwise, a rogue peer could crash us.
    
    PR:             298222
    Reported by:    Robert Morris
    Reviewed by:    markj
    Discussed with: secteam (markj)
    MFC after:      2 weeks
    Analyzed with:  Claude Code Opus 5
---
 usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c      | 8 ++++++--
 usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c | 3 ++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
index 9252e63749bb..25129567ee92 100644
--- a/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
+++ b/usr.sbin/bsnmpd/tools/bsnmptools/bsnmpget.c
@@ -413,7 +413,9 @@ snmptool_get(struct snmp_toolinfo *snmptoolctx)
 		 * Loop through the object list and set object->error to the
 		 * varbinding that caused the error.
 		 */
-		if (snmp_object_seterror(snmptoolctx,
+		if (resp.error_index < 1 ||
+		    resp.error_index > (int32_t)resp.nbindings ||
+		    snmp_object_seterror(snmptoolctx,
 		    &(resp.bindings[resp.error_index - 1]),
 		    resp.error_status) <= 0) {
 			snmp_pdu_free(&resp);
@@ -1107,7 +1109,9 @@ snmptool_set(struct snmp_toolinfo *snmptoolctx)
 			break;
 		}
 
-		if (snmp_object_seterror(snmptoolctx,
+		if (resp.error_index < 1 ||
+		    resp.error_index > (int32_t)resp.nbindings ||
+		    snmp_object_seterror(snmptoolctx,
 		    &(resp.bindings[resp.error_index - 1]),
 		    resp.error_status) <= 0) {
 			snmp_pdu_free(&resp);
diff --git a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
index d8fbb55290a8..4c53555407de 100644
--- a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
@@ -1993,7 +1993,8 @@ snmp_output_err_resp(struct snmp_toolinfo *snmptoolctx, struct snmp_pdu *pdu)
 	struct snmp_object *object;
 	char buf[ASN_OIDSTRLEN];
 
-	if (pdu == NULL || (pdu->error_index > (int32_t) pdu->nbindings)) {
+	if (pdu == NULL || pdu->error_index < 1 ||
+	    (pdu->error_index > (int32_t) pdu->nbindings)) {
 		fprintf(stdout, "Invalid error index in PDU\n");
 		return;
 	}