Bug 1632241: add SCTP auth token boundary check. r=ng, a=dveditz
Differential Revision:
https://phabricator.services.mozilla.com/D72053
--- a/netwerk/sctp/src/netinet/sctp_input.c
+++ b/netwerk/sctp/src/netinet/sctp_input.c
@@ -2173,17 +2173,17 @@ sctp_process_cookie_new(struct mbuf *m,
struct sctp_tcb *stcb;
struct sctp_init_chunk *init_cp, init_buf;
struct sctp_init_ack_chunk *initack_cp, initack_buf;
union sctp_sockstore store;
struct sctp_association *asoc;
int init_offset, initack_offset, initack_limit;
int retval;
int error = 0;
- uint8_t auth_chunk_buf[SCTP_PARAM_BUFFER_SIZE];
+ uint8_t auth_chunk_buf[SCTP_CHUNK_BUFFER_SIZE];
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
struct socket *so;
so = SCTP_INP_SO(inp);
#endif
/*
* find and validate the INIT chunk in the cookie (peer's info) the
@@ -2368,18 +2368,22 @@ sctp_process_cookie_new(struct mbuf *m,
*/
/* pull the local authentication parameters from the cookie/init-ack */
sctp_auth_get_cookie_params(stcb, m,
initack_offset + sizeof(struct sctp_init_ack_chunk),
initack_limit - (initack_offset + sizeof(struct sctp_init_ack_chunk)));
if (auth_skipped) {
struct sctp_auth_chunk *auth;
- auth = (struct sctp_auth_chunk *)
- sctp_m_getptr(m, auth_offset, auth_len, auth_chunk_buf);
+ if (auth_len <= SCTP_CHUNK_BUFFER_SIZE) {
+ auth = (struct sctp_auth_chunk *)
+ sctp_m_getptr(m, auth_offset, auth_len, auth_chunk_buf);
+ } else {
+ auth = NULL;
+ }
if ((auth == NULL) || sctp_handle_auth(stcb, auth, m, auth_offset)) {
/* auth HMAC failed, dump the assoc and packet */
SCTPDBG(SCTP_DEBUG_AUTH1,
"COOKIE-ECHO: AUTH failed\n");
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
atomic_add_int(&stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(stcb);
SCTP_SOCKET_LOCK(so, 1);
@@ -4844,21 +4848,25 @@ sctp_process_control(struct mbuf *m, int
*/
SCTP_INP_DECR_REF(inp);
}
/* now go back and verify any auth chunk to be sure */
if (auth_skipped && (stcb != NULL)) {
struct sctp_auth_chunk *auth;
- auth = (struct sctp_auth_chunk *)
- sctp_m_getptr(m, auth_offset,
+ if (auth_len <= SCTP_CHUNK_BUFFER_SIZE) {
+ auth = (struct sctp_auth_chunk *)
+ sctp_m_getptr(m, auth_offset,
auth_len, chunk_buf);
- got_auth = 1;
- auth_skipped = 0;
+ got_auth = 1;
+ auth_skipped = 0;
+ } else {
+ auth = NULL;
+ }
if ((auth == NULL) || sctp_handle_auth(stcb, auth, m,
auth_offset)) {
/* auth HMAC failed so dump it */
*offset = length;
return (stcb);
} else {
/* remaining chunks are HMAC checked */
stcb->asoc.authenticated = 1;