Pankaj Sharma - 2015-09-14

This issue (token#354) is to prevent the resource leaks in case of exceptional flow code.
Request you to please review it and close.
Issue as : "Resource leak (RESOURCE_LEAK)- leaked_handle: Handle variable "fd" going out of scope leaks the handle."

Description:

Assigning local "fd" by handled return from "socket(sa->sa_family, SOCK_STREAM, 0)" ;
when successfully handled opened by socket(). at line :367

-Case 1:
if evutil_make_socket_nonblocking(fd) has been gotten failed in making non-blocking ;
then it's jumping to label "done:" before closing opened handle, hence leaked.

-Case 2:
if "ownfd" is assigned to "1" at line :372 .
it means that the local "fd" is assigned by "socket(sa->sa_family, SOCK_STREAM, 0)" at line :367
and every cases of jumping to label "done:" there is no check of "ownfd" for local socket() creation ,cause "Resource Leak (fd)".

Impact:

This socket leaks can lead to crashes, denial of service, and the inability to open more files or sockets. After the limit is reached, the process must close some of the resources' open handles before allocating more and If the process has leaked these handles, there is no way to reclaim these resources until the process terminates.

Solution :

So, need to set "ownfd" to 1 when soket() creation is successful at above "if (evutil_make_socket_nonblocking(fd)<0)" line:370
and need to check "ownfd" in label "done:" before "return result".

The patch is already attached for respective changes as:

diff -Naur a/libevent-2.0.22-stable/bufferevent_sock.c b/libevent-2.0.22-stable/bufferevent_sock.c
--- a/libevent-2.0.22-stable/bufferevent_sock.c 2015-04-27 16:15:53.210942586 +0530
+++ b/libevent-2.0.22-stable/bufferevent_sock.c 2015-04-28 14:32:55.022856747 +0530
@@ -373,9 +373,9 @@
fd = socket(sa->sa_family, SOCK_STREAM, 0);
if (fd < 0)
goto done;
+ ownfd = 1;
if (evutil_make_socket_nonblocking(fd)<0)
goto done;
- ownfd = 1;
}
if (sa) {
#ifdef WIN32
@@ -426,10 +426,10 @@

freesock:
_bufferevent_run_eventcb(bev, BEV_EVENT_ERROR);
+done:
if (ownfd)
evutil_closesocket(fd);
/ do something about the error? /
-done:
_bufferevent_decref_and_unlock(bev);
return result;
}