Re: Fix memory leak in LibreSSL/tls_conninfo_free()

2017-01-09 Thread Shuo Chen
On Mon, Jan 9, 2017 at 7:31 AM, Joel Sing <j...@sing.id.au> wrote:
> On Sunday 08 January 2017 07:59:34 Shuo Chen wrote:
>> Valgrind finds out that conninfo->servername is not free()d by
>> tls_conninfo_free().
>>
>> Here's a quick fix.
>
> Committed, thanks!

Thank you!



Fix busy-looping in netcat's TLS handshaking

2017-01-07 Thread Shuo Chen
When doing TLS handshaking, netcat does it in a busy-looping way,
because the socket fd is set to non-blocking.

do {
if ((i = tls_handshake(tls_ctx)) == -1)
errx(1, "tls handshake failed (%s)",
tls_error(tls_ctx));
} while (i == TLS_WANT_POLLIN || i == TLS_WANT_POLLOUT);

strace(1) shows many lines like this:

04:20:25.566148 read(4, 0x15cae23, 5)   = -1 EAGAIN (Resource
temporarily unavailable)
04:20:25.566214 read(4, 0x15cae23, 5)   = -1 EAGAIN (Resource
temporarily unavailable)
04:20:25.566280 read(4, 0x15cae23, 5)   = -1 EAGAIN (Resource
temporarily unavailable)
04:20:25.566343 read(4, 0x15cae23, 5)   = -1 EAGAIN (Resource
temporarily unavailable)
04:20:25.566409 read(4, 0x15cae23, 5)   = -1 EAGAIN (Resource
temporarily unavailable)
04:20:25.566475 read(4, 0x15cae23, 5)   = -1 EAGAIN (Resource
temporarily unavailable)

I added a handshake() function and replaced busy-looping with poll()ing.

Regards,
Shuo Chen



diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c
--- a/src/usr.bin/nc/netcat.c
+++ b/src/usr.bin/nc/netcat.c
@@ -713,21 +713,41 @@ unix_bind(char *path, int flags)
return (s);
 }
 
+int
+handshake(int sockfd, struct tls *tls_ctx)
+{
+   struct pollfd pfd;
+   int ret;
+
+   bzero(, sizeof(pfd));
+   pfd.fd = sockfd;
+   while ((ret = tls_handshake(tls_ctx)) != 0) {
+   if (ret == -1)
+   break;
+   pfd.events = 0;
+   if (ret == TLS_WANT_POLLIN)
+   pfd.events = POLLIN;
+   else if (ret == TLS_WANT_POLLOUT)
+   pfd.events = POLLOUT;
+   if (pfd.events == 0)
+   err(1, "no events");
+   else if (poll(, 1, -1) == -1)
+   err(1, "poll");
+   }
+   return (ret);
+}
+
 void
 tls_setup_client(struct tls *tls_ctx, int s, char *host)
 {
-   int i;
-
if (tls_connect_socket(tls_ctx, s,
tls_expectname ? tls_expectname : host) == -1) {
errx(1, "tls connection failed (%s)",
tls_error(tls_ctx));
}
-   do {
-   if ((i = tls_handshake(tls_ctx)) == -1)
-   errx(1, "tls handshake failed (%s)",
-   tls_error(tls_ctx));
-   } while (i == TLS_WANT_POLLIN || i == TLS_WANT_POLLOUT);
+   if (handshake(s, tls_ctx) == -1)
+   errx(1, "tls handshake failed (%s)",
+   tls_error(tls_ctx));
if (vflag)
report_tls(tls_ctx, host, tls_expectname);
if (tls_expecthash && tls_peer_cert_hash(tls_ctx) &&
@@ -745,14 +765,9 @@ tls_setup_server(struct tls *tls_ctx, int
warnx("tls accept failed (%s)",
tls_error(tls_ctx));
tls_cctx = NULL;
-   } else {
-   int i;
-
-   do {
-   if ((i = tls_handshake(tls_cctx)) == -1)
-   warnx("tls handshake failed (%s)",
-   tls_error(tls_cctx));
-   } while(i == TLS_WANT_POLLIN || i == TLS_WANT_POLLOUT);
+   } else if (handshake(connfd, tls_cctx) == -1) {
+   warnx("tls handshake failed (%s)",
+   tls_error(tls_cctx));
}
if (tls_cctx) {
int gotcert = tls_peer_cert_provided(tls_cctx);