]> granicus.if.org Git - transmission/commitdiff
Fix peer communication vulnerability (no known exploits) reported by Ben Hawkes
authorJordan Lee <jordan@transmissionbt.com>
Sun, 29 Jun 2014 01:43:27 +0000 (01:43 +0000)
committerJordan Lee <jordan@transmissionbt.com>
Sun, 29 Jun 2014 01:43:27 +0000 (01:43 +0000)
NEWS
libtransmission/bitfield.c
libtransmission/peer-msgs.c

diff --git a/NEWS b/NEWS
index 93ac8f5da4586985d247aee2f9261db66099934a..675520ddc23e83c238679b33e049fbe72132b4ed 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+=== Transmission 2.83 (2014/xx/yy) ===
+[http://trac.transmissionbt.com/query?milestone=2.84&group=component&order=severity All tickets closed by this release]
+==== All Platforms ====
+  * Fix peer communication vulnerability (no known exploits) reported by Ben Hawkes
+
 === Transmission 2.83 (2014/05/18) ===
 [http://trac.transmissionbt.com/query?milestone=2.83&group=component&order=severity All tickets closed by this release]
 ==== All Platforms ====
index 11320ff49b94bccb766deff88b548bd09f014f81..bed09aec528ac98ae8cfa1377393a6cc26a8f70b 100644 (file)
@@ -167,7 +167,7 @@ tr_bitfieldCountTrueBits (const tr_bitfield * b)
 static size_t
 get_bytes_needed (size_t bit_count)
 {
-  return (bit_count + 7u) / 8u;
+  return (bit_count >> 3) + (bit_count & 7 ? 1 : 0);
 }
 
 static void
@@ -228,11 +228,16 @@ tr_bitfieldEnsureBitsAlloced (tr_bitfield * b, size_t n)
     }
 }
 
-static void
+static bool
 tr_bitfieldEnsureNthBitAlloced (tr_bitfield * b, size_t nth)
 {
   /* count is zero-based, so we need to allocate nth+1 bits before setting the nth */
+
+  if (nth == SIZE_MAX)
+    return false;
+
   tr_bitfieldEnsureBitsAlloced (b, nth + 1);
+  return true;
 }
 
 static void
@@ -365,9 +370,8 @@ tr_bitfieldSetFromFlags (tr_bitfield * b, const bool * flags, size_t n)
 void
 tr_bitfieldAdd (tr_bitfield * b, size_t nth)
 {
-  if (!tr_bitfieldHas (b, nth))
+  if (!tr_bitfieldHas (b, nth) && tr_bitfieldEnsureNthBitAlloced (b, nth))
     {
-      tr_bitfieldEnsureNthBitAlloced (b, nth);
       b->bits[nth >> 3u] |= (0x80 >> (nth & 7u));
       tr_bitfieldIncTrueCount (b, 1);
     }
@@ -393,7 +397,9 @@ tr_bitfieldAddRange (tr_bitfield * b, size_t begin, size_t end)
   eb = end >> 3;
   em = 0xff << (7 - (end & 7));
 
-  tr_bitfieldEnsureNthBitAlloced (b, end);
+  if (!tr_bitfieldEnsureNthBitAlloced (b, end))
+    return;
+
   if (sb == eb)
     {
       b->bits[sb] |= (sm & em);
@@ -414,9 +420,8 @@ tr_bitfieldRem (tr_bitfield * b, size_t nth)
 {
   assert (tr_bitfieldIsValid (b));
 
-  if (!tr_bitfieldHas (b, nth))
+  if (!tr_bitfieldHas (b, nth) && tr_bitfieldEnsureNthBitAlloced (b, nth))
     {
-      tr_bitfieldEnsureNthBitAlloced (b, nth);
       b->bits[nth >> 3u] &= (0xff7f >> (nth & 7u));
       tr_bitfieldIncTrueCount (b, -1);
     }
@@ -443,7 +448,9 @@ tr_bitfieldRemRange (tr_bitfield * b, size_t begin, size_t end)
   eb = end >> 3;
   em = ~ (0xff << (7 - (end & 7)));
 
-  tr_bitfieldEnsureNthBitAlloced (b, end);
+  if (!tr_bitfieldEnsureNthBitAlloced (b, end))
+    return;
+
   if (sb == eb)
     {
       b->bits[sb] &= (sm | em);
index 84646f73b6d7abf076dd53928d01144055a7c946..8644644c95a1388a31d9cc0780411d289dfa0255 100644 (file)
 #include "variant.h"
 #include "version.h"
 
+#ifndef EBADMSG
+ #define EBADMSG EINVAL
+#endif
+
 /**
 ***
 **/
@@ -1693,6 +1697,12 @@ clientGotBlock (tr_peerMsgs                * msgs,
     assert (msgs);
     assert (req);
 
+    if (!requestIsValid (msgs, req)) {
+        dbgmsg (msgs, "dropping invalid block %u:%u->%u",
+                req->index, req->offset, req->length);
+        return EBADMSG;
+    }
+
     if (req->length != tr_torBlockCountBytes (msgs->torrent, block)) {
         dbgmsg (msgs, "wrong block size -- expected %u, got %d",
                 tr_torBlockCountBytes (msgs->torrent, block), req->length);