diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2016-11-26 14:51:45 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2017-04-14 11:06:09 +0200 |
commit | 719d1a38c67afb5e896d35bccb2cc3f922872ec8 (patch) | |
tree | c943ef810b7d73283ba0cebb802b2b0f128e8569 /src/stream.c | |
parent | a7d7dd220cd8a94ca6ee341620f0cd40815ec3b7 (diff) |
osmo_stream_srv_fd_cb(): don't leak socket FDs on errors
So far we seem to assume that the accept_cb does all handling of socket
fd cleanup. However, there are cases where there is no accept_cb set,
the accept_cb returns error, or an earlier sctp_sock_activate_events()
or the activation of non-blocking mode fails.
For those cases, close the socket and return an error code.
Fixes: CID#57915
Change-Id: I3a3ce9194ab7ca5c1921fc79c2a1c9e10a552cf0
Diffstat (limited to 'src/stream.c')
-rw-r--r-- | src/stream.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/src/stream.c b/src/stream.c index 591cd06..653f26b 100644 --- a/src/stream.c +++ b/src/stream.c @@ -529,6 +529,7 @@ struct osmo_stream_srv_link { static int osmo_stream_srv_fd_cb(struct osmo_fd *ofd, unsigned int what) { int ret; + int sock_fd; struct sockaddr_in sa; socklen_t sa_len = sizeof(sa); struct osmo_stream_srv_link *link = ofd->data; @@ -541,17 +542,33 @@ static int osmo_stream_srv_fd_cb(struct osmo_fd *ofd, unsigned int what) } LOGP(DLINP, LOGL_DEBUG, "accept()ed new link from %s to port %u\n", inet_ntoa(sa.sin_addr), link->port); + sock_fd = ret; - if (link->proto == IPPROTO_SCTP) - sctp_sock_activate_events(ret); + if (link->proto == IPPROTO_SCTP) { + ret = sctp_sock_activate_events(sock_fd); + if (ret < 0) + goto error_close_socket; + } - if (link->flags & OSMO_STREAM_SRV_F_NODELAY) - setsockopt_nodelay(ret, link->proto, 1); + if (link->flags & OSMO_STREAM_SRV_F_NODELAY) { + ret = setsockopt_nodelay(ret, link->proto, 1); + if (ret < 0) + goto error_close_socket; + } - if (link->accept_cb) - link->accept_cb(link, ret); + if (!link->accept_cb) { + ret = -ENOTSUP; + goto error_close_socket; + } + ret = link->accept_cb(link, sock_fd); + if (ret) + goto error_close_socket; return 0; + +error_close_socket: + close(sock_fd); + return ret; } /*! \brief Create an Osmocom Stream Server Link |