From ff1f6f1bdeccacc9f7f92948a28874fdabe9c6e7 Mon Sep 17 00:00:00 2001 From: Martijn van Duren Date: Tue, 20 Dec 2022 20:01:26 +0000 Subject: When writing out a PDU with authpriv that's larger than READ_BUF_SIZE we overflow the encbuf. Allocate encbuf on the fly so that we always have enough room. Give decryption the same treatment, although this one is not at risk, since the input is limited to READ_BUF_SIZE. OK sthen@, kn@ --- usr.sbin/snmpd/usm.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'usr.sbin') diff --git a/usr.sbin/snmpd/usm.c b/usr.sbin/snmpd/usm.c index a2095373ace..1ced2fdb432 100644 --- a/usr.sbin/snmpd/usm.c +++ b/usr.sbin/snmpd/usm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: usm.c,v 1.24 2022/01/05 17:01:06 tb Exp $ */ +/* $OpenBSD: usm.c,v 1.25 2022/12/20 20:01:25 martijn Exp $ */ /* * Copyright (c) 2012 GeNUA mbH @@ -504,7 +504,7 @@ usm_encrypt(struct snmp_message *msg, struct ber_element *pdu) struct ber_element *encrpdu = NULL; void *ptr; ssize_t elen, len; - u_char encbuf[READ_BUF_SIZE]; + u_char *encbuf; if (!MSG_HAS_PRIV(msg)) return pdu; @@ -517,10 +517,12 @@ usm_encrypt(struct snmp_message *msg, struct ber_element *pdu) #endif len = ober_write_elements(&ber, pdu); - if (ober_get_writebuf(&ber, &ptr) > 0) { + if (ober_get_writebuf(&ber, &ptr) > 0 && + (encbuf = malloc(len + EVP_MAX_BLOCK_LENGTH)) != NULL) { elen = usm_crypt(msg, ptr, len, encbuf, 1); if (elen > 0) encrpdu = ober_add_nstring(NULL, (char *)encbuf, elen); + free(encbuf); } ober_free(&ber); @@ -617,12 +619,13 @@ usm_decrypt(struct snmp_message *msg, struct ber_element *encr) { u_char *privstr; size_t privlen; - u_char buf[READ_BUF_SIZE]; + u_char *buf; struct ber ber; struct ber_element *scoped_pdu = NULL; ssize_t scoped_pdu_len; - if (ober_get_nstring(encr, (void *)&privstr, &privlen) < 0) + if (ober_get_nstring(encr, (void *)&privstr, &privlen) < 0 || + (buf = malloc(privlen)) == NULL) return NULL; scoped_pdu_len = usm_crypt(msg, privstr, (int)privlen, buf, 0); @@ -642,6 +645,7 @@ usm_decrypt(struct snmp_message *msg, struct ber_element *encr) #endif ober_free(&ber); + free(buf); return scoped_pdu; } -- cgit v1.2.3