diff -Nru transmission-2.82/debian/changelog transmission-2.82/debian/changelog
--- transmission-2.82/debian/changelog 2014-07-11 18:11:03.000000000 +0000
+++ transmission-2.82/debian/changelog 2018-01-16 13:22:25.000000000 +0000
@@ -1,3 +1,15 @@
+transmission (2.82-1.1ubuntu3.2) trusty-security; urgency=medium
+
+ * SECURITY UPDATE: Remote attacker with arbitrary execute
+ - debian/CVE-2018-5702.patch: mitigate dns rebinding
+ attacks against daemon in libtransmission/quark.c,
+ libtransmission/quark.h, libtransmission/rpc-server.c,
+ libtransmission/rpc-server.h, libtransmission/session.c,
+ libtransmission/transmission.h, libtransmission/web.c.
+ - CVE-2018-5702
+
+ -- Leonidas S. Barbosa Tue, 16 Jan 2018 10:21:51 -0300
+
transmission (2.82-1.1ubuntu3.1) trusty-security; urgency=medium
* SECURITY UPDATE: denial of service and possible code execution via
diff -Nru transmission-2.82/debian/patches/CVE-2018-5702.patch transmission-2.82/debian/patches/CVE-2018-5702.patch
--- transmission-2.82/debian/patches/CVE-2018-5702.patch 1970-01-01 00:00:00.000000000 +0000
+++ transmission-2.82/debian/patches/CVE-2018-5702.patch 2018-01-16 13:21:22.000000000 +0000
@@ -0,0 +1,283 @@
+From 440f03e9ad5ed3efc9e7d943befe33e5cbb65a20 Mon Sep 17 00:00:00 2001
+From: Tavis Ormandy
+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 | 109 +++++++++++++++++++++++++++++++++++++----
+ libtransmission/rpc-server.h | 6 +++
+ libtransmission/session.c | 2 +
+ libtransmission/transmission.h | 1 +
+ libtransmission/web.c | 1 +
+ 7 files changed, 113 insertions(+), 10 deletions(-)
+
+Index: transmission-2.82/libtransmission/quark.c
+===================================================================
+--- transmission-2.82.orig/libtransmission/quark.c
++++ transmission-2.82/libtransmission/quark.c
+@@ -280,6 +280,8 @@ static const struct tr_key_struct my_sta
+ { "rpc-authentication-required", 27 },
+ { "rpc-bind-address", 16 },
+ { "rpc-enabled", 11 },
++ { "rpc-host-whitelist", 18 },
++ { "rpc-host-whitelist-enabled", 26 },
+ { "rpc-password", 12 },
+ { "rpc-port", 8 },
+ { "rpc-url", 7 },
+Index: transmission-2.82/libtransmission/quark.h
+===================================================================
+--- transmission-2.82.orig/libtransmission/quark.h
++++ transmission-2.82/libtransmission/quark.h
+@@ -290,6 +290,8 @@ enum
+ TR_KEY_rpc_authentication_required,
+ TR_KEY_rpc_bind_address,
+ TR_KEY_rpc_enabled,
++ TR_KEY_rpc_host_whitelist,
++ TR_KEY_rpc_host_whitelist_enabled,
+ TR_KEY_rpc_password,
+ TR_KEY_rpc_port,
+ TR_KEY_rpc_url,
+Index: transmission-2.82/libtransmission/rpc-server.c
+===================================================================
+--- transmission-2.82.orig/libtransmission/rpc-server.c
++++ transmission-2.82/libtransmission/rpc-server.c
+@@ -58,6 +58,7 @@ struct tr_rpc_server
+ bool isEnabled;
+ bool isPasswordEnabled;
+ bool isWhitelistEnabled;
++ bool isHostWhitelistEnabled;
+ tr_port port;
+ char * url;
+ struct in_addr bindAddress;
+@@ -67,6 +68,7 @@ struct tr_rpc_server
+ char * password;
+ char * whitelistStr;
+ tr_list * whitelist;
++ tr_list * hostWhitelist;
+
+ char * sessionId;
+ time_t sessionIdExpiresAt;
+@@ -600,6 +602,47 @@ isAddressAllowed (const tr_rpc_server *
+ }
+
+ static bool
++isHostnameAllowed (const tr_rpc_server * server, struct evhttp_request * req)
++{
++ /* If password auth is enabled, any hostname is permitted. */
++ if (server->isPasswordEnabled)
++ return true;
++
++ /* If whitelist is disabled, no restrictions. */
++ if (!server->isHostWhitelistEnabled)
++ return true;
++
++ const char * 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. */
++ 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)
+ {
+ const char * ours = get_current_session_id (server);
+@@ -667,6 +710,22 @@ handle_request (struct evhttp_request *
+ handle_upload (req, server);
+ }
+ #ifdef REQUIRE_SESSION_ID
++ else if (!isHostnameAllowed (server, req))
++ {
++ char * const tmp = tr_strdup_printf (
++ "Transmission received your request, but the hostname was unrecognized.
"
++ "To fix this, choose one of the following options:"
++ "
"
++ "- Enable password authentication, then any hostname is allowed.
"
++ "- Add the hostname you want to use to the whitelist in settings.
"
++ "
"
++ "If you're editing settings.json, see the 'rpc-host-whitelist' and 'rpc-host-whitelist-enabled' entries.
"
++ "This requirement has been added to help prevent "
++ "DNS Rebinding "
++ "attacks.
");
++ send_simple_response (req, 421, tmp);
++ tr_free (tmp);
++ }
+ else if (!test_session_id (server, req))
+ {
+ const char * sessionId = get_current_session_id (server);
+@@ -678,7 +737,7 @@ handle_request (struct evhttp_request *
+ " When you get this 409 error message, resend your request with the updated header"
+ ""
+ "This requirement has been added to help prevent "
+- "CSRF "
++ "CSRF "
+ "attacks.
"
+ "%s: %s
",
+ TR_RPC_SESSION_ID_HEADER, sessionId);
+@@ -800,19 +859,14 @@ tr_rpcGetUrl (const tr_rpc_server * serv
+ return server->url ? server->url : "";
+ }
+
+-void
+-tr_rpcSetWhitelist (tr_rpc_server * server, const char * whitelistStr)
++static void
++tr_rpcSetList (const char * 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)))
+ tr_free (tmp);
+
+ /* build the new whitelist entries */
+@@ -821,7 +875,7 @@ tr_rpcSetWhitelist (tr_rpc_server * serv
+ 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
+@@ -834,6 +888,23 @@ tr_rpcSetWhitelist (tr_rpc_server * serv
+ }
+ }
+
++void
++tr_rpcSetHostWhitelist (tr_rpc_server* server, const char * whitelistStr)
++{
++ tr_rpcSetList (whitelistStr, &server->hostWhitelist);
++}
++
++void
++tr_rpcSetWhitelist (tr_rpc_server * server, const char * 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)
+ {
+@@ -853,6 +924,12 @@ tr_rpcGetWhitelistEnabled (const tr_rpc_
+ return server->isWhitelistEnabled;
+ }
+
++void
++tr_rpcSetHostWhitelistEnabled(tr_rpc_server * server, bool isEnabled)
++{
++ server->isHostWhitelistEnabled = isEnabled;
++}
++
+ /****
+ ***** PASSWORD
+ ****/
+@@ -988,6 +1065,18 @@ tr_rpcInit (tr_session * session, tr_va
+ 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)
++ 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);
+Index: transmission-2.82/libtransmission/rpc-server.h
+===================================================================
+--- transmission-2.82.orig/libtransmission/rpc-server.h
++++ transmission-2.82/libtransmission/rpc-server.h
+@@ -52,6 +52,12 @@ void tr_rpcSetWhitelist (tr_r
+
+ 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,
++ const char * whitelist);
++
+ void tr_rpcSetPassword (tr_rpc_server * server,
+ const char * password);
+
+Index: transmission-2.82/libtransmission/session.c
+===================================================================
+--- transmission-2.82.orig/libtransmission/session.c
++++ transmission-2.82/libtransmission/session.c
+@@ -357,6 +357,8 @@ tr_sessionGetDefaultSettings (tr_variant
+ 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);
+Index: transmission-2.82/libtransmission/transmission.h
+===================================================================
+--- transmission-2.82.orig/libtransmission/transmission.h
++++ transmission-2.82/libtransmission/transmission.h
+@@ -149,6 +149,7 @@ const char* tr_getDefaultDownloadDir (vo
+ #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"
+Index: transmission-2.82/libtransmission/web.c
+===================================================================
+--- transmission-2.82.orig/libtransmission/web.c
++++ transmission-2.82/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 -Nru transmission-2.82/debian/patches/series transmission-2.82/debian/patches/series
--- transmission-2.82/debian/patches/series 2014-07-11 18:10:56.000000000 +0000
+++ transmission-2.82/debian/patches/series 2018-01-16 13:21:43.000000000 +0000
@@ -1,3 +1,4 @@
systemd_service_fixes.patch
fix_freebsd_quota_include.patch
CVE-2014-4909.patch
+CVE-2018-5702.patch