bundled_pjproject: Backport security fixes from pjproject 2.13.1
Merge-pull-request-from-GHSA-9pfh-r8x4-w26w.patch Merge-pull-request-from-GHSA-cxwq-5g9x-x7fr.patch Locking-fix-so-that-SSL_shutdown-and-SSL_write-are-n.patch Don-t-call-SSL_shutdown-when-receiving-SSL_ERROR_SYS.patch Resolves: #188
This commit is contained in:
parent
6df35a1a6f
commit
05b45ca303
203
third-party/pjproject/patches/0300-Merge-pull-request-from-GHSA-9pfh-r8x4-w26w.patch
vendored
Normal file
203
third-party/pjproject/patches/0300-Merge-pull-request-from-GHSA-9pfh-r8x4-w26w.patch
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
From 3ba8f3c0188fa05bb62d8bc9176ca7c7db79f8c0 Mon Sep 17 00:00:00 2001
|
||||
From: Nanang Izzuddin <nanang@teluu.com>
|
||||
Date: Tue, 20 Dec 2022 11:39:12 +0700
|
||||
Subject: [PATCH 300/303] 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 | 32 ++++++++++++++++++++------------
|
||||
2 files changed, 24 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/pjnath/include/pjnath/stun_msg.h b/pjnath/include/pjnath/stun_msg.h
|
||||
index 6b5fc0f21..e8f52db3c 100644
|
||||
--- a/pjnath/include/pjnath/stun_msg.h
|
||||
+++ b/pjnath/include/pjnath/stun_msg.h
|
||||
@@ -436,20 +436,21 @@ typedef enum pj_stun_status
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
Transaction ID
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
\endverbatim
|
||||
*/
|
||||
+#pragma pack(1)
|
||||
typedef struct pj_stun_msg_hdr
|
||||
{
|
||||
/**
|
||||
* STUN message type, which the first two bits must be zeroes.
|
||||
*/
|
||||
pj_uint16_t type;
|
||||
|
||||
/**
|
||||
* The message length is the size, in bytes, of the message not
|
||||
* including the 20 byte STUN header.
|
||||
@@ -467,53 +468,56 @@ typedef struct pj_stun_msg_hdr
|
||||
* The transaction ID is a 96 bit identifier. STUN transactions are
|
||||
* identified by their unique 96-bit transaction ID. For request/
|
||||
* response transactions, the transaction ID is chosen by the STUN
|
||||
* client and MUST be unique for each new STUN transaction generated by
|
||||
* that STUN client. The transaction ID MUST be uniformly and randomly
|
||||
* distributed between 0 and 2**96 - 1.
|
||||
*/
|
||||
pj_uint8_t tsx_id[12];
|
||||
|
||||
} pj_stun_msg_hdr;
|
||||
+#pragma pack()
|
||||
|
||||
|
||||
/**
|
||||
* This structre describes STUN attribute header. Each attribute is
|
||||
* TLV encoded, with a 16 bit type, 16 bit length, and variable value.
|
||||
* Each STUN attribute ends on a 32 bit boundary:
|
||||
*
|
||||
* \verbatim
|
||||
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Type | Length |
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
\endverbatim
|
||||
*/
|
||||
+#pragma pack(1)
|
||||
typedef struct pj_stun_attr_hdr
|
||||
{
|
||||
/**
|
||||
* STUN attribute type.
|
||||
*/
|
||||
pj_uint16_t type;
|
||||
|
||||
/**
|
||||
* The Length refers to the length of the actual useful content of the
|
||||
* Value portion of the attribute, measured in bytes. The value
|
||||
* in the Length field refers to the length of the Value part of the
|
||||
* attribute prior to padding - i.e., the useful content.
|
||||
*/
|
||||
pj_uint16_t length;
|
||||
|
||||
} pj_stun_attr_hdr;
|
||||
+#pragma pack()
|
||||
|
||||
|
||||
/**
|
||||
* This structure describes STUN generic IP address attribute, used for
|
||||
* example to represent STUN MAPPED-ADDRESS attribute.
|
||||
*
|
||||
* The generic IP address attribute indicates the transport address.
|
||||
* It consists of an eight bit address family, and a sixteen bit port,
|
||||
* followed by a fixed length value representing the IP address. If the
|
||||
* address family is IPv4, the address is 32 bits, in network byte
|
||||
diff --git a/pjnath/src/pjnath/stun_msg.c b/pjnath/src/pjnath/stun_msg.c
|
||||
index bd83351e6..fd15230bc 100644
|
||||
--- a/pjnath/src/pjnath/stun_msg.c
|
||||
+++ b/pjnath/src/pjnath/stun_msg.c
|
||||
@@ -739,22 +739,22 @@ PJ_DEF(int) pj_stun_set_padding_char(int chr)
|
||||
int old_pad = padding_char;
|
||||
padding_char = chr;
|
||||
return old_pad;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#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
|
||||
+ (a)->hdr.length=(pj_uint16_t)(l)
|
||||
+#define ATTR_HDR_LEN sizeof(pj_stun_attr_hdr)
|
||||
|
||||
static pj_uint16_t GETVAL16H(const pj_uint8_t *buf, unsigned pos)
|
||||
{
|
||||
return (pj_uint16_t) ((buf[pos + 0] << 8) | \
|
||||
(buf[pos + 1] << 0));
|
||||
}
|
||||
|
||||
/*unused PJ_INLINE(pj_uint16_t) GETVAL16N(const pj_uint8_t *buf, unsigned pos)
|
||||
{
|
||||
return pj_htons(GETVAL16H(buf,pos));
|
||||
@@ -2318,56 +2318,64 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
|
||||
PJ_ASSERT_RETURN(pool && pdu && pdu_len && p_msg, PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(sizeof(pj_stun_msg_hdr) == 20, PJ_EBUG);
|
||||
|
||||
if (p_parsed_len)
|
||||
*p_parsed_len = 0;
|
||||
if (p_response)
|
||||
*p_response = NULL;
|
||||
|
||||
/* Check if this is a STUN message, if necessary */
|
||||
if (options & PJ_STUN_CHECK_PACKET) {
|
||||
- status = pj_stun_msg_check(pdu, pdu_len, options);
|
||||
- if (status != PJ_SUCCESS)
|
||||
- return status;
|
||||
+ 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 */
|
||||
msg = PJ_POOL_ZALLOC_T(pool, pj_stun_msg);
|
||||
pj_memcpy(&msg->hdr, pdu, sizeof(pj_stun_msg_hdr));
|
||||
msg->hdr.type = pj_ntohs(msg->hdr.type);
|
||||
msg->hdr.length = pj_ntohs(msg->hdr.length);
|
||||
msg->hdr.magic = pj_ntohl(msg->hdr.magic);
|
||||
|
||||
pdu += sizeof(pj_stun_msg_hdr);
|
||||
/* pdu_len -= sizeof(pj_stun_msg_hdr); */
|
||||
pdu_len = msg->hdr.length;
|
||||
|
||||
/* No need to create response if this is not a request */
|
||||
if (!PJ_STUN_IS_REQUEST(msg->hdr.type))
|
||||
p_response = NULL;
|
||||
|
||||
/* Parse attributes */
|
||||
- while (pdu_len >= 4) {
|
||||
- unsigned attr_type, attr_val_len;
|
||||
- const struct attr_desc *adesc;
|
||||
+ while (pdu_len >= ATTR_HDR_LEN) {
|
||||
+ unsigned attr_type, attr_val_len;
|
||||
+ const struct attr_desc *adesc;
|
||||
|
||||
/* Get attribute type and length. If length is not aligned
|
||||
* to 4 bytes boundary, add padding.
|
||||
*/
|
||||
attr_type = GETVAL16H(pdu, 0);
|
||||
attr_val_len = GETVAL16H(pdu, 2);
|
||||
attr_val_len = (attr_val_len + 3) & (~3);
|
||||
|
||||
- /* Check length */
|
||||
- if (pdu_len < attr_val_len) {
|
||||
- pj_str_t err_msg;
|
||||
- char err_msg_buf[80];
|
||||
+ /* Check length */
|
||||
+ if (pdu_len < attr_val_len + ATTR_HDR_LEN) {
|
||||
+ pj_str_t err_msg;
|
||||
+ char err_msg_buf[80];
|
||||
|
||||
err_msg.ptr = err_msg_buf;
|
||||
err_msg.slen = pj_ansi_snprintf(err_msg_buf, sizeof(err_msg_buf),
|
||||
"Attribute %s has invalid length",
|
||||
pj_stun_get_attr_name(attr_type));
|
||||
|
||||
PJ_LOG(4,(THIS_FILE, "Error decoding message: %.*s",
|
||||
(int)err_msg.slen, err_msg.ptr));
|
||||
|
||||
if (p_response) {
|
||||
--
|
||||
2.41.0
|
||||
|
81
third-party/pjproject/patches/0301-Merge-pull-request-from-GHSA-cxwq-5g9x-x7fr.patch
vendored
Normal file
81
third-party/pjproject/patches/0301-Merge-pull-request-from-GHSA-cxwq-5g9x-x7fr.patch
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
From 02d2273f085943b7d8daf7814d9b316216cae26b Mon Sep 17 00:00:00 2001
|
||||
From: sauwming <ming@teluu.com>
|
||||
Date: Fri, 23 Dec 2022 15:05:28 +0800
|
||||
Subject: [PATCH 301/303] Merge pull request from GHSA-cxwq-5g9x-x7fr
|
||||
|
||||
* Fixed heap buffer overflow when parsing STUN errcode attribute
|
||||
|
||||
* Also fixed uint parsing
|
||||
---
|
||||
pjnath/src/pjnath/stun_msg.c | 11 ++++++-----
|
||||
1 file changed, 6 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/pjnath/src/pjnath/stun_msg.c b/pjnath/src/pjnath/stun_msg.c
|
||||
index fd15230bc..d3aaae5bf 100644
|
||||
--- a/pjnath/src/pjnath/stun_msg.c
|
||||
+++ b/pjnath/src/pjnath/stun_msg.c
|
||||
@@ -1432,26 +1432,26 @@ static pj_status_t decode_uint_attr(pj_pool_t *pool,
|
||||
void **p_attr)
|
||||
{
|
||||
pj_stun_uint_attr *attr;
|
||||
|
||||
PJ_UNUSED_ARG(msghdr);
|
||||
|
||||
/* Create the attribute */
|
||||
attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint_attr);
|
||||
GETATTRHDR(buf, &attr->hdr);
|
||||
|
||||
- attr->value = GETVAL32H(buf, 4);
|
||||
-
|
||||
/* Check that the attribute length is valid */
|
||||
if (attr->hdr.length != 4)
|
||||
return PJNATH_ESTUNINATTRLEN;
|
||||
|
||||
+ attr->value = GETVAL32H(buf, 4);
|
||||
+
|
||||
/* Done */
|
||||
*p_attr = attr;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf,
|
||||
unsigned len,
|
||||
const pj_stun_msg_hdr *msghdr,
|
||||
@@ -1751,28 +1751,29 @@ static pj_status_t decode_errcode_attr(pj_pool_t *pool,
|
||||
{
|
||||
pj_stun_errcode_attr *attr;
|
||||
pj_str_t value;
|
||||
|
||||
PJ_UNUSED_ARG(msghdr);
|
||||
|
||||
/* Create the attribute */
|
||||
attr = PJ_POOL_ZALLOC_T(pool, pj_stun_errcode_attr);
|
||||
GETATTRHDR(buf, &attr->hdr);
|
||||
|
||||
+ /* Check that the attribute length is valid */
|
||||
+ if (attr->hdr.length < 4)
|
||||
+ return PJNATH_ESTUNINATTRLEN;
|
||||
+
|
||||
attr->err_code = buf[6] * 100 + buf[7];
|
||||
|
||||
/* Get pointer to the string in the message */
|
||||
value.ptr = ((char*)buf + ATTR_HDR_LEN + 4);
|
||||
value.slen = attr->hdr.length - 4;
|
||||
- /* Make sure the length is never negative */
|
||||
- if (value.slen < 0)
|
||||
- value.slen = 0;
|
||||
|
||||
/* Copy the string to the attribute */
|
||||
pj_strdup(pool, &attr->reason, &value);
|
||||
|
||||
/* Done */
|
||||
*p_attr = attr;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
--
|
||||
2.41.0
|
||||
|
166
third-party/pjproject/patches/0302-Locking-fix-so-that-SSL_shutdown-and-SSL_write-are-n.patch
vendored
Normal file
166
third-party/pjproject/patches/0302-Locking-fix-so-that-SSL_shutdown-and-SSL_write-are-n.patch
vendored
Normal file
|
@ -0,0 +1,166 @@
|
|||
From 0a3af5f1a0f64fd30f35338b8328391283d88ecb Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Fredrickson <mfredrickson@fluentstream.com>
|
||||
Date: Tue, 30 May 2023 04:33:05 -0500
|
||||
Subject: [PATCH 302/303] Locking fix so that SSL_shutdown and SSL_write are
|
||||
not called at same time (#3583)
|
||||
|
||||
---
|
||||
pjlib/src/pj/ssl_sock_ossl.c | 82 ++++++++++++++++++++++--------------
|
||||
1 file changed, 51 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
|
||||
index ed441e3e2..5c8e67b76 100644
|
||||
--- a/pjlib/src/pj/ssl_sock_ossl.c
|
||||
+++ b/pjlib/src/pj/ssl_sock_ossl.c
|
||||
@@ -1627,44 +1627,58 @@ static void ssl_destroy(pj_ssl_sock_t *ssock)
|
||||
/* Potentially shutdown OpenSSL library if this is the last
|
||||
* context exists.
|
||||
*/
|
||||
shutdown_openssl();
|
||||
}
|
||||
|
||||
|
||||
/* Reset SSL socket state */
|
||||
static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
|
||||
{
|
||||
+ int post_unlock_flush_circ_buf = 0;
|
||||
+
|
||||
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
|
||||
|
||||
+ /* Must lock around SSL calls, particularly SSL_shutdown
|
||||
+ * as it can modify the write BIOs and destructively
|
||||
+ * interfere with any ssl_write() calls in progress
|
||||
+ * above in a multithreaded environment */
|
||||
+ pj_lock_acquire(ssock->write_mutex);
|
||||
+
|
||||
/* Detach from SSL instance */
|
||||
if (ossock->ossl_ssl) {
|
||||
SSL_set_ex_data(ossock->ossl_ssl, sslsock_idx, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoid calling SSL_shutdown() if handshake wasn't completed.
|
||||
* OpenSSL 1.0.2f complains if SSL_shutdown() is called during an
|
||||
* SSL handshake, while previous versions always return 0.
|
||||
*/
|
||||
if (ossock->ossl_ssl && SSL_in_init(ossock->ossl_ssl) == 0) {
|
||||
- int ret = SSL_shutdown(ossock->ossl_ssl);
|
||||
- if (ret == 0) {
|
||||
- /* Flush data to send close notify. */
|
||||
- flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
|
||||
- }
|
||||
+ int ret = SSL_shutdown(ossock->ossl_ssl);
|
||||
+ if (ret == 0) {
|
||||
+ /* SSL_shutdown will potentially trigger a bunch of
|
||||
+ * data to dump to the socket */
|
||||
+ post_unlock_flush_circ_buf = 1;
|
||||
+ }
|
||||
}
|
||||
|
||||
- pj_lock_acquire(ssock->write_mutex);
|
||||
ssock->ssl_state = SSL_STATE_NULL;
|
||||
+
|
||||
pj_lock_release(ssock->write_mutex);
|
||||
|
||||
+ if (post_unlock_flush_circ_buf) {
|
||||
+ /* Flush data to send close notify. */
|
||||
+ flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
|
||||
+ }
|
||||
+
|
||||
ssl_close_sockets(ssock);
|
||||
|
||||
/* Upon error, OpenSSL may leave any error description in the thread
|
||||
* error queue, which sometime may cause next call to SSL API returning
|
||||
* false error alarm, e.g: in Linux, SSL_CTX_use_certificate_chain_file()
|
||||
* returning false error after a handshake error (in different SSL_CTX!).
|
||||
* For now, just clear thread error queue here.
|
||||
*/
|
||||
ERR_clear_error();
|
||||
}
|
||||
@@ -2330,52 +2344,58 @@ static pj_status_t ssl_read(pj_ssl_sock_t *ssock, void *data, int *size)
|
||||
{
|
||||
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
|
||||
int size_ = *size;
|
||||
int len = size_;
|
||||
|
||||
/* SSL_read() may write some data to write buffer when re-negotiation
|
||||
* is on progress, so let's protect it with write mutex.
|
||||
*/
|
||||
pj_lock_acquire(ssock->write_mutex);
|
||||
*size = size_ = SSL_read(ossock->ossl_ssl, data, size_);
|
||||
- pj_lock_release(ssock->write_mutex);
|
||||
|
||||
if (size_ <= 0) {
|
||||
pj_status_t status;
|
||||
int err = SSL_get_error(ossock->ossl_ssl, size_);
|
||||
|
||||
- /* SSL might just return SSL_ERROR_WANT_READ in
|
||||
- * re-negotiation.
|
||||
- */
|
||||
- if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ) {
|
||||
- if (err == SSL_ERROR_SYSCALL && size_ == -1 &&
|
||||
- ERR_peek_error() == 0 && errno == 0)
|
||||
- {
|
||||
- status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
|
||||
- err, len);
|
||||
- PJ_LOG(4,("SSL", "SSL_read() = -1, with "
|
||||
- "SSL_ERROR_SYSCALL, no SSL error, "
|
||||
- "and errno = 0 - skip BIO error"));
|
||||
- /* Ignore these errors */
|
||||
- } else {
|
||||
- /* Reset SSL socket state, then return PJ_FALSE */
|
||||
- status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
|
||||
- err, len);
|
||||
- ssl_reset_sock_state(ssock);
|
||||
- return status;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* Need renegotiation */
|
||||
- return PJ_EEOF;
|
||||
+ /* SSL might just return SSL_ERROR_WANT_READ in
|
||||
+ * re-negotiation.
|
||||
+ */
|
||||
+ if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ) {
|
||||
+ if (err == SSL_ERROR_SYSCALL && size_ == -1 &&
|
||||
+ ERR_peek_error() == 0 && errno == 0)
|
||||
+ {
|
||||
+ status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
|
||||
+ err, len);
|
||||
+ PJ_LOG(4,("SSL", "SSL_read() = -1, with "
|
||||
+ "SSL_ERROR_SYSCALL, no SSL error, "
|
||||
+ "and errno = 0 - skip BIO error"));
|
||||
+ /* Ignore these errors */
|
||||
+ } else {
|
||||
+ /* Reset SSL socket state, then return PJ_FALSE */
|
||||
+ status = STATUS_FROM_SSL_ERR2("Read", ssock, size_,
|
||||
+ err, len);
|
||||
+ pj_lock_release(ssock->write_mutex);
|
||||
+ /* Unfortunately we can't hold the lock here to reset all the state.
|
||||
+ * We probably should though.
|
||||
+ */
|
||||
+ ssl_reset_sock_state(ssock);
|
||||
+ return status;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ pj_lock_release(ssock->write_mutex);
|
||||
+ /* Need renegotiation */
|
||||
+ return PJ_EEOF;
|
||||
}
|
||||
|
||||
+ pj_lock_release(ssock->write_mutex);
|
||||
+
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Write plain data to SSL and flush write BIO. */
|
||||
static pj_status_t ssl_write(pj_ssl_sock_t *ssock, const void *data,
|
||||
pj_ssize_t size, int *nwritten)
|
||||
{
|
||||
ossl_sock_t *ossock = (ossl_sock_t *)ssock;
|
||||
pj_status_t status = PJ_SUCCESS;
|
||||
--
|
||||
2.41.0
|
||||
|
123
third-party/pjproject/patches/0303-Don-t-call-SSL_shutdown-when-receiving-SSL_ERROR_SYS.patch
vendored
Normal file
123
third-party/pjproject/patches/0303-Don-t-call-SSL_shutdown-when-receiving-SSL_ERROR_SYS.patch
vendored
Normal file
|
@ -0,0 +1,123 @@
|
|||
From 0f7267f220be79e21cf9f96efa01929285e9aa55 Mon Sep 17 00:00:00 2001
|
||||
From: Riza Sulistyo <trengginas@users.noreply.github.com>
|
||||
Date: Wed, 5 Jul 2023 10:38:21 +0700
|
||||
Subject: [PATCH 303/303] Don't call SSL_shutdown() when receiving
|
||||
SSL_ERROR_SYSCALL or SSL_ERROR_SSL (#3577)
|
||||
|
||||
---
|
||||
pjlib/src/pj/ssl_sock_imp_common.c | 1 +
|
||||
pjlib/src/pj/ssl_sock_imp_common.h | 13 +++++++------
|
||||
pjlib/src/pj/ssl_sock_ossl.c | 17 ++++++++++++-----
|
||||
3 files changed, 20 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/pjlib/src/pj/ssl_sock_imp_common.c b/pjlib/src/pj/ssl_sock_imp_common.c
|
||||
index ae2f1136e..c825676c3 100644
|
||||
--- a/pjlib/src/pj/ssl_sock_imp_common.c
|
||||
+++ b/pjlib/src/pj/ssl_sock_imp_common.c
|
||||
@@ -237,20 +237,21 @@ static void ssl_close_sockets(pj_ssl_sock_t *ssock)
|
||||
#endif
|
||||
|
||||
/* When handshake completed:
|
||||
* - notify application
|
||||
* - if handshake failed, reset SSL state
|
||||
* - return PJ_FALSE when SSL socket instance is destroyed by application.
|
||||
*/
|
||||
static pj_bool_t on_handshake_complete(pj_ssl_sock_t *ssock,
|
||||
pj_status_t status)
|
||||
{
|
||||
+ ssock->handshake_status = status;
|
||||
/* Cancel handshake timer */
|
||||
if (ssock->timer.id == TIMER_HANDSHAKE_TIMEOUT) {
|
||||
pj_timer_heap_cancel(ssock->param.timer_heap, &ssock->timer);
|
||||
ssock->timer.id = TIMER_NONE;
|
||||
}
|
||||
|
||||
/* Update certificates info on successful handshake */
|
||||
if (status == PJ_SUCCESS)
|
||||
ssl_update_certs_info(ssock);
|
||||
|
||||
diff --git a/pjlib/src/pj/ssl_sock_imp_common.h b/pjlib/src/pj/ssl_sock_imp_common.h
|
||||
index cba28dbd3..8a63faa90 100644
|
||||
--- a/pjlib/src/pj/ssl_sock_imp_common.h
|
||||
+++ b/pjlib/src/pj/ssl_sock_imp_common.h
|
||||
@@ -99,26 +99,27 @@ struct pj_ssl_sock_t
|
||||
* information allocation. Don't use for
|
||||
* other purposes. */
|
||||
pj_ssl_sock_t *parent;
|
||||
pj_ssl_sock_param param;
|
||||
pj_ssl_sock_param newsock_param;
|
||||
pj_ssl_cert_t *cert;
|
||||
|
||||
pj_ssl_cert_info local_cert_info;
|
||||
pj_ssl_cert_info remote_cert_info;
|
||||
|
||||
- pj_bool_t is_server;
|
||||
- enum ssl_state ssl_state;
|
||||
- pj_ioqueue_op_key_t handshake_op_key;
|
||||
- pj_ioqueue_op_key_t shutdown_op_key;
|
||||
- pj_timer_entry timer;
|
||||
- pj_status_t verify_status;
|
||||
+ pj_bool_t is_server;
|
||||
+ enum ssl_state ssl_state;
|
||||
+ pj_ioqueue_op_key_t handshake_op_key;
|
||||
+ pj_ioqueue_op_key_t shutdown_op_key;
|
||||
+ pj_timer_entry timer;
|
||||
+ pj_status_t verify_status;
|
||||
+ pj_status_t handshake_status;
|
||||
|
||||
pj_bool_t is_closing;
|
||||
unsigned long last_err;
|
||||
|
||||
pj_sock_t sock;
|
||||
pj_activesock_t *asock;
|
||||
|
||||
pj_sockaddr local_addr;
|
||||
pj_sockaddr rem_addr;
|
||||
int addr_len;
|
||||
diff --git a/pjlib/src/pj/ssl_sock_ossl.c b/pjlib/src/pj/ssl_sock_ossl.c
|
||||
index 5c8e67b76..8a717e362 100644
|
||||
--- a/pjlib/src/pj/ssl_sock_ossl.c
|
||||
+++ b/pjlib/src/pj/ssl_sock_ossl.c
|
||||
@@ -1646,27 +1646,34 @@ static void ssl_reset_sock_state(pj_ssl_sock_t *ssock)
|
||||
|
||||
/* Detach from SSL instance */
|
||||
if (ossock->ossl_ssl) {
|
||||
SSL_set_ex_data(ossock->ossl_ssl, sslsock_idx, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Avoid calling SSL_shutdown() if handshake wasn't completed.
|
||||
* OpenSSL 1.0.2f complains if SSL_shutdown() is called during an
|
||||
* SSL handshake, while previous versions always return 0.
|
||||
+ * Call SSL_shutdown() when there is a timeout handshake failure or
|
||||
+ * the last error is not SSL_ERROR_SYSCALL and not SSL_ERROR_SSL.
|
||||
*/
|
||||
if (ossock->ossl_ssl && SSL_in_init(ossock->ossl_ssl) == 0) {
|
||||
- int ret = SSL_shutdown(ossock->ossl_ssl);
|
||||
- if (ret == 0) {
|
||||
- /* SSL_shutdown will potentially trigger a bunch of
|
||||
- * data to dump to the socket */
|
||||
- post_unlock_flush_circ_buf = 1;
|
||||
+ if (ssock->handshake_status == PJ_ETIMEDOUT ||
|
||||
+ (ssock->last_err != SSL_ERROR_SYSCALL &&
|
||||
+ ssock->last_err != SSL_ERROR_SSL))
|
||||
+ {
|
||||
+ int ret = SSL_shutdown(ossock->ossl_ssl);
|
||||
+ if (ret == 0) {
|
||||
+ /* SSL_shutdown will potentially trigger a bunch of
|
||||
+ * data to dump to the socket */
|
||||
+ post_unlock_flush_circ_buf = 1;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
ssock->ssl_state = SSL_STATE_NULL;
|
||||
|
||||
pj_lock_release(ssock->write_mutex);
|
||||
|
||||
if (post_unlock_flush_circ_buf) {
|
||||
/* Flush data to send close notify. */
|
||||
flush_circ_buf_output(ssock, &ssock->shutdown_op_key, 0, 0);
|
||||
--
|
||||
2.41.0
|
||||
|
Loading…
Reference in New Issue