From 9f76e45b9d6671e2074fb7a3885db703045a791f Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 6 May 2019 22:17:31 +0300 Subject: [PATCH 1/5] Drop support of insecure miniUPnPc versions The minimum supported miniUPnPc API version is set to 10. --- .travis.yml | 2 +- src/net.cpp | 18 ++++-------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 21d1062c262..d25b1bf234e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -139,7 +139,7 @@ jobs: env: >- HOST=x86_64-unknown-linux-gnu DOCKER_NAME_TAG=ubuntu:14.04 - PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libicu-dev libpng-dev libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.1++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" + PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libicu-dev libpng-dev libssl-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev libdb5.1++-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" NO_DEPENDS=1 RUN_FUNCTIONAL_TESTS=false GOAL="install" diff --git a/src/net.cpp b/src/net.cpp index 1335804b06e..c073849e476 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -36,6 +36,9 @@ #include #include #include +// The minimum supported miniUPnPc API version is set to 10. This keeps compatibility +// with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages. +static_assert(MINIUPNPC_API_VERSION >= 10, "miniUPnPc API version >= 10 assumed"); #endif #include @@ -1403,16 +1406,10 @@ static void ThreadMapPort() struct UPNPDev * devlist = nullptr; char lanaddr[64]; -#ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ - devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0); -#elif MINIUPNPC_API_VERSION < 14 - /* miniupnpc 1.6 */ int error = 0; +#if MINIUPNPC_API_VERSION < 14 devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, &error); #else - /* miniupnpc 1.9.20150730 */ - int error = 0; devlist = upnpDiscover(2000, multicastif, minissdpdpath, 0, 0, 2, &error); #endif @@ -1446,15 +1443,8 @@ static void ThreadMapPort() std::string strDesc = "Bitcoin " + FormatFullVersion(); do { -#ifndef UPNPDISCOVER_SUCCESS - /* miniupnpc 1.5 */ - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0); -#else - /* miniupnpc 1.6 */ r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); -#endif if(r!=UPNPCOMMAND_SUCCESS) LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", From 91a1b8508358d04685391651aea303ebce1c3d05 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 6 May 2019 22:58:10 +0300 Subject: [PATCH 2/5] Use PACKAGE_NAME in UPnP description --- src/net.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net.cpp b/src/net.cpp index c073849e476..b2339f265c2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1440,7 +1440,7 @@ static void ThreadMapPort() } } - std::string strDesc = "Bitcoin " + FormatFullVersion(); + std::string strDesc = PACKAGE_NAME " " + FormatFullVersion(); do { r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, From 02709e95601c6020a87a6a05ee1d00c13fc38f9b Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Mon, 6 May 2019 23:17:51 +0300 Subject: [PATCH 3/5] Align formatting with clang-format --- src/net.cpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/net.cpp b/src/net.cpp index b2339f265c2..82527f942c1 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1423,36 +1423,32 @@ static void ThreadMapPort() if (fDiscover) { char externalIPAddress[40]; r = UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIPAddress); - if(r != UPNPCOMMAND_SUCCESS) + if (r != UPNPCOMMAND_SUCCESS) { LogPrintf("UPnP: GetExternalIPAddress() returned %d\n", r); - else - { - if(externalIPAddress[0]) - { + } else { + if (externalIPAddress[0]) { CNetAddr resolved; - if(LookupHost(externalIPAddress, resolved, false)) { + if (LookupHost(externalIPAddress, resolved, false)) { LogPrintf("UPnP: ExternalIPAddress = %s\n", resolved.ToString().c_str()); AddLocal(resolved, LOCAL_UPNP); } - } - else + } else { LogPrintf("UPnP: GetExternalIPAddress failed.\n"); + } } } std::string strDesc = PACKAGE_NAME " " + FormatFullVersion(); do { - r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, - port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); + r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype, port.c_str(), port.c_str(), lanaddr, strDesc.c_str(), "TCP", 0, "0"); - if(r!=UPNPCOMMAND_SUCCESS) - LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", - port, port, lanaddr, r, strupnperror(r)); - else + if (r != UPNPCOMMAND_SUCCESS) { + LogPrintf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n", port, port, lanaddr, r, strupnperror(r)); + } else { LogPrintf("UPnP Port Mapping successful.\n"); - } - while(g_upnp_interrupt.sleep_for(std::chrono::minutes(20))); + } + } while (g_upnp_interrupt.sleep_for(std::chrono::minutes(20))); r = UPNP_DeletePortMapping(urls.controlURL, data.first.servicetype, port.c_str(), "TCP", 0); LogPrintf("UPNP_DeletePortMapping() returned: %d\n", r); From ab2190557ec2757fa48b52855b05561854af49af Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Tue, 21 May 2019 19:10:48 +0300 Subject: [PATCH 4/5] doc: Add release notes for 15993 --- doc/release-notes-15993.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 doc/release-notes-15993.md diff --git a/doc/release-notes-15993.md b/doc/release-notes-15993.md new file mode 100644 index 00000000000..493c7126ee9 --- /dev/null +++ b/doc/release-notes-15993.md @@ -0,0 +1,3 @@ +Build system changes +-------------------- +The minimum supported miniUPnPc API version is set to 10. This keeps compatibility with Ubuntu 16.04 LTS and Debian 8 `libminiupnpc-dev` packages. Please note, on Debian this package is still vulnerable to [CVE-2017-8798](https://security-tracker.debian.org/tracker/CVE-2017-8798) (in jessie only) and [CVE-2017-1000494](https://security-tracker.debian.org/tracker/CVE-2017-1000494) (both in jessie and in stretch). From 59cb722fd050393a69f1e0df97d857c893d19d80 Mon Sep 17 00:00:00 2001 From: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com> Date: Thu, 6 Jun 2019 22:18:42 +0200 Subject: [PATCH 5/5] Update configure to reject unsafe miniUPnPc API ver Also fixes behavior when libminiupnpc is not installed. --- configure.ac | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 854d6b1d49a..cafa7c7f945 100644 --- a/configure.ac +++ b/configure.ac @@ -928,6 +928,26 @@ if test x$use_upnp != xno; then [AC_CHECK_LIB([miniupnpc], [upnpDiscover], [MINIUPNPC_LIBS=-lminiupnpc], [have_miniupnpc=no])], [have_miniupnpc=no] ) +dnl The minimum supported miniUPnPc API version is set to 10. This keeps compatibility +dnl with Ubuntu 16.04 LTS and Debian 8 libminiupnpc-dev packages. +if test x$have_miniupnpc != xno; then + AC_MSG_CHECKING([whether miniUPnPc API version is supported]) + AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[ + @%:@include + ]], [[ + #if MINIUPNPC_API_VERSION >= 10 + // Everything is okay + #else + # error miniUPnPc API version is too old + #endif + ]])],[ + AC_MSG_RESULT(yes) + ],[ + AC_MSG_RESULT(no) + AC_MSG_WARN([miniUPnPc API version < 10 is unsupported, disabling UPnP support.]) + have_miniupnpc=no + ]) +fi fi BITCOIN_QT_INIT @@ -1326,9 +1346,10 @@ dnl enable upnp support AC_MSG_CHECKING([whether to build with support for UPnP]) if test x$have_miniupnpc = xno; then if test x$use_upnp = xyes; then - AC_MSG_ERROR("UPnP requested but cannot be built. use --without-miniupnpc") + AC_MSG_ERROR("UPnP requested but cannot be built. Use --without-miniupnpc.") fi AC_MSG_RESULT(no) + use_upnp=no else if test x$use_upnp != xno; then AC_MSG_RESULT(yes)