mirror of
https://github.com/electron/electron.git
synced 2026-04-10 03:01:51 -04:00
chore: cherry-pick 2c26785, b03de8b and a3c3ef6 from usrsctp. (#27491)
* chore: cherry-pick 2c26785, b03de8b and a3c3ef6 from usrsctp. * update patches Co-authored-by: Electron Bot <electron@github.com>
This commit is contained in:
@@ -15,5 +15,7 @@
|
||||
|
||||
"src/electron/patches/sqlite": "src/third_party/sqlite/src",
|
||||
|
||||
"src/electron/patches/icu": "src/third_party/icu"
|
||||
"src/electron/patches/icu": "src/third_party/icu",
|
||||
|
||||
"src/electron/patches/usrsctp": "src/third_party/usrsctp/usrsctplib"
|
||||
}
|
||||
|
||||
3
patches/usrsctp/.patches
Normal file
3
patches/usrsctp/.patches
Normal file
@@ -0,0 +1,3 @@
|
||||
cherry_picking_improve_the_input_validation_and_processing_of.patch
|
||||
cherry_picking_clean_up_more_resources_of_an_existing_sctp.patch
|
||||
cherry_picking_harden_the_handling_of_outgoing_streams.patch
|
||||
@@ -0,0 +1,104 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Tuexen <tuexen@fh-muenster.de>
|
||||
Date: Sat, 12 Dec 2020 23:30:59 +0100
|
||||
Subject: Cherry picking: Clean up more resouces of an existing SCTP
|
||||
association in case of a restart.
|
||||
|
||||
This fixes a use-after-free scenario, which was reported by Felix
|
||||
Wilhelm from Google in case a peer is able to modify the cookie.
|
||||
However, this can also be triggered by an assciation restart under
|
||||
some specific conditions.
|
||||
|
||||
diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c
|
||||
index e2f03c73165d8e1ecd08b9f103afe03a3d2adb7f..669b2b2131d6e1e844f98fc10547db1715e6a0bd 100755
|
||||
--- a/usrsctplib/netinet/sctp_input.c
|
||||
+++ b/usrsctplib/netinet/sctp_input.c
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 366248 2020-09-29 09:36:06Z tuexen $");
|
||||
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 368593 2020-12-12 22:23:45Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@@ -1595,6 +1595,11 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
struct sctp_association *asoc;
|
||||
struct sctp_init_chunk *init_cp, init_buf;
|
||||
struct sctp_init_ack_chunk *initack_cp, initack_buf;
|
||||
+ struct sctp_asconf_addr *aparam, *naparam;
|
||||
+ struct sctp_asconf_ack *aack, *naack;
|
||||
+ struct sctp_tmit_chunk *chk, *nchk;
|
||||
+ struct sctp_stream_reset_list *strrst, *nstrrst;
|
||||
+ struct sctp_queued_to_read *sq, *nsq;
|
||||
struct sctp_nets *net;
|
||||
struct mbuf *op_err;
|
||||
struct timeval old;
|
||||
@@ -1891,8 +1896,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
* kick us so it COULD still take a timeout
|
||||
* to move these.. but it can't hurt to mark them.
|
||||
*/
|
||||
- struct sctp_tmit_chunk *chk;
|
||||
- TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
|
||||
+ TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
|
||||
if (chk->sent < SCTP_DATAGRAM_RESEND) {
|
||||
chk->sent = SCTP_DATAGRAM_RESEND;
|
||||
sctp_flight_size_decrease(chk);
|
||||
@@ -2084,6 +2088,57 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
stcb->asoc.strmout[i].next_mid_unordered = 0;
|
||||
stcb->asoc.strmout[i].last_msg_incomplete = 0;
|
||||
}
|
||||
+ TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
|
||||
+ TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
|
||||
+ SCTP_FREE(strrst, SCTP_M_STRESET);
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) {
|
||||
+ TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next);
|
||||
+ if (sq->data) {
|
||||
+ sctp_m_freem(sq->data);
|
||||
+ sq->data = NULL;
|
||||
+ }
|
||||
+ sctp_free_remote_addr(sq->whoFrom);
|
||||
+ sq->whoFrom = NULL;
|
||||
+ sq->stcb = NULL;
|
||||
+ sctp_free_a_readq(stcb, sq);
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
|
||||
+ TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
|
||||
+ if (chk->data) {
|
||||
+ sctp_m_freem(chk->data);
|
||||
+ chk->data = NULL;
|
||||
+ }
|
||||
+ if (chk->holds_key_ref)
|
||||
+ sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
+ sctp_free_remote_addr(chk->whoTo);
|
||||
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
|
||||
+ SCTP_DECR_CHK_COUNT();
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(chk, &asoc->asconf_send_queue, sctp_next, nchk) {
|
||||
+ TAILQ_REMOVE(&asoc->asconf_send_queue, chk, sctp_next);
|
||||
+ if (chk->data) {
|
||||
+ sctp_m_freem(chk->data);
|
||||
+ chk->data = NULL;
|
||||
+ }
|
||||
+ if (chk->holds_key_ref)
|
||||
+ sctp_auth_key_release(stcb, chk->auth_keyid, SCTP_SO_LOCKED);
|
||||
+ sctp_free_remote_addr(chk->whoTo);
|
||||
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_chunk), chk);
|
||||
+ SCTP_DECR_CHK_COUNT();
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(aparam, &asoc->asconf_queue, next, naparam) {
|
||||
+ TAILQ_REMOVE(&asoc->asconf_queue, aparam, next);
|
||||
+ SCTP_FREE(aparam,SCTP_M_ASC_ADDR);
|
||||
+ }
|
||||
+ TAILQ_FOREACH_SAFE(aack, &asoc->asconf_ack_sent, next, naack) {
|
||||
+ TAILQ_REMOVE(&asoc->asconf_ack_sent, aack, next);
|
||||
+ if (aack->data != NULL) {
|
||||
+ sctp_m_freem(aack->data);
|
||||
+ }
|
||||
+ SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), aack);
|
||||
+ }
|
||||
+
|
||||
/* process the INIT-ACK info (my info) */
|
||||
asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
|
||||
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
|
||||
@@ -0,0 +1,54 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Tuexen <tuexen@fh-muenster.de>
|
||||
Date: Mon, 14 Dec 2020 00:57:51 +0100
|
||||
Subject: Cherry picking: Harden the handling of outgoing streams in case of an
|
||||
restart or INIT collision.
|
||||
|
||||
This avouds an out-of-bounce access in case the peer can
|
||||
break the cookie signature. Thanks to Felix Wilhelm from Google for
|
||||
reporting the issue.
|
||||
|
||||
diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c
|
||||
index 669b2b2131d6e1e844f98fc10547db1715e6a0bd..6a5bdba4264b47e10766467255dd9ebd5d135556 100755
|
||||
--- a/usrsctplib/netinet/sctp_input.c
|
||||
+++ b/usrsctplib/netinet/sctp_input.c
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 368593 2020-12-12 22:23:45Z tuexen $");
|
||||
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 368622 2020-12-13 23:51:51Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@@ -1886,7 +1886,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
NULL);
|
||||
}
|
||||
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
|
||||
- asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
|
||||
+ if (asoc->pre_open_streams < asoc->streamoutcnt) {
|
||||
+ asoc->pre_open_streams = asoc->streamoutcnt;
|
||||
+ }
|
||||
|
||||
if (ntohl(init_cp->init.initiate_tag) != asoc->peer_vtag) {
|
||||
/* Ok the peer probably discarded our
|
||||
@@ -2040,8 +2042,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
|
||||
/* move to OPEN state, if not in SHUTDOWN_SENT */
|
||||
SCTP_SET_STATE(stcb, SCTP_STATE_OPEN);
|
||||
}
|
||||
- asoc->pre_open_streams =
|
||||
- ntohs(initack_cp->init.num_outbound_streams);
|
||||
+ if (asoc->pre_open_streams < asoc->streamoutcnt) {
|
||||
+ asoc->pre_open_streams = asoc->streamoutcnt;
|
||||
+ }
|
||||
asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
|
||||
asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
|
||||
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
|
||||
@@ -2361,7 +2364,6 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
/* process the INIT-ACK info (my info) */
|
||||
asoc->my_vtag = ntohl(initack_cp->init.initiate_tag);
|
||||
asoc->my_rwnd = ntohl(initack_cp->init.a_rwnd);
|
||||
- asoc->pre_open_streams = ntohs(initack_cp->init.num_outbound_streams);
|
||||
asoc->init_seq_number = ntohl(initack_cp->init.initial_tsn);
|
||||
asoc->sending_seq = asoc->asconf_seq_out = asoc->str_reset_seq_out = asoc->init_seq_number;
|
||||
asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
|
||||
@@ -0,0 +1,127 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Tuexen <tuexen@fh-muenster.de>
|
||||
Date: Tue, 29 Sep 2020 11:38:11 +0200
|
||||
Subject: Cherry picking: Improve the input validation and processing of
|
||||
cookies.
|
||||
|
||||
This avoids setting the association in an inconsistent
|
||||
state, which could result in a use-after-free situation.
|
||||
The issue can be triggered by a malicious peer, if the peer
|
||||
can modify the cookie without the local endpoint recognizing it.
|
||||
|
||||
Thanks to Ned Williamson for reporting the issue.
|
||||
|
||||
diff --git a/usrsctplib/netinet/sctp_input.c b/usrsctplib/netinet/sctp_input.c
|
||||
index 2555eacd68a9bf8c5a29ee190ee6fc03f5c7699c..e2f03c73165d8e1ecd08b9f103afe03a3d2adb7f 100755
|
||||
--- a/usrsctplib/netinet/sctp_input.c
|
||||
+++ b/usrsctplib/netinet/sctp_input.c
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 364268 2020-08-16 11:50:37Z tuexen $");
|
||||
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 366248 2020-09-29 09:36:06Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@@ -2260,10 +2260,6 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
vrf_id, port);
|
||||
return (NULL);
|
||||
}
|
||||
- /* get the correct sctp_nets */
|
||||
- if (netp)
|
||||
- *netp = sctp_findnet(stcb, init_src);
|
||||
-
|
||||
asoc = &stcb->asoc;
|
||||
/* get scope variables out of cookie */
|
||||
asoc->scope.ipv4_local_scope = cookie->ipv4_scope;
|
||||
@@ -2320,10 +2316,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
asoc->advanced_peer_ack_point = asoc->last_acked_seq;
|
||||
|
||||
/* process the INIT info (peer's info) */
|
||||
- if (netp)
|
||||
- retval = sctp_process_init(init_cp, stcb);
|
||||
- else
|
||||
- retval = 0;
|
||||
+ retval = sctp_process_init(init_cp, stcb);
|
||||
if (retval < 0) {
|
||||
#if defined(__APPLE__) && !defined(__Userspace__)
|
||||
atomic_add_int(&stcb->asoc.refcnt, 1);
|
||||
@@ -2506,19 +2499,21 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
|
||||
*/
|
||||
;
|
||||
}
|
||||
- /* since we did not send a HB make sure we don't double things */
|
||||
- if ((netp) && (*netp))
|
||||
- (*netp)->hb_responded = 1;
|
||||
-
|
||||
if (stcb->asoc.sctp_autoclose_ticks &&
|
||||
sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL);
|
||||
}
|
||||
(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
|
||||
- if ((netp != NULL) && (*netp != NULL)) {
|
||||
+ *netp = sctp_findnet(stcb, init_src);
|
||||
+ if (*netp != NULL) {
|
||||
struct timeval old;
|
||||
|
||||
- /* calculate the RTT and set the encaps port */
|
||||
+ /*
|
||||
+ * Since we did not send a HB, make sure we don't double
|
||||
+ * things.
|
||||
+ */
|
||||
+ (*netp)->hb_responded = 1;
|
||||
+ /* Calculate the RTT. */
|
||||
old.tv_sec = cookie->time_entered.tv_sec;
|
||||
old.tv_usec = cookie->time_entered.tv_usec;
|
||||
sctp_calculate_rto(stcb, asoc, *netp, &old, SCTP_RTT_FROM_NON_DATA);
|
||||
diff --git a/usrsctplib/netinet/sctp_pcb.c b/usrsctplib/netinet/sctp_pcb.c
|
||||
index 2bae796e5ad5c7cc490ceb4fa01c5cc448499232..f439c78eb45969f46cc47ca90cd710279b675071 100755
|
||||
--- a/usrsctplib/netinet/sctp_pcb.c
|
||||
+++ b/usrsctplib/netinet/sctp_pcb.c
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
#if defined(__FreeBSD__) && !defined(__Userspace__)
|
||||
#include <sys/cdefs.h>
|
||||
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 364268 2020-08-16 11:50:37Z tuexen $");
|
||||
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 366248 2020-09-29 09:36:06Z tuexen $");
|
||||
#endif
|
||||
|
||||
#include <netinet/sctp_os.h>
|
||||
@@ -4997,7 +4997,15 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
if ((ntohs(sin->sin_port) == 0) ||
|
||||
(sin->sin_addr.s_addr == INADDR_ANY) ||
|
||||
(sin->sin_addr.s_addr == INADDR_BROADCAST) ||
|
||||
- IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
|
||||
+ IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) ||
|
||||
+#if defined(__Userspace__)
|
||||
+ (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) != 0) ||
|
||||
+ (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) != 0) &&
|
||||
+ (SCTP_IPV6_V6ONLY(inp) != 0)))) {
|
||||
+#else
|
||||
+ (((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) != 0) &&
|
||||
+ (SCTP_IPV6_V6ONLY(inp) != 0))) {
|
||||
+#endif
|
||||
/* Invalid address */
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
|
||||
@@ -5016,7 +5024,8 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
sin6 = (struct sockaddr_in6 *)firstaddr;
|
||||
if ((ntohs(sin6->sin6_port) == 0) ||
|
||||
IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
|
||||
- IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
|
||||
+ IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) ||
|
||||
+ ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)) {
|
||||
/* Invalid address */
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
|
||||
@@ -5034,7 +5043,8 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
|
||||
|
||||
sconn = (struct sockaddr_conn *)firstaddr;
|
||||
if ((ntohs(sconn->sconn_port) == 0) ||
|
||||
- (sconn->sconn_addr == NULL)) {
|
||||
+ (sconn->sconn_addr == NULL) ||
|
||||
+ ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) == 0)) {
|
||||
/* Invalid address */
|
||||
SCTP_INP_RUNLOCK(inp);
|
||||
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
|
||||
Reference in New Issue
Block a user