File transmission-CVE-2014-4909.patch of Package transmission.2927

Index: transmission-2.82/libtransmission/bitfield.c
===================================================================
--- transmission-2.82.orig/libtransmission/bitfield.c
+++ transmission-2.82/libtransmission/bitfield.c
@@ -170,7 +170,7 @@ tr_bitfieldCountTrueBits (const tr_bitfi
 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
@@ -231,11 +231,16 @@ tr_bitfieldEnsureBitsAlloced (tr_bitfiel
     }
 }
 
-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
@@ -368,9 +373,8 @@ tr_bitfieldSetFromFlags (tr_bitfield * b
 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);
     }
@@ -396,7 +400,9 @@ tr_bitfieldAddRange (tr_bitfield * b, si
   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);
@@ -417,9 +423,8 @@ tr_bitfieldRem (tr_bitfield * b, size_t
 {
   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);
     }
@@ -446,7 +451,9 @@ tr_bitfieldRemRange (tr_bitfield * b, si
   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: transmission-2.82/libtransmission/peer-msgs.c
===================================================================
--- transmission-2.82.orig/libtransmission/peer-msgs.c
+++ transmission-2.82/libtransmission/peer-msgs.c
@@ -36,6 +36,10 @@
 #include "variant.h"
 #include "version.h"
 
+#ifndef EBADMSG
+ #define EBADMSG EINVAL
+#endif
+
 /**
 ***
 **/
@@ -1696,6 +1700,12 @@ clientGotBlock (tr_peerMsgs
     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);
Index: transmission-2.82/libtransmission/variant-benc.c
===================================================================
--- transmission-2.82.orig/libtransmission/variant-benc.c
+++ transmission-2.82/libtransmission/variant-benc.c
@@ -87,32 +87,42 @@ tr_bencParseStr (const uint8_t  * buf,
                  const uint8_t ** setme_str,
                  size_t *         setme_strlen)
 {
-  size_t len;
   const void * end;
-  char * endptr;
+  size_t len;
+  char * ulend;
+  const uint8_t * strbegin;
+  const uint8_t * strend;
 
   if (buf >= bufend)
-    return EILSEQ;
+    goto err;
 
   if (!isdigit (*buf))
-    return EILSEQ;
+    goto err;
 
   end = memchr (buf, ':', bufend - buf);
   if (end == NULL)
-    return EILSEQ;
+    goto err;
 
   errno = 0;
-  len = strtoul ((const char*)buf, &endptr, 10);
-  if (errno || endptr != end)
-    return EILSEQ;
-
-  if ((const uint8_t*)end + 1 + len > bufend)
-    return EILSEQ;
+  len = strtoul ((const char*)buf, &ulend, 10);
+  if (errno || ulend != end)
+    goto err;
+
+  strbegin = (const uint8_t*)end + 1;
+  strend = strbegin + len;
+  if ((strend<strbegin) || (strend>bufend))
+    goto err;
 
   *setme_end = (const uint8_t*)end + 1 + len;
   *setme_str = (const uint8_t*)end + 1;
   *setme_strlen = len;
   return 0;
+
+err:
+  *setme_end = NULL;
+  *setme_str = NULL;
+  *setme_strlen= 0;
+  return EILSEQ;
 }
 
 static tr_variant*
Index: transmission-2.82/libtransmission/variant-test.c
===================================================================
--- transmission-2.82.orig/libtransmission/variant-test.c
+++ transmission-2.82/libtransmission/variant-test.c
@@ -85,13 +85,23 @@ testStr (void)
 {
   uint8_t buf[128];
   int err;
+  int n;
   const uint8_t * end;
   const uint8_t * str;
   size_t len;
 
+  /* string len is designed to overflow */
+  n = tr_snprintf ((char*)buf, sizeof (buf), "%zu:boat", (size_t)(SIZE_MAX-2));
+  err = tr_bencParseStr (buf, buf+n, &end, &str, &len);
+  check_int_eq (EILSEQ, err);
+  check_int_eq (0, len);
+  check (str == NULL);
+  check (end == NULL);
+  check (!len);
+
   /* good string */
-  tr_snprintf ((char*)buf, sizeof (buf), "4:boat");
-  err = tr_bencParseStr (buf, buf + 6, &end, &str, &len);
+  n = tr_snprintf ((char*)buf, sizeof (buf), "4:boat");
+  err = tr_bencParseStr (buf, buf+n, &end, &str, &len);
   check_int_eq (0, err);
   check_int_eq (4, len);
   check (!strncmp ((char*)str, "boat", len));
@@ -101,7 +111,7 @@ testStr (void)
   len = 0;
 
   /* string goes past end of buffer */
-  err = tr_bencParseStr (buf, buf + 5, &end, &str, &len);
+  err = tr_bencParseStr (buf, buf+(n-1), &end, &str, &len);
   check_int_eq (EILSEQ, err);
   check_int_eq (0, len);
   check (str == NULL);
@@ -109,8 +119,8 @@ testStr (void)
   check (!len);
 
   /* empty string */
-  tr_snprintf ((char*)buf, sizeof (buf), "0:");
-  err = tr_bencParseStr (buf, buf + 2, &end, &str, &len);
+  n = tr_snprintf ((char*)buf, sizeof (buf), "0:");
+  err = tr_bencParseStr (buf, buf+n, &end, &str, &len);
   check_int_eq (0, err);
   check_int_eq (0, len);
   check (!*str);
@@ -120,8 +130,8 @@ testStr (void)
   len = 0;
 
   /* short string */
-  tr_snprintf ((char*)buf, sizeof (buf), "3:boat");
-  err = tr_bencParseStr (buf, buf + 6, &end, &str, &len);
+  n = tr_snprintf ((char*)buf, sizeof (buf), "3:boat");
+  err = tr_bencParseStr (buf, buf+n, &end, &str, &len);
   check_int_eq (0, err);
   check_int_eq (3, len);
   check (!strncmp ((char*)str, "boa", len));
Index: transmission-2.82/macosx/Makefile.am
===================================================================
--- transmission-2.82.orig/macosx/Makefile.am
+++ transmission-2.82/macosx/Makefile.am
@@ -140,6 +140,10 @@ EXTRA_DIST = \
     PrefsWindow.m \
     ProgressGradients.h \
     ProgressGradients.m \
+    ShareToolbarItem.h \
+    ShareToolbarItem.m \
+    ShareTorrentFileHelper.h \
+    ShareTorrentFileHelper.m \
     StatsWindowController.h \
     StatsWindowController.m \
     StatusBarController.h \
openSUSE Build Service is sponsored by