[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#924944: unblock: trojan/1.10.0-2



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-CC: GreaterFire@protonmail.com

Please unblock new upload of trojan (1.10.0-2). Upstream has made a commit on
upstream stable branch to fix a resource leak issue (fd leak):

https://github.com/trojan-gfw/trojan/commit/c8851178cc73f07997910aa608120d604629b5a4

This new upload is building successfully on all release architectures.

Please let me know if there's any doubts. Thank you!

--
Regards,
Boyuan Yang


Detailed changes (full diff):

commit 71ba0eee50285ffa7d15bc01bfdd0fc268d3acf3
Author: GreaterFire-guest <GreaterFire@protonmail.com>
Date:   Sat Mar 16 23:11:37 2019 -0700

    Prepare new upload (1.10.0-2, unstable)

diff --git a/debian/changelog b/debian/changelog
index 91f13d4..4ce7231 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+trojan (1.10.0-2) unstable; urgency=high
+
+  * Fix a file descriptor leak when the remote endpoint closes the TCP
+    connection before the local SSL session is closed.
+
+ -- GreaterFire <GreaterFire@protonmail.com>  Sun, 17 Mar 2019 06:01:42 +0000
+
 trojan (1.10.0-1) unstable; urgency=medium
 
   * New upstream release 1.10.0.
diff --git a/debian/control b/debian/control
index 2247142..84d4bd8 100644
--- a/debian/control
+++ b/debian/control
@@ -3,7 +3,7 @@ Section: web
 Priority: optional
 Maintainer: GreaterFire <GreaterFire@protonmail.com>
 Build-Depends: debhelper (>= 11), cmake (>= 3.7.2), libboost-system-dev,
libboost-program-options-dev, libssl-dev, default-libmysqlclient-dev, openssl,
python3, curl
-Standards-Version: 4.3.0.1
+Standards-Version: 4.3.0.3
 Vcs-Browser: https://salsa.debian.org/debian/trojan
 Vcs-Git: https://salsa.debian.org/debian/trojan.git
 Homepage: https://github.com/trojan-gfw/trojan
diff --git a/debian/patches/0001-fix-resource-leak.patch
b/debian/patches/0001-fix-resource-leak.patch
new file mode 100644
index 0000000..02fa943
--- /dev/null
+++ b/debian/patches/0001-fix-resource-leak.patch
@@ -0,0 +1,219 @@
+From: GreaterFire <32649575+GreaterFire@users.noreply.github.com>
+Date: Sun, 17 Mar 2019 05:32:08 +0000
+Subject: [PATCH] fix resource leak
+
+---
+ src/clientsession.cpp  | 33 ++++++++++++++++++++++++---------
+ src/forwardsession.cpp | 26 ++++++++++++++++++--------
+ src/serversession.cpp  | 33 ++++++++++++++++++++++++---------
+ src/service.cpp        |  6 ++++++
+ 4 files changed, 72 insertions(+), 26 deletions(-)
+
+diff --git a/src/clientsession.cpp b/src/clientsession.cpp
+index 6e38fb1..7aedc84 100644
+--- a/src/clientsession.cpp
++++ b/src/clientsession.cpp
+@@ -37,8 +37,13 @@ tcp::socket& ClientSession::accept_socket() {
+ }
+ 
+ void ClientSession::start() {
++    boost::system::error_code ec;
+     start_time = time(NULL);
+-    in_endpoint = in_socket.remote_endpoint();
++    in_endpoint = in_socket.remote_endpoint(ec);
++    if (ec) {
++        destroy();
++        return;
++    }
+     auto ssl = out_socket.native_handle();
+     if (config.ssl.sni != "") {
+         SSL_set_tlsext_host_name(ssl, config.ssl.sni.c_str());
+@@ -159,7 +164,12 @@ void ClientSession::in_recv(const string &data) {
+             is_udp = req.command == TrojanRequest::UDP_ASSOCIATE;
+             if (is_udp) {
+                 udp::endpoint
bindpoint(in_socket.local_endpoint().address(), 0);
+-                udp_socket.open(bindpoint.protocol());
++                boost::system::error_code ec;
++                udp_socket.open(bindpoint.protocol(), ec);
++                if (ec) {
++                    destroy();
++                    return;
++                }
+                 udp_socket.bind(bindpoint);
+                 Log::log_with_endpoint(in_endpoint, "requested UDP associate
to " + req.address.address + ':' + to_string(req.address.port) + ", open UDP
socket " + udp_socket.local_endpoint().address().to_string() + ':' +
to_string(udp_socket.local_endpoint().port()) + " for relay", Log::INFO);
+                 in_async_write(string("\x05\x00\x00", 3) +
SOCKS5Address::generate(udp_socket.local_endpoint()));
+@@ -218,7 +228,12 @@ void ClientSession::in_sent() {
+                     destroy();
+                     return;
+                 }
+-                out_socket.lowest_layer().open(iterator-
>endpoint().protocol());
++                boost::system::error_code ec;
++                out_socket.lowest_layer().open(iterator-
>endpoint().protocol(), ec);
++                if (ec) {
++                    destroy();
++                    return;
++                }
+                 if (config.tcp.no_delay) {
+                     out_socket.lowest_layer().set_option(tcp::no_delay(true)
);
+                 }
+@@ -372,11 +387,11 @@ void ClientSession::destroy() {
+     }
+     if (out_socket.lowest_layer().is_open()) {
+         out_socket.lowest_layer().cancel(ec);
+-        auto self = shared_from_this();
+-        out_socket.async_shutdown([this, self](const
boost::system::error_code) {
+-            boost::system::error_code ec;
+-            out_socket.lowest_layer().shutdown(tcp::socket::shutdown_both,
ec);
+-            out_socket.lowest_layer().close(ec);
+-        });
++        // only do unidirectional shutdown and don't wait for other side's
close_notify
++        // a.k.a. call SSL_shutdown() once and discard its return value
++        ::SSL_set_shutdown(out_socket.native_handle(),
SSL_RECEIVED_SHUTDOWN);
++        out_socket.shutdown(ec);
++        out_socket.lowest_layer().shutdown(tcp::socket::shutdown_both, ec);
++        out_socket.lowest_layer().close(ec);
+     }
+ }
+diff --git a/src/forwardsession.cpp b/src/forwardsession.cpp
+index 2c94b05..acf9918 100644
+--- a/src/forwardsession.cpp
++++ b/src/forwardsession.cpp
+@@ -36,8 +36,13 @@ tcp::socket& ForwardSession::accept_socket() {
+ }
+ 
+ void ForwardSession::start() {
++    boost::system::error_code ec;
+     start_time = time(NULL);
+-    in_endpoint = in_socket.remote_endpoint();
++    in_endpoint = in_socket.remote_endpoint(ec);
++    if (ec) {
++        destroy();
++        return;
++    }
+     auto ssl = out_socket.native_handle();
+     if (config.ssl.sni != "") {
+         SSL_set_tlsext_host_name(ssl, config.ssl.sni.c_str());
+@@ -63,7 +68,12 @@ void ForwardSession::start() {
+             destroy();
+             return;
+         }
+-        out_socket.lowest_layer().open(iterator->endpoint().protocol());
++        boost::system::error_code ec;
++        out_socket.lowest_layer().open(iterator->endpoint().protocol(), ec);
++        if (ec) {
++            destroy();
++            return;
++        }
+         if (config.tcp.no_delay) {
+             out_socket.lowest_layer().set_option(tcp::no_delay(true));
+         }
+@@ -199,11 +209,11 @@ void ForwardSession::destroy() {
+     }
+     if (out_socket.lowest_layer().is_open()) {
+         out_socket.lowest_layer().cancel(ec);
+-        auto self = shared_from_this();
+-        out_socket.async_shutdown([this, self](const
boost::system::error_code) {
+-            boost::system::error_code ec;
+-            out_socket.lowest_layer().shutdown(tcp::socket::shutdown_both,
ec);
+-            out_socket.lowest_layer().close(ec);
+-        });
++        // only do unidirectional shutdown and don't wait for other side's
close_notify
++        // a.k.a. call SSL_shutdown() once and discard its return value
++        ::SSL_set_shutdown(out_socket.native_handle(),
SSL_RECEIVED_SHUTDOWN);
++        out_socket.shutdown(ec);
++        out_socket.lowest_layer().shutdown(tcp::socket::shutdown_both, ec);
++        out_socket.lowest_layer().close(ec);
+     }
+ }
+diff --git a/src/serversession.cpp b/src/serversession.cpp
+index 88280d6..6d70efb 100644
+--- a/src/serversession.cpp
++++ b/src/serversession.cpp
+@@ -38,8 +38,13 @@ tcp::socket& ServerSession::accept_socket() {
+ }
+ 
+ void ServerSession::start() {
++    boost::system::error_code ec;
+     start_time = time(NULL);
+-    in_endpoint = in_socket.lowest_layer().remote_endpoint();
++    in_endpoint = in_socket.lowest_layer().remote_endpoint(ec);
++    if (ec) {
++        destroy();
++        return;
++    }
+     auto self = shared_from_this();
+     in_socket.async_handshake(stream_base::server, [this, self](const
boost::system::error_code error) {
+         if (error) {
+@@ -175,7 +180,12 @@ void ServerSession::in_recv(const string &data) {
+                     }
+                 }
+             }
+-            out_socket.open(iterator->endpoint().protocol());
++            boost::system::error_code ec;
++            out_socket.open(iterator->endpoint().protocol(), ec);
++            if (ec) {
++                destroy();
++                return;
++            }
+             if (config.tcp.no_delay) {
+                 out_socket.set_option(tcp::no_delay(true));
+             }
+@@ -278,7 +288,12 @@ void ServerSession::udp_sent() {
+             }
+             if (!udp_socket.is_open()) {
+                 auto protocol = iterator->endpoint().protocol();
+-                udp_socket.open(protocol);
++                boost::system::error_code ec;
++                udp_socket.open(protocol, ec);
++                if (ec) {
++                    destroy();
++                    return;
++                }
+                 udp_socket.bind(udp::endpoint(protocol, 0));
+                 udp_async_read();
+             }
+@@ -311,11 +326,11 @@ void ServerSession::destroy() {
+     }
+     if (in_socket.lowest_layer().is_open()) {
+         in_socket.lowest_layer().cancel(ec);
+-        auto self = shared_from_this();
+-        in_socket.async_shutdown([this, self](const
boost::system::error_code) {
+-            boost::system::error_code ec;
+-            in_socket.lowest_layer().shutdown(tcp::socket::shutdown_both,
ec);
+-            in_socket.lowest_layer().close(ec);
+-        });
++        // only do unidirectional shutdown and don't wait for other side's
close_notify
++        // a.k.a. call SSL_shutdown() once and discard its return value
++        ::SSL_set_shutdown(in_socket.native_handle(),
SSL_RECEIVED_SHUTDOWN);
++        in_socket.shutdown(ec);
++        in_socket.lowest_layer().shutdown(tcp::socket::shutdown_both, ec);
++        in_socket.lowest_layer().close(ec);
+     }
+ }
+diff --git a/src/service.cpp b/src/service.cpp
+index e2240d3..6cd8f53 100644
+--- a/src/service.cpp
++++ b/src/service.cpp
+@@ -207,6 +207,8 @@ void Service::run() {
+ }
+ 
+ void Service::stop() {
++    boost::system::error_code ec;
++    socket_acceptor.cancel(ec);
+     io_service.stop();
+ }
+ 
+@@ -220,6 +222,10 @@ void Service::async_accept() {
+         session = make_shared<ClientSession>(config, io_service,
ssl_context);
+     }
+     socket_acceptor.async_accept(session->accept_socket(), [this,
session](const boost::system::error_code error) {
++        if (error == boost::asio::error::operation_aborted) {
++            // got cancel signal, stop calling myself
++            return;
++        }
+         if (!error) {
+             boost::system::error_code ec;
+             auto endpoint = session->accept_socket().remote_endpoint(ec);
+-- 
+2.21.0
+
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..066e9ce
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+0001-fix-resource-leak.patch

Attachment: signature.asc
Description: This is a digitally signed message part


Reply to: