Selaa lähdekoodia

- added low_mem_threshold1 & low_mem_threshold2 (the ammount of free memory
from which tls operations will start to fail preemptively is now configurable;
by default the value depends on the number of processes)
- doc update

Andrei Pelinescu-Onciul 18 vuotta sitten
vanhempi
commit
66fff017aa

+ 97 - 7
modules/tls/README

@@ -78,10 +78,49 @@ Important Notes
    The tls module includes workarounds for the following known openssl
    bugs: openssl #1204 (disable SS_OP_TLS_BLOCK_PADDING_BUG if
    compression is enabled, for versions between 0.9.8 and 0.9.8c),
-   openssl #1468 (fix zlib compression memory allocation) and openssl
-   #1467 (kerberos support will be disabled if openssl version less than
-   0.9.8e-beta1). The bug reports can be viewed at
-   http://rt.openssl.org/.
+   openssl #1468 (fix zlib compression memory allocation), openssl #1467
+   (kerberos support will be disabled if the openssl version is less than
+   0.9.8e-beta1) and openssl #1491 (stop using tls in low memory
+   situations due to the very high risk of openssl crashing or leaking
+   memory). The bug reports can be viewed at http://rt.openssl.org/.
+
+Compiling the TLS Module
+
+   In most case compiling the TLS module is as simple as:
+make modules modules=modules/tls
+
+   or
+cd modules/tls
+make
+
+   or (compiling whole ser and the tls module)
+make all include_modules=tls
+
+   .
+
+   However in some cases the openssl library requires linking with other
+   libraries. For example compiling the openssl library with kerberos and
+   zlib-shared support will require linking the tls module with libkrb5
+   and libz. In this case just add TLS_EXTRA_LIBS="library list" to
+   make's command line. E.g.:
+make TLS_EXTRA_LIBS="-lkrb5 -lz" all include_modules=tls
+
+   In general, if ser fails to start with a symbol not found error when
+   trying to load the tls module (check the log), it means some needed
+   library was not linked and it must be added to TLS_EXTRA_LIBS
+
+TLS and Low Memory
+
+   The openssl library doesn't handle very well low memory situations. If
+   memory allocations start to fail (due to memory shortage), openssl can
+   crash or cause memory leaks (making the memory shortage even worse).
+   As of this writing all openssl versions were affected (includind
+   0.9.8e), see openssl bug #1491. The tls module has some workarounds
+   for preventing this problem (see low_mem_treshold1 and
+   low_mem_threshold2), however starting ser with enough shared memory is
+   higly recommended. When this is not possible a quick way to
+   significantly reduce openssl memory usage it to disable compression
+   (see tls_disable_compression).
 
 Known Limitations
 
@@ -383,6 +422,57 @@ tls_log (int)
 modparam("tls", "tls_log", 10)
 ...
 
