1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
From: Tzafrir Cohen <tzafrir@debian.org>
Subject: Resolve crashes due to large stack allocations when using TCP
Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=378269
CVE: CVE-2012-5976
Bug: https://issues.asterisk.org/jira/browse/ASTERISK-20658
This patch fixes similar issues to the above in Asterisk 1.6.2: both the
chan_sip TCP code and HTTP server code included loops that accepted an
unlimited ammount of input from an unauthenticated user before properly
parsing them. This patch adds some limits to the ammount recieved from
each such connection.
See also: http://downloads.asterisk.org/pub/security/AST-2012-014.html
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -544,6 +544,7 @@ static int mwi_expiry = DEFAULT_MWI_EXPI
#define SIP_MAX_HEADERS 64 /*!< Max amount of SIP headers to read */
#define SIP_MAX_LINES 256 /*!< Max amount of lines in SIP attachment (like SDP) */
+#define SIP_MAX_PACKET_SIZE 20480 /*!< Max SIP packet size */
#define SIP_MIN_PACKET 4096 /*!< Initialize size of memory to allocate for packets */
#define MAX_HISTORY_ENTRIES 50 /*!< Max entires in the history list for a sip_pvt */
@@ -3078,7 +3079,7 @@ static void *_sip_tcp_helper_thread(stru
req.socket.fd = tcptls_session->fd;
/* Read in headers one line at a time */
- while (req.len < 4 || strncmp(REQ_OFFSET_TO_STR(&req, len - 4), "\r\n\r\n", 4)) {
+ while ((req.len <= SIP_MAX_PACKET_SIZE) && (req.len < 4 || strncmp(REQ_OFFSET_TO_STR(&req, len - 4), "\r\n\r\n", 4))) {
if (!tcptls_session->client && !authenticated ) {
if ((timeout = sip_check_authtimeout(start)) < 0) {
goto cleanup;
--- a/main/http.c
+++ b/main/http.c
@@ -54,6 +54,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revisi
#define MAX_PREFIX 80
#define DEFAULT_SESSION_LIMIT 100
+#define MAX_HEAD_SIZE 8192
/* See http.h for more information about the SSL implementation */
#if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE))
@@ -664,6 +665,7 @@ static void *httpd_helper_thread(void *d
{
char buf[4096];
char cookie[4096];
+ int header_len = 0;
struct ast_tcptls_session_instance *ser = data;
struct ast_variable *vars=NULL, *headers = NULL;
char *uri, *title=NULL;
@@ -696,12 +698,15 @@ static void *httpd_helper_thread(void *d
}
/* process "Cookie: " lines */
- while (fgets(cookie, sizeof(cookie), ser->f)) {
+ while (header_len <= MAX_HEAD_SIZE && fgets(cookie, sizeof(cookie), ser->f)) {
+ int len;
/* Trim trailing characters */
ast_trim_blanks(cookie);
- if (ast_strlen_zero(cookie)) {
+ len = strlen(cookie); /* FIXME: not real length. Blanks removed */
+ if (len == 0) {
break;
}
+ header_len += len;
if (!strncasecmp(cookie, "Cookie: ", 8)) {
vars = parse_cookies(cookie);
} else {
|