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,