On Sun, Jan 2, 2011 at 02:34, Dmitry Semyonov wrote:

> I'm attaching new version of the patch. It fixes another missed crash
> at "else if (TLS_buffer[buf_end] != '\n')" line, as well as the same
> issues in duplicate code of SSL_readline().

Unfortunately, this was not enough. It is also necessary to fix code
which checks return values of SSL and TLS receive functions. Another
cumulative patch is attached. It should be applied to Debian version
instead of (rather than in addition to) all previously provided
patches.

Stephane, I'll send you upstream-based patch separately.

-- 
...Bye..Dmitry.
--- echoping-6.0.2.orig/echoping.h
+++ echoping-6.0.2/echoping.h
@@ -194,7 +194,7 @@
 int SSL_readline ();
 #endif
 #ifdef GNUTLS
-int TLS_readline ();
+ssize_t TLS_readline ();
 #endif
 /* util.c */
 char *random_string ();
--- echoping-6.0.2.orig/http.c
+++ echoping-6.0.2/http.c
@@ -68,7 +68,7 @@
 int
 read_from_server(CHANNEL fs, short ssl, boolean accept_redirects)
 {
-	int             nr = 0;
+	ssize_t		nr = 0;
 	int             total = 0;
 	char            reply_code;
 	int             first_line = TRUE;
@@ -82,7 +82,7 @@
 #ifdef OPENSSL
 		else {
 			nr = SSL_readline(fs.ssl, big_recvline, MAXTOREAD, TRUE);
-			if (nr == -1) {
+			if (nr < 0) {
 				sslcode = ERR_get_error();
 				err_ret("SSL_readline error: %s",
 					ERR_error_string(sslcode, NULL));
@@ -93,7 +93,7 @@
 		else
 		{
 			nr = TLS_readline(fs.tls, big_recvline, MAXTOREAD, TRUE);
-			if (nr == -1) {
+			if (nr < 0) {
 				err_ret("TLS_readline error: %s",
 					gnutls_strerror(nr));
 			}
@@ -141,7 +141,7 @@
 #endif
 #ifdef GNUTLS
 	else
-	nr = TLS_readline(fs.tls, big_recvline, MAXTOREAD, FALSE);
+		nr = TLS_readline(fs.tls, big_recvline, MAXTOREAD, FALSE);
 #endif
 	/* 
 	 * printf ("DEBUG: reading body \"%s\"\n (%d chars)\n", big_recvline,
--- echoping-6.0.2.orig/readline.c
+++ echoping-6.0.2/readline.c
@@ -65,8 +65,8 @@
 	if (ln) {
 		/* Empty buffer */
 		if (buf_end == 0) {
-			rc = SSL_read(sslh, SSL_buffer, maxlen);
-			if (rc == -1)
+			rc = SSL_read(sslh, SSL_buffer, maxlen > MAXTOREAD ? MAXTOREAD : maxlen);
+			if (rc < 0)
 				return rc;
 			buf_end = rc;
 			buf_ptr = 0;
@@ -74,25 +74,26 @@
 		/* No more data in the buffer */
 		else if (buf_ptr == buf_end) {
 			buf_ptr = 0;
-			rc = SSL_read(sslh, SSL_buffer, maxlen);
-			if (rc == -1)
+			rc = SSL_read(sslh, SSL_buffer, maxlen > MAXTOREAD ? MAXTOREAD : maxlen);
+			if (rc < 0)
 				return rc;
 			buf_end = rc;
-		} else if (SSL_buffer[buf_end] != '\n') {
+		} else if (SSL_buffer[buf_end - 1] != '\n') {
 			/* We have a probleme here is the first SSL_read sent back a 
 			 * text not finished by a \n. See www.SSL.de for an example. 
 			 * We get more data. See bug #230384 */
-			rc = SSL_read(sslh, SSL_buffer + buf_end, maxlen);
-			if (rc == -1)
+			rc = SSL_read(sslh, SSL_buffer + buf_end,
+				      maxlen > MAXTOREAD - buf_end ? MAXTOREAD - buf_end : maxlen);
+			if (rc < 0)
 				return rc;
 			buf_end = buf_end + rc;
 		}
 		for (oi = buf_ptr, i = buf_ptr;
-		     i <= buf_end && SSL_buffer[i] != '\n'; i++) {
+		     i < buf_end && SSL_buffer[i] != '\n'; i++) {
 			*ptr++ = SSL_buffer[i];
 			buf_ptr++;
 		}
-		if (SSL_buffer[i] == '\n')
+		if (i < buf_end && SSL_buffer[i] == '\n')
 			buf_ptr++;
 		*ptr = '\0';
 		/* if (ln) printf ("SSL_readline returns %d (%s)\n", i - oi,
@@ -126,21 +127,22 @@
 int             buf_ptr;
 int             buf_end;
 
-int
+ssize_t
 TLS_readline(session, ptr, maxlen, ln)
 	gnutls_session  session;
 	char           *ptr;
 	int             maxlen;
 	unsigned short  ln;
 {
-	int             rc = 0;
+	ssize_t         rc = 0;
 	int             n = 0;
 	int             i, oi;
 	if (ln) {
 		/* Empty buffer */
 		if (buf_end == 0) {
-			rc = gnutls_record_recv(session, TLS_buffer, maxlen);
-			if (rc == -1)
+			rc = gnutls_record_recv(session, TLS_buffer,
+					        maxlen > MAXTOREAD ? MAXTOREAD : maxlen);
+			if (rc < 0)
 				return rc;
 			buf_end = rc;
 			buf_ptr = 0;
@@ -148,23 +150,24 @@
 		/* No more data in the buffer */
 		else if (buf_ptr == buf_end) {
 			buf_ptr = 0;
-			rc = gnutls_record_recv(session, TLS_buffer, maxlen);
-			if (rc == -1)
+			rc = gnutls_record_recv(session, TLS_buffer,
+					        maxlen > MAXTOREAD ? MAXTOREAD : maxlen);
+			if (rc < 0)
 				return rc;
 			buf_end = rc;
-		} else if (TLS_buffer[buf_end] != '\n') {
+		} else if (TLS_buffer[buf_end - 1] != '\n') {
 			rc = gnutls_record_recv(session, TLS_buffer + buf_end,
-						maxlen);
-			if (rc == -1)
+						maxlen > MAXTOREAD - buf_end ? MAXTOREAD - buf_end : maxlen);
+			if (rc < 0)
 				return rc;
 			buf_end = buf_end + rc;
 		}
 		for (oi = buf_ptr, i = buf_ptr;
-		     i <= buf_end && TLS_buffer[i] != '\n'; i++) {
+		     i < buf_end && TLS_buffer[i] != '\n'; i++) {
 			*ptr++ = TLS_buffer[i];
 			buf_ptr++;
 		}
-		if (TLS_buffer[i] == '\n')
+		if (i < buf_end && TLS_buffer[i] == '\n')
 			buf_ptr++;
 		*ptr = '\0';
 		/* printf ("DEBUG: TLS_readline returns %d (%s)\n", i - oi,

Reply via email to