+low_mem_threshold1 (integer)
+
+   Sets the minimal free memory from which new tls connection will start
+   to fail. The value is expressed in KB.
+
+   The default value depends on whether the openssl library used handles
+   well low memory situations (openssl bug #1491). As of this writing
+   this is not true for any openssl version (including 0.9.8e).
+
+   If an ill-behaved openssl version is detected, a very conservative
+   value is choosed, which depends on the maximum possible number of
+   simultaneously created tls connections (and hence on the process
+   number).
+
+   The following values have a special meaning:
+     * -1 - use the default value
+     * 0 - disable (tls connections will not fail preemptively)
+
+   See also low_mem_threshold2.
+
+   Example 15. Set low_memory_threshold1 parameter
+...
+modparam("tls", "low_memory_threshold1", -1)
+...
+
+low_mem_threshold2 (integer)
+
+   Sets the minimal free memory from which tls operations on already
+   established tls connections will start to fail preemptively. The value
+   is expressed in KB.
+
+   The default value depends on whether the openssl library used handles
+   well low memory situations (openssl bug #1491). As of this writing
+   this is not true for any openssl version (including 0.9.8e).
+
+   If an ill-behaved openssl version is detected, a very conservative
+   value is choosed, which depends on the maximum possible number of
+   simultaneously created tls connections (and hence on the process
+   number).
+
+   The following values have a special meaning:
+     * -1 - use the default value
+     * 0 - disable (tls operations will not fail preemptively)
+
+   See also low_mem_threshold1.
+
+   Example 16. Set low_memory_threshold2 parameter
+...
+modparam("tls", "low_memory_threshold2", -1)
+...
+
 tls_force_run (boolean)
 
    If enabled ser will start even if some of the openssl sanity checks
@@ -399,7 +489,7 @@ tls_force_run (boolean)
 
    By default tls_force_run is disabled.
 
-   Example 15. Set tls_force_run parameter
+   Example 17. Set tls_force_run parameter
 ...
 modparam("tls", "tls_force_run", 11)
 ...
@@ -429,7 +519,7 @@ config (string)
    ser acts as a server when it accepts a connection and as a client when
    it initiates a new connection by itself (it connects to something).
 
-   Example 16. Short config file
+   Example 18. Short config file
 [server:default]
 method = TLSv1
 verify_certificate = no
@@ -455,7 +545,7 @@ ca_list = local_ca.pem
    For a more complete example check the tls.cfg distributed with the ser
    source (sip_router/modules/tls/tls.cfg).
 
-   Example 17. Set config parameter
+   Example 19. Set config parameter
 ...
 modparam("tls", "config", "/usr/local/etc/ser/tls.cfg")
 ...

+ 78 - 0
modules/tls/doc/params.xml

@@ -292,6 +292,84 @@ modparam("tls", "tls_log", 10)
 	</example>
 	</section>
 
+<section id="low_mem_threshold1">
+	<title><varname>low_mem_threshold1</varname> (integer)</title>
+	<para>
+		Sets the minimal free memory from which new tls connection will start to fail. The value is expressed in KB.
+	</para>
+	<para>
+		The default value depends on whether the openssl library used handles well low memory situations (openssl bug #1491). As of this writing this is not true for any openssl version (including 0.9.8e).
+	</para>
+	<para>
+		If an ill-behaved openssl version is detected, a very conservative value is choosed, which depends on the maximum possible number of simultaneously created tls connections (and hence on the process number).
+	</para>
+	<para>
+		The following values have a special meaning:
+	</para>
+	<itemizedlist>
+			<listitem>
+				<para>
+					-1 - use the default value
+				</para>
+			</listitem>
+			<listitem>
+				<para>
+					0 - disable (tls connections will not fail preemptively)
+				</para>
+			</listitem>
+	</itemizedlist>
+	<para>
+		See also <varname>low_mem_threshold2</varname>.
+	</para>
+	<example>
+		<title>Set <varname>low_memory_threshold1</varname> parameter</title>
+		<programlisting>
+...
+modparam("tls", "low_memory_threshold1", -1)
+...
+	</programlisting>
+	</example>
+	</section>
+
+<section id="low_mem_threshold2">
+	<title><varname>low_mem_threshold2</varname> (integer)</title>
+	<para>
+		Sets the minimal free memory from which tls operations on already established tls connections will start to fail preemptively.  The value is expressed in KB.
+	</para>
+	<para>
+		The default value depends on whether the openssl library used handles well low memory situations (openssl bug #1491). As of this writing this is not true for any openssl version (including 0.9.8e).
+	</para>
+	<para>
+		If an ill-behaved openssl version is detected, a very conservative value is choosed, which depends on the maximum possible number of simultaneously created tls connections (and hence on the process number).
+	</para>
+	<para>
+		The following values have a special meaning:
+	</para>
+	<itemizedlist>
+			<listitem>
+				<para>
+					-1 - use the default value
+				</para>
+			</listitem>
+			<listitem>
+				<para>
+					0 - disable (tls operations will not fail preemptively)
+				</para>
+			</listitem>
+	</itemizedlist>
+	<para>
+		See also <varname>low_mem_threshold1</varname>.
+	</para>
+	<example>
+		<title>Set <varname>low_memory_threshold2</varname> parameter</title>
+		<programlisting>
+...
+modparam("tls", "low_memory_threshold2", -1)
+...
+	</programlisting>
+	</example>
+	</section>
+
 	<section id="tls_force_run">
 	<title><varname>tls_force_run</varname> (boolean)</title>
 	<para>

+ 38 - 0
modules/tls/doc/tls.xml

@@ -77,6 +77,44 @@ route{
   <ulink url="http://rt.openssl.org/">http://rt.openssl.org/</ulink>.
 		</para>
 		</section>
+
+
+		<section id="tls.compile">
+		<title>Compiling the TLS Module</title>
+		<para>
+			In most case compiling the TLS module is as simple as:
+			<programlisting>
+make modules modules=modules/tls
+			</programlisting>
+			or
+			<programlisting>
+cd modules/tls
+make
+			</programlisting>
+			or (compiling whole ser and the tls module)
+			<programlisting>
+make all include_modules=tls
+			</programlisting>
+			.
+		</para>
+		<para>
+			However in some cases the openssl library requires linking with other libraries. For example compiling the openssl library with kerberos and zlib-shared support will require linking the tls module with libkrb5 and libz. In this case just add  <emphasis>TLS_EXTRA_LIBS</emphasis>="library list" to make's command line. E.g.:
+			<programlisting>
+make TLS_EXTRA_LIBS="-lkrb5 -lz" all include_modules=tls
+			</programlisting>
+		</para>
+		<para>
+			In general, if ser fails to start with a symbol not found error when trying to load the tls module (check the log), it means some needed library was not linked and it must be added to <emphasis>TLS_EXTRA_LIBS</emphasis>
+		</para>
+		</section>
+
+		<section id="tls.low_memory">
+		<title>TLS and Low Memory</title>
+		<para>
+			The openssl library doesn't handle very well low memory situations. If memory allocations start to fail (due to memory shortage), openssl can crash or cause memory leaks (making the memory shortage even worse). As of this writing all openssl versions were affected (includind 0.9.8e), see openssl bug #1491. The tls module has some workarounds for preventing this problem (see <varname>low_mem_treshold1</varname> and <varname>low_mem_threshold2</varname>), however starting ser with enough shared memory is higly recommended. When this is not possible a quick way to significantly reduce openssl memory usage it to  disable compression (see <varname>tls_disable_compression</varname>).
+		</para>
+		</section>
+
 		<section id="tls.known_limitations">
 		<title>Known Limitations</title>
 		<para>

+ 24 - 6
modules/tls/tls_init.c

@@ -102,7 +102,8 @@ to compile on the  _target_ system)"
 #ifdef TLS_KSSL_WORKARROUND
 int openssl_kssl_malloc_bug=0; /* is openssl bug #1467 present ? */
 #endif
-int openssl_low_mem_bug=0; /* openssl bug #1491 workaround */
+int openssl_mem_threshold1=-1; /* low memory threshold for connect/accept */
+int openssl_mem_threshold2=-1; /* like above but for other tsl operations */
 int tls_disable_compression = 0; /* by default enabled */
 int tls_force_run = 0; /* ignore some start-up sanity checks, use it
 						  at your own risk */
@@ -533,15 +534,32 @@ int init_tls_h(void)
 			" kerberos support will be disabled...\n");
 	}
 	#endif
-	LOG(L_WARN, "tls: init_tls_h: openssl low memory bugs (#1491) workaround"
-				" enabled (on low memory tls operations will fail"
-				" preemptively)\n");
-	openssl_low_mem_bug=1; /* openssl bug #1491 workaround, for now
-								always enabled */
+	 /* set free memory threshold for openssl bug #1491 workaround */
+	if (openssl_mem_threshold1<0){
+		/* default */
+		openssl_mem_threshold1=512*1024*get_max_procs();
+	}else
+		openssl_mem_threshold1*=1024; /* KB */
+	if (openssl_mem_threshold2<0){
+		/* default */
+		openssl_mem_threshold2=256*1024*get_max_procs();
+	}else
+		openssl_mem_threshold2*=1024; /* KB */
+	if ((openssl_mem_threshold1==0) || (openssl_mem_threshold2==0))
+		LOG(L_WARN, "tls: openssl bug #1491 (crash/mem leaks on low memory)"
+					" workarround disabled\n");
+	else
+		LOG(L_WARN, "tls: openssl bug #1491 (crash/mem leaks on low memory)"
+				" workaround enabled (on low memory tls operations will fail"
+				" preemptively) with free memory thresholds %d and %d bytes\n",
+				openssl_mem_threshold1, openssl_mem_threshold2);
+	
 	if (shm_available()==(unsigned long)(-1)){
 		LOG(L_WARN, "tls: ser compiled without MALLOC_STATS support:"
 				" the workaround for low mem. openssl bugs will _not_ "
 				"work\n");
+		openssl_mem_threshold1=0;
+		openssl_mem_threshold2=0;
 	}
 	SSL_library_init();
 	SSL_load_error_strings();

+ 2 - 1
modules/tls/tls_init.h

@@ -43,7 +43,8 @@
 #define TLS_KSSL_WORKARROUND
 extern int openssl_kssl_malloc_bug; /* is openssl bug #1467 present ? */
 #endif
-extern int openssl_low_mem_bug; /* openssl bug #1491 workarround */
+extern int openssl_mem_threshold1; /* low memory threshold for connect */
+extern int openssl_mem_threshold2; /* like above but for other tsl operations */
 
 
 extern int tls_disable_compression; /* by default enabled */

+ 2 - 0
modules/tls/tls_mod.c

@@ -208,6 +208,8 @@ static param_export_t params[] = {
 	{"config",              PARAM_STR,    &tls_cfg_file           },
 	{"tls_disable_compression", PARAM_INT,&tls_disable_compression},
 	{"tls_force_run",       PARAM_INT,    &tls_force_run},
+	{"low_mem_threshold1",       PARAM_INT,    &openssl_mem_threshold1},
+	{"low_mem_threshold2",       PARAM_INT,    &openssl_mem_threshold2},
 	{0, 0, 0}
 };
 

+ 11 - 9
modules/tls/tls_server.c

@@ -53,8 +53,10 @@
 #include "tls_server.h"
 
 /* low memory treshold for openssl bug #1491 workaround */
-#define MIN_FREE_MEM_NEW_CONNECTION	(512*1024*get_max_procs()) /* 512k*no*/
-#define MIN_FREE_MEM_CONNECTED		(256*1024*get_max_procs()) /* 128k*no*/
+#define LOW_MEM_NEW_CONNECTION_TEST() \
+	((openssl_mem_threshold1) && (shm_available()<openssl_mem_threshold1))
+#define LOW_MEM_CONNECTED_TEST() \
+	((openssl_mem_threshold2) && (shm_available()<openssl_mem_threshold2))
 
 /* 
  * finish the ssl init (creates the SSL and set extra_data to it)
@@ -67,7 +69,7 @@ static int tls_complete_init(struct tcp_connection* c)
 	struct tls_extra_data* data = 0;
 	tls_cfg_t* cfg;
 
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_NEW_CONNECTION)){
+	if (LOW_MEM_NEW_CONNECTION_TEST()){
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
 				" operation: %lu\n", shm_available());
 		goto error2;
@@ -142,7 +144,7 @@ static int tls_update_fd(struct tcp_connection *c, int fd)
 	if (!c->extra_data && tls_complete_init(c) < 0) {
 		ERR("Delayed init failed\n");
 		return -1;
-	}else if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_CONNECTED)){
+	}else if (LOW_MEM_CONNECTED_TEST()){
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
 				" operation: %lu\n", shm_available());
 		return -1;
@@ -304,7 +306,7 @@ static int tls_accept(struct tcp_connection *c, int* error)
 		     /* Not critical */
 		return 0;
 	}
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_NEW_CONNECTION)){
+	if (LOW_MEM_NEW_CONNECTION_TEST()){
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
 				" operation: %lu\n", shm_available());
 		goto err;
@@ -401,7 +403,7 @@ static int tls_connect(struct tcp_connection *c, int* error)
 		     /* Not critical */
 		return 0;
 	}
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_NEW_CONNECTION)){
+	if (LOW_MEM_NEW_CONNECTION_TEST()){
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
 				" operation: %lu\n", shm_available());
 		goto err;
@@ -498,7 +500,7 @@ static int tls_shutdown(struct tcp_connection *c)
 		ERR("No SSL data to perform tls_shutdown\n");
 		return -1;
 	}
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_CONNECTED)){
+	if (LOW_MEM_CONNECTED_TEST()){
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
 				" operation: %lu\n", shm_available());
 		goto err;
@@ -573,7 +575,7 @@ static int tls_write(struct tcp_connection *c, const void *buf, size_t len, int*
 	ssl = ((struct tls_extra_data*)c->extra_data)->ssl;
 
 	err = 0;
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_CONNECTED)){
+	if (LOW_MEM_CONNECTED_TEST()){
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
 				" operation: %lu\n", shm_available());
 		ret=-1;
@@ -818,7 +820,7 @@ int tls_h_read(struct tcp_connection * c)
 		r->error = TCP_REQ_OVERRUN;
 		return -1;
 	}
-	if (openssl_low_mem_bug && (shm_available()<MIN_FREE_MEM_CONNECTED)){
+	if (LOW_MEM_CONNECTED_TEST()){
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
 				" operation: %lu\n", shm_available());
 		return -1;