public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Peter Robinson <pbrobinson@gmail.com>
To: git-commits@fedoraproject.org
Subject: [rpms/transmission] epel10: Upstream fix for CVE-2018-5702 (Mitigate dns rebinding attacks against daemon)
Date: Mon, 20 Jul 2026 20:37:31 GMT	[thread overview]
Message-ID: <178457985138.1.12096459075179516853.rpms-transmission-cd457e5eac4b@fedoraproject.org> (raw)

A new commit has been pushed.

Repo   : rpms/transmission
Branch : epel10
Commit : cd457e5eac4b0a05f718df77813087eddc151d4d
Author : Peter Robinson <pbrobinson@gmail.com>
Date   : 2018-01-16T06:53:44+00:00
Stats  : +310/-3 in 2 file(s)
URL    : https://src.fedoraproject.org/rpms/transmission/c/cd457e5eac4b0a05f718df77813087eddc151d4d?branch=epel10

Log:
Upstream fix for CVE-2018-5702 (Mitigate dns rebinding attacks against daemon)

---
diff --git a/CVE-2018-5702.patch b/CVE-2018-5702.patch
new file mode 100644
index 0000000..5c3b6d1
--- /dev/null
+++ b/CVE-2018-5702.patch
@@ -0,0 +1,302 @@
+Fix a weakness that allows remote code execution via the Transmission
+RPC server using DNS rebinding:
+
+https://bugs.chromium.org/p/project-zero/issues/detail?id=1447
+
+Patch adapted from Tavis Ormandy's patch on the Transmission master
+branch to the Transmission 2.92 release by Leo Famulari
+<leo@famulari.name>:
+
+https://github.com/transmission/transmission/pull/468/commits
+
+From fe2d3c6e75088f3d9b6040ce06da3d530358bc2f Mon Sep 17 00:00:00 2001
+From: Tavis Ormandy <taviso@google.com>
+Date: Thu, 11 Jan 2018 10:00:41 -0800
+Subject: [PATCH] mitigate dns rebinding attacks against daemon
+
+---
+ libtransmission/quark.c        |   2 + 
+ libtransmission/quark.h        |   2 + 
+ libtransmission/rpc-server.c   | 116 +++++++++++++++++++++++++++++++++++++----
+ libtransmission/rpc-server.h   |   4 ++
+ libtransmission/session.c      |   2 + 
+ libtransmission/transmission.h |   1 + 
+ libtransmission/web.c          |   3 ++
+ 7 files changed, 121 insertions(+), 9 deletions(-)
+
+diff --git a/libtransmission/quark.c b/libtransmission/quark.c
+index 30cc2bca4..6de4bc221 100644
+--- a/libtransmission/quark.c
++++ b/libtransmission/quark.c
+@@ -297,6 +297,8 @@ static const struct tr_key_struct my_static[] =
+   { "rpc-version-minimum", 19 },
+   { "rpc-whitelist", 13 },
+   { "rpc-whitelist-enabled", 21 },
++  { "rpc-host-whitelist", 18 },
++  { "rpc-host-whitelist-enabled", 26 },
+   { "scrape", 6 },
+   { "scrape-paused-torrents-enabled", 30 },
+   { "scrapeState", 11 },
+diff --git a/libtransmission/quark.h b/libtransmission/quark.h
+index 7f5212733..21723dea9 100644
+--- a/libtransmission/quark.h
++++ b/libtransmission/quark.h
+@@ -299,6 +299,8 @@ enum
+   TR_KEY_rpc_version_minimum,
+   TR_KEY_rpc_whitelist,
+   TR_KEY_rpc_whitelist_enabled,
++  TR_KEY_rpc_host_whitelist,
++  TR_KEY_rpc_host_whitelist_enabled,
+   TR_KEY_scrape,
+   TR_KEY_scrape_paused_torrents_enabled,
+   TR_KEY_scrapeState,
+diff --git a/libtransmission/rpc-server.c b/libtransmission/rpc-server.c
+index a3485f3fa..a048dc8aa 100644
+--- a/libtransmission/rpc-server.c
++++ b/libtransmission/rpc-server.c
+@@ -52,6 +52,7 @@ struct tr_rpc_server
+     bool               isEnabled;
+     bool               isPasswordEnabled;
+     bool               isWhitelistEnabled;
++    bool               isHostWhitelistEnabled;
+     tr_port            port;
+     char             * url;
+     struct in_addr     bindAddress;
+@@ -63,6 +64,7 @@ struct tr_rpc_server
+     char             * password;
+     char             * whitelistStr;
+     tr_list          * whitelist;
++    tr_list          * hostWhitelist;
+ 
+     char             * sessionId;
+     time_t             sessionIdExpiresAt;
+@@ -588,6 +590,49 @@ isAddressAllowed (const tr_rpc_server * server, const char * address)
+   return false;
+ }
+ 
++static bool isHostnameAllowed(tr_rpc_server const* server, struct evhttp_request* req)
++{
++    /* If password auth is enabled, any hostname is permitted. */
++    if (server->isPasswordEnabled)
++    {
++        return true;
++    }
++
++    char const* const host = evhttp_find_header(req->input_headers, "Host");
++
++    /* No host header, invalid request. */
++    if (host == NULL)
++    {
++        return false;
++    }
++
++    /* Host header might include the port. */
++    char* const hostname = tr_strndup(host, strcspn(host, ":"));
++
++    /* localhost or ipaddress is always acceptable. */
++    if (strcmp(hostname, "localhost") == 0 || strcmp(hostname, "localhost.") == 0 || tr_addressIsIP(hostname))
++    {
++        tr_free(hostname);
++        return true;
++    }
++
++    /* Otherwise, hostname must be whitelisted. */
++    if (server->isHostWhitelistEnabled)
++    {
++        for (tr_list* l = server->hostWhitelist; l != NULL; l = l->next)
++        {
++            if (tr_wildmat(hostname, l->data))
++            {
++                tr_free(hostname);
++                return true;
++            }
++        }
++    }
++
++    tr_free(hostname);
++    return false;
++}
++
+ static bool
+ test_session_id (struct tr_rpc_server * server, struct evhttp_request * req)
+ {
+@@ -663,6 +708,23 @@ handle_request (struct evhttp_request * req, void * arg)
+           handle_upload (req, server);
+         }
+ #ifdef REQUIRE_SESSION_ID
++        else if (!isHostnameAllowed(server, req))
++        {
++            char* tmp = tr_strdup_printf(
++                "<p>Transmission received your request, but the hostname was unrecognized.</p>"
++                "<p>To fix this, choose one of the following options:"
++                "<ul>"
++                "<li>Enable password authentication, then any hostname is allowed.</li>"
++                "<li>Add the hostname you want to use to the whitelist in settings.</li>"
++                "</ul></p>"
++                "<p>If you're editing settings.json, see the 'rpc-host-whitelist' and 'rpc-host-whitelist-enabled' entries.</p>"
++                "<p>This requirement has been added to help prevent "
++                "<a href=\"https://en.wikipedia.org/wiki/DNS_rebinding\">DNS Rebinding</a> "
++                "attacks.</p>");
++            send_simple_response(req, 421, tmp);
++            tr_free(tmp);
++        }
++
+       else if (!test_session_id (server, req))
+         {
+           const char * sessionId = get_current_session_id (server);
+@@ -674,7 +736,7 @@ handle_request (struct evhttp_request * req, void * arg)
+             "<li> When you get this 409 error message, resend your request with the updated header"
+             "</ol></p>"
+             "<p>This requirement has been added to help prevent "
+-            "<a href=\"http://en.wikipedia.org/wiki/Cross-site_request_forgery\">CSRF</a> "
++            "<a href=\"https://en.wikipedia.org/wiki/Cross-site_request_forgery\">CSRF</a> "
+             "attacks.</p>"
+             "<p><code>%s: %s</code></p>",
+             TR_RPC_SESSION_ID_HEADER, sessionId);
+@@ -875,19 +937,14 @@ tr_rpcGetUrl (const tr_rpc_server * server)
+   return server->url ? server->url : "";
+ }
+ 
+-void
+-tr_rpcSetWhitelist (tr_rpc_server * server, const char * whitelistStr)
++static void
++tr_rpcSetList (char const* whitelistStr, tr_list** list)
+ {
+   void * tmp;
+   const char * walk;
+ 
+-  /* keep the string */
+-  tmp = server->whitelistStr;
+-  server->whitelistStr = tr_strdup (whitelistStr);
+-  tr_free (tmp);
+-
+   /* clear out the old whitelist entries */
+-  while ((tmp = tr_list_pop_front (&server->whitelist)))
++  while ((tmp = tr_list_pop_front (list)) != NULL)
+     tr_free (tmp);
+ 
+   /* build the new whitelist entries */
+@@ -896,7 +953,7 @@ tr_rpcSetWhitelist (tr_rpc_server * server, const char * whitelistStr)
+       const char * delimiters = " ,;";
+       const size_t len = strcspn (walk, delimiters);
+       char * token = tr_strndup (walk, len);
+-      tr_list_append (&server->whitelist, token);
++      tr_list_append (list, token);
+       if (strcspn (token, "+-") < len)
+         tr_logAddNamedInfo (MY_NAME, "Adding address to whitelist: %s (And it has a '+' or '-'!  Are you using an old ACL by mistake?)", token);
+       else
+@@ -909,6 +966,21 @@ tr_rpcSetWhitelist (tr_rpc_server * server, const char * whitelistStr)
+     }
+ }
+ 
++void tr_rpcSetHostWhitelist(tr_rpc_server* server, char const* whitelistStr)
++{
++    tr_rpcSetList(whitelistStr, &server->hostWhitelist);
++}
++
++void tr_rpcSetWhitelist(tr_rpc_server* server, char const* whitelistStr)
++{
++    /* keep the string */
++    char* const tmp = server->whitelistStr;
++    server->whitelistStr = tr_strdup(whitelistStr);
++    tr_free(tmp);
++
++    tr_rpcSetList(whitelistStr, &server->whitelist);
++}
++
+ const char*
+ tr_rpcGetWhitelist (const tr_rpc_server * server)
+ {
+@@ -930,6 +1002,11 @@ tr_rpcGetWhitelistEnabled (const tr_rpc_server * server)
+   return server->isWhitelistEnabled;
+ }
+ 
++void tr_rpcSetHostWhitelistEnabled(tr_rpc_server* server, bool isEnabled)
++{
++    server->isHostWhitelistEnabled = isEnabled;
++}
++
+ /****
+ *****  PASSWORD
+ ****/
+@@ -1063,6 +1140,28 @@ tr_rpcInit (tr_session  * session, tr_variant * settings)
+   else
+     tr_rpcSetWhitelistEnabled (s, boolVal);
+ 
++  key = TR_KEY_rpc_host_whitelist_enabled;
++
++  if (!tr_variantDictFindBool(settings, key, &boolVal))
++  {
++      missing_settings_key(key);
++  }
++  else
++  {
++      tr_rpcSetHostWhitelistEnabled(s, boolVal);
++  }
++
++  key = TR_KEY_rpc_host_whitelist;
++
++  if (!tr_variantDictFindStr(settings, key, &str, NULL) && str != NULL)
++  {
++      missing_settings_key(key);
++  }
++  else
++  {
++      tr_rpcSetHostWhitelist(s, str);
++  }
++
+   key = TR_KEY_rpc_authentication_required;
+   if (!tr_variantDictFindBool (settings, key, &boolVal))
+     missing_settings_key (key);
+diff --git a/libtransmission/rpc-server.h b/libtransmission/rpc-server.h
+index e0302c5ea..8c9e6b24e 100644
+--- a/libtransmission/rpc-server.h
++++ b/libtransmission/rpc-server.h
+@@ -49,6 +49,10 @@ void            tr_rpcSetWhitelist (tr_rpc_server * server,
+ 
+ const char*     tr_rpcGetWhitelist (const tr_rpc_server * server);
+ 
++void tr_rpcSetHostWhitelistEnabled(tr_rpc_server* server, bool isEnabled);
++
++void tr_rpcSetHostWhitelist(tr_rpc_server* server, char const* whitelist);
++
+ void            tr_rpcSetPassword (tr_rpc_server * server,
+                                    const char *    password);
+ 
+diff --git a/libtransmission/session.c b/libtransmission/session.c
+index 844cadba8..58b717913 100644
+--- a/libtransmission/session.c
++++ b/libtransmission/session.c
+@@ -359,6 +359,8 @@ tr_sessionGetDefaultSettings (tr_variant * d)
+   tr_variantDictAddStr  (d, TR_KEY_rpc_username,                    "");
+   tr_variantDictAddStr  (d, TR_KEY_rpc_whitelist,                   TR_DEFAULT_RPC_WHITELIST);
+   tr_variantDictAddBool (d, TR_KEY_rpc_whitelist_enabled,           true);
++  tr_variantDictAddStr(d, TR_KEY_rpc_host_whitelist, TR_DEFAULT_RPC_HOST_WHITELIST);
++  tr_variantDictAddBool(d, TR_KEY_rpc_host_whitelist_enabled, true);
+   tr_variantDictAddInt  (d, TR_KEY_rpc_port,                        atoi (TR_DEFAULT_RPC_PORT_STR));
+   tr_variantDictAddStr  (d, TR_KEY_rpc_url,                         TR_DEFAULT_RPC_URL_STR);
+   tr_variantDictAddBool (d, TR_KEY_scrape_paused_torrents_enabled,  true);
+diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h
+index 4f76adfd6..e213a8f4e 100644
+--- a/libtransmission/transmission.h
++++ b/libtransmission/transmission.h
+@@ -123,6 +123,7 @@ const char* tr_getDefaultDownloadDir (void);
+ #define TR_DEFAULT_BIND_ADDRESS_IPV4        "0.0.0.0"
+ #define TR_DEFAULT_BIND_ADDRESS_IPV6             "::"
+ #define TR_DEFAULT_RPC_WHITELIST          "127.0.0.1"
++#define TR_DEFAULT_RPC_HOST_WHITELIST              ""
+ #define TR_DEFAULT_RPC_PORT_STR                "9091"
+ #define TR_DEFAULT_RPC_URL_STR       "/transmission/"
+ #define TR_DEFAULT_PEER_PORT_STR              "51413"
+diff --git a/libtransmission/web.c b/libtransmission/web.c
+index ee495e9fc..c7f062730 100644
+--- a/libtransmission/web.c
++++ b/libtransmission/web.c
+@@ -594,6 +594,7 @@ tr_webGetResponseStr (long code)
+       case 415: return "Unsupported Media Type";
+       case 416: return "Requested Range Not Satisfiable";
+       case 417: return "Expectation Failed";
++      case 421: return "Misdirected Request";
+       case 500: return "Internal Server Error";
+       case 501: return "Not Implemented";
+       case 502: return "Bad Gateway";

diff --git a/transmission.spec b/transmission.spec
index 8d18e26..445641b 100644
--- a/transmission.spec
+++ b/transmission.spec
@@ -2,19 +2,20 @@
 
 Name:           transmission
 Version:        2.92
-Release:        10%{?dist}
+Release:        11%{?dist}
 Summary:        A lightweight GTK+ BitTorrent client
-
-Group:          Applications/Internet
 # See COPYING. This licensing situation is... special.
 License:        MIT and GPLv2
 URL:            http://www.transmissionbt.com
+
 Source0:        http://download.transmissionbt.com/files/transmission-%{version}.tar.xz
 # https://bugzilla.redhat.com/show_bug.cgi?id=1221292
 Source1:        https://raw.githubusercontent.com/gnome-design-team/gnome-icons/master/apps-symbolic/Adwaita/scalable/apps/transmission-symbolic.svg
 #Patch0:         transmission-2.84-overshoot.patch
 Patch1:		transmission-libsystemd.patch
 Patch2:		transmission-fdlimits.patch
+# https://github.com/transmission/transmission/pull/468
+Patch3:		CVE-2018-5702.patch
 
 BuildRequires:  compat-openssl10-devel >= 0.9.4
 BuildRequires:  glib2-devel >= 2.32.0
@@ -95,6 +96,7 @@ exit 0
 #%%patch0 -p0
 %patch1 -p0
 %patch2 -p0
+%patch3 -p1
 
 # fix icon location for Transmission Qt
 sed -i 's|Icon=%{name}-qt|Icon=%{name}|g' qt/%{name}-qt.desktop
@@ -230,6 +232,9 @@ EOF
 %doc %{_mandir}/man1/transmission-qt.*
 
 %changelog
+* Tue Jan 16 2018 Peter Robinson <pbrobinson@fedoraproject.org> 2.92-11
+- Upstream fix for CVE-2018-5702 (Mitigate dns rebinding attacks against daemon)
+
 * Wed Jan 10 2018 Heiko Reese <fedora@heiko-reese.de> - 2.92-10
 - Removed hardcoded fdlimit of 1024
 

                 reply	other threads:[~2026-07-20 20:37 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=178457985138.1.12096459075179516853.rpms-transmission-cd457e5eac4b@fedoraproject.org \
    --to=pbrobinson@gmail.com \
    --cc=git-commits@fedoraproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox