From d8440f4d711a654b511f50f79c0445b26f9dd1e1 Mon Sep 17 00:00:00 2001 From: Nanang Izzuddin Date: Tue, 20 Dec 2022 11:39:12 +0700 Subject: [PATCH] Merge pull request from GHSA-9pfh-r8x4-w26w * Fix buffer overread in STUN message decoder * Updates based on comments --- pjnath/include/pjnath/stun_msg.h | 4 ++++ pjnath/src/pjnath/stun_msg.c | 14 +++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pjnath/include/pjnath/stun_msg.h b/pjnath/include/pjnath/stun_msg.h index b52f95c586..e49f096f3a 100644 --- a/pjnath/include/pjnath/stun_msg.h +++ b/pjnath/include/pjnath/stun_msg.h @@ -442,6 +442,7 @@ typedef enum pj_stun_status \endverbatim */ +#pragma pack(1) typedef struct pj_stun_msg_hdr { /** @@ -473,6 +474,7 @@ typedef struct pj_stun_msg_hdr pj_uint8_t tsx_id[12]; } pj_stun_msg_hdr; +#pragma pack() /** @@ -490,6 +492,7 @@ typedef struct pj_stun_msg_hdr \endverbatim */ +#pragma pack(1) typedef struct pj_stun_attr_hdr { /** @@ -506,6 +509,7 @@ typedef struct pj_stun_attr_hdr pj_uint16_t length; } pj_stun_attr_hdr; +#pragma pack() /** diff --git a/pjnath/src/pjnath/stun_msg.c b/pjnath/src/pjnath/stun_msg.c index 3def6b3eac..e904a0ba47 100644 --- a/pjnath/src/pjnath/stun_msg.c +++ b/pjnath/src/pjnath/stun_msg.c @@ -746,7 +746,7 @@ PJ_DEF(int) pj_stun_set_padding_char(int chr) #define INIT_ATTR(a,t,l) (a)->hdr.type=(pj_uint16_t)(t), \ (a)->hdr.length=(pj_uint16_t)(l) -#define ATTR_HDR_LEN 4 +#define ATTR_HDR_LEN sizeof(pj_stun_attr_hdr) static pj_uint16_t GETVAL16H(const pj_uint8_t *buf, unsigned pos) { @@ -2327,6 +2327,14 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool, status = pj_stun_msg_check(pdu, pdu_len, options); if (status != PJ_SUCCESS) return status; + } else { + /* For safety, verify packet length at least */ + pj_uint32_t msg_len = GETVAL16H(pdu, 2) + 20; + if (msg_len > pdu_len || + ((options & PJ_STUN_IS_DATAGRAM) && msg_len != pdu_len)) + { + return PJNATH_EINSTUNMSGLEN; + } } /* Create the message, copy the header, and convert to host byte order */ @@ -2345,7 +2353,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool, p_response = NULL; /* Parse attributes */ - while (pdu_len >= 4) { + while (pdu_len >= ATTR_HDR_LEN) { unsigned attr_type, attr_val_len; const struct attr_desc *adesc; @@ -2357,7 +2365,7 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool, attr_val_len = (attr_val_len + 3) & (~3); /* Check length */ - if (pdu_len < attr_val_len) { + if (pdu_len < attr_val_len + ATTR_HDR_LEN) { pj_str_t err_msg; char err_msg_buf[80];