From: martijn Date: Tue, 20 Dec 2022 20:01:25 +0000 (+0000) Subject: When writing out a PDU with authpriv that's larger than READ_BUF_SIZE X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=5d518481432a0e7cc6f870f8015b12d640a28de0;p=openbsd 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@ --- 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; }