Skip to content

Commit 24ae3c7

Browse files
tuexenmibrunin
authored andcommitted
[Backport] CVE-2020-16044: Use after free in WebRTC [1/3]
Manual cherry-pick of patch originally committed to usrsctp: https://chromium.googlesource.com/external/github.com/sctplab/usrsctp/+/2c26785bed47cf18e127c516ab242b4e3781ed20 : 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. Related to Chromium bug 1163228 Change-Id: I724b797b2c3e6865fd54af085e9f71f04db668d1 Reviewed-by: Allan Sandfeld Jensen <[email protected]>
1 parent d3a7e0a commit 24ae3c7

File tree

2 files changed

+24
-19
lines changed

2 files changed

+24
-19
lines changed

chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_input.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
#ifdef __FreeBSD__
3636
#include <sys/cdefs.h>
37-
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 355135 2019-11-27 19:32:29Z tuexen $");
37+
__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 366248 2020-09-29 09:36:06Z tuexen $");
3838
#endif
3939

4040
#include <netinet/sctp_os.h>
@@ -2272,10 +2272,6 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
22722272
vrf_id, port);
22732273
return (NULL);
22742274
}
2275-
/* get the correct sctp_nets */
2276-
if (netp)
2277-
*netp = sctp_findnet(stcb, init_src);
2278-
22792275
asoc = &stcb->asoc;
22802276
/* get scope variables out of cookie */
22812277
asoc->scope.ipv4_local_scope = cookie->ipv4_scope;
@@ -2332,10 +2328,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
23322328
asoc->advanced_peer_ack_point = asoc->last_acked_seq;
23332329

23342330
/* process the INIT info (peer's info) */
2335-
if (netp)
2336-
retval = sctp_process_init(init_cp, stcb);
2337-
else
2338-
retval = 0;
2331+
retval = sctp_process_init(init_cp, stcb);
23392332
if (retval < 0) {
23402333
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
23412334
atomic_add_int(&stcb->asoc.refcnt, 1);
@@ -2518,19 +2511,21 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
25182511
*/
25192512
;
25202513
}
2521-
/* since we did not send a HB make sure we don't double things */
2522-
if ((netp) && (*netp))
2523-
(*netp)->hb_responded = 1;
2524-
25252514
if (stcb->asoc.sctp_autoclose_ticks &&
25262515
sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE)) {
25272516
sctp_timer_start(SCTP_TIMER_TYPE_AUTOCLOSE, inp, stcb, NULL);
25282517
}
25292518
(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
2530-
if ((netp != NULL) && (*netp != NULL)) {
2519+
*netp = sctp_findnet(stcb, init_src);
2520+
if (*netp != NULL) {
25312521
struct timeval old;
25322522

2533-
/* calculate the RTT and set the encaps port */
2523+
/*
2524+
* Since we did not send a HB, make sure we don't double
2525+
* things.
2526+
*/
2527+
(*netp)->hb_responded = 1;
2528+
/* Calculate the RTT. */
25342529
old.tv_sec = cookie->time_entered.tv_sec;
25352530
old.tv_usec = cookie->time_entered.tv_usec;
25362531
sctp_calculate_rto(stcb, asoc, *netp, &old, SCTP_RTT_FROM_NON_DATA);

chromium/third_party/usrsctp/usrsctplib/usrsctplib/netinet/sctp_pcb.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
#ifdef __FreeBSD__
3636
#include <sys/cdefs.h>
37-
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 356377 2020-01-05 14:06:40Z tuexen $");
37+
__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 366248 2020-09-29 09:36:06Z tuexen $");
3838
#endif
3939

4040
#include <netinet/sctp_os.h>
@@ -5011,7 +5011,15 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
50115011
if ((ntohs(sin->sin_port) == 0) ||
50125012
(sin->sin_addr.s_addr == INADDR_ANY) ||
50135013
(sin->sin_addr.s_addr == INADDR_BROADCAST) ||
5014-
IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
5014+
IN_MULTICAST(ntohl(sin->sin_addr.s_addr)) ||
5015+
#if defined(__Userspace__)
5016+
(((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) != 0) ||
5017+
(((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) != 0) &&
5018+
(SCTP_IPV6_V6ONLY(inp) != 0)))) {
5019+
#else
5020+
(((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) != 0) &&
5021+
(SCTP_IPV6_V6ONLY(inp) != 0))) {
5022+
#endif
50155023
/* Invalid address */
50165024
SCTP_INP_RUNLOCK(inp);
50175025
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
@@ -5030,7 +5038,8 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
50305038
sin6 = (struct sockaddr_in6 *)firstaddr;
50315039
if ((ntohs(sin6->sin6_port) == 0) ||
50325040
IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
5033-
IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
5041+
IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr) ||
5042+
((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)) {
50345043
/* Invalid address */
50355044
SCTP_INP_RUNLOCK(inp);
50365045
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
@@ -5048,7 +5057,8 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
50485057

50495058
sconn = (struct sockaddr_conn *)firstaddr;
50505059
if ((ntohs(sconn->sconn_port) == 0) ||
5051-
(sconn->sconn_addr == NULL)) {
5060+
(sconn->sconn_addr == NULL) ||
5061+
((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_CONN) == 0)) {
50525062
/* Invalid address */
50535063
SCTP_INP_RUNLOCK(inp);
50545064
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);

0 commit comments

Comments
 (0)