git: de5689d1e6ea - stable/15 - bsnmp: validate the lower bound of error_index in responses

From: Maxim Konovalov <maxim_at_FreeBSD.org>
Date: Tue, 06 Oct 2026 17:39:27 UTC
The branch stable/15 has been updated by maxim:

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

commit de5689d1e6ea621249e1ef44db3c2d3ee8431ba5
Author:     Maxim Konovalov <maxim@FreeBSD.org>
AuthorDate: 2026-09-22 21:32:43 +0000
Commit:     Maxim Konovalov <maxim@FreeBSD.org>
CommitDate: 2026-10-06 17:37:11 +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
    
    (cherry picked from commit 296e3fd54ca8972fa6696974097a2f2705f8dfc4)
---
 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 4d1058629496..857bb205b9b4 100644
--- a/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
+++ b/usr.sbin/bsnmpd/tools/libbsnmptools/bsnmptools.c
@@ -1994,7 +1994,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;
 	